Skip to content

Instantly share code, notes, and snippets.

@dmikurube
Created January 20, 2012 06:25
Show Gist options
  • Save dmikurube/1645716 to your computer and use it in GitHub Desktop.
Save dmikurube/1645716 to your computer and use it in GitHub Desktop.
Core image archaeologist
// g++ -I/.../google-coredumper/include -L/.../google-coredumper/lib -lcoredumper core_dumper.cc
// env LD_LIBRARY_PATH=/.../google-coredumper-working/lib ./a.out
#include <google/coredumper.h>
int main() {
WriteCoreDump("hyanore.core");
return 0;
}
// gcc -I/.../libdwarf/include -L/.../libdwarf/lib -g -lelf -ldwarf dwarf_analyzer.c
// env LD_LIBRARY_PATH=/.../libdwarf/lib ./a.out
//
// grep hoge_t a.out
// Binary file a.out matches
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <libdwarf.h>
#include <dwarf.h>
#include <libelf.h>
const char* dwarf_tag_strings[0x43 + 1] = {
"(0x00)",
"DW_TAG_array_type", // 0x01
"DW_TAG_class_type", // 0x02
"DW_TAG_entry_point", // 0x03
"DW_TAG_enumeration_type", // 0x04
"DW_TAG_formal_parameter", // 0x05
"(0x06)",
"(0x07)",
"DW_TAG_imported_declaration", // 0x08
"(0x09)",
"DW_TAG_label", // 0x0a
"DW_TAG_lexical_block", // 0x0b
"(0x0c)",
"DW_TAG_member", // 0x0d
"(0x0e)",
"DW_TAG_pointer_type", // 0x0f
"DW_TAG_reference_type ", // 0x10
"DW_TAG_compile_unit", // 0x11
"DW_TAG_string_type", // 0x12
"DW_TAG_structure_type", // 0x13
"(0x14)",
"DW_TAG_subroutine_type", // 0x15
"DW_TAG_typedef", // 0x16
"DW_TAG_union_type", // 0x17
"DW_TAG_unspecified_parameters", // 0x18
"DW_TAG_variant", // 0x19
"DW_TAG_common_block", // 0x1a
"DW_TAG_common_inclusion", // 0x1b
"DW_TAG_inheritance", // 0x1c
"DW_TAG_inlined_subroutine", // 0x1d
"DW_TAG_module", // 0x1e
"DW_TAG_ptr_to_member_type", // 0x1f
"DW_TAG_set_type", // 0x20
"DW_TAG_subrange_type", // 0x21
"DW_TAG_with_stmt", // 0x22
"DW_TAG_access_declaration", // 0x23
"DW_TAG_base_type", // 0x24
"DW_TAG_catch_block", // 0x25
"DW_TAG_const_type", // 0x26
"DW_TAG_constant", // 0x27
"DW_TAG_enumerator", // 0x28
"DW_TAG_file_type", // 0x29
"DW_TAG_friend", // 0x2a
"DW_TAG_namelist", // 0x2b
"DW_TAG_namelist_item(s)", // 0x2c
"DW_TAG_packed_type", // 0x2d
"DW_TAG_subprogram", // 0x2e
"DW_TAG_template_type_param(eter)", // 0x2f
"DW_TAG_template_value_param(eter)", // 0x30
"DW_TAG_thrown_type", // 0x31
"DW_TAG_try_block", // 0x32
"DW_TAG_variant_part", // 0x33
"DW_TAG_variable", // 0x34
"DW_TAG_volatile_type", // 0x35
"DW_TAG_dwarf_procedure", // 0x36
"DW_TAG_restrict_type", // 0x37
"DW_TAG_interface_type", // 0x38
"DW_TAG_namespace", // 0x39
"DW_TAG_imported_module", // 0x3a
"DW_TAG_unspecified_type", // 0x3b
"DW_TAG_partial_unit", // 0x3c
"DW_TAG_imported_unit", // 0x3d
"DW_TAG_mutable_type", // 0x3e
"DW_TAG_condition", // 0x3f
"DW_TAG_shared_type", // 0x40
"DW_TAG_type_unit", // 0x41
"DW_TAG_rvalue_reference_type", // 0x42
"DW_TAG_template_alias" // 0x43
};
struct hoge_t {
int x_member;
char* y_member;
double z_member;
};
class hogera_t {
int* a_member;
double b_member;
struct hoge_t hoge_member;
struct hoge_t* hoge_ptr_member;
};
int dump_name(Dwarf_Die die) {
char *str;
int ret;
Dwarf_Error err;
Dwarf_Attribute attr;
ret = dwarf_attr(die, DW_AT_name, &attr, &err);
if (ret != DW_DLV_OK) return -1;
ret = dwarf_formstring(attr, &str, &err);
if (ret != DW_DLV_OK) return -2;
printf("%s", str);
return 0;
}
int dump_line(Dwarf_Die die) {
int ret;
Dwarf_Error err;
Dwarf_Attribute attr;
Dwarf_Unsigned line;
ret = dwarf_attr(die, DW_AT_decl_line, &attr, &err);
if (ret == DW_DLV_NO_ENTRY) return 0;
if (ret != DW_DLV_OK) return -1;
ret = dwarf_formudata(attr, &line, &err);
if (ret != DW_DLV_OK) return -2;
printf("%d", static_cast<int>(line));
return 0;
}
int dump_single_variable_die(Dwarf_Die die) {
printf("("); dump_line(die); printf(") ");
dump_name(die);
}
int dump_single_type_die(Dwarf_Die die) {
dump_name(die);
/*
ret = dwarf_tag(return_die, &type_tag, &err);
printf(" [%s]", dwarf_tag_strings[type_tag]);
*/
}
int dump_single_cu_die(Dwarf_Die die) {
dump_name(die);
}
int dump_single_subprogram_die(Dwarf_Die die) {
dump_name(die);
}
int dump_single_member_die(Dwarf_Debug dbg, Dwarf_Die die) {
Dwarf_Error err;
int ret;
Dwarf_Attribute attr;
Dwarf_Off offset;
char* type_str;
printf("("); dump_line(die); printf(") ");
dump_name(die);
ret = dwarf_attr(die, DW_AT_type, &attr, &err);
if (ret != DW_DLV_OK) { printf("[type error]"); return -1; }
// dwarf_global_formref better ?
ret = dwarf_formref(attr, &offset, &err);
if (ret != DW_DLV_OK) {
printf(" [null type]");
} else {
Dwarf_Die return_die = 0;
Dwarf_Half type_tag = 0;
ret = dwarf_offdie_b(dbg, offset, 1 /* debug_info, debug_type if 0 */,
&return_die, &err);
if (ret == DW_DLV_OK) {
printf("["); dump_single_type_die(return_die); printf("]");
} else if (ret == DW_DLV_NO_ENTRY) {
printf("[no entry]");
} else {
printf("[error]");
}
}
return 0;
}
int dump_recursive_die(Dwarf_Debug dbg, Dwarf_Die die, int d) {
Dwarf_Error err;
int ret;
while (1) {
Dwarf_Half tag;
Dwarf_Die child;
ret = dwarf_tag(die, &tag, &err);
if (ret != DW_DLV_OK) return -1;
for (int i = 0; i < d; ++i) printf(" ");
printf("%02x: %s: ", tag, dwarf_tag_strings[tag]);
if (tag == DW_TAG_variable || tag == DW_TAG_formal_parameter) {
dump_single_variable_die(die);
} else if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type) {
dump_single_type_die(die);
} else if (tag == DW_TAG_member) {
dump_single_member_die(dbg, die);
} else if (tag == DW_TAG_compile_unit) {
dump_single_cu_die(die);
} else if (tag == DW_TAG_subprogram) {
dump_single_subprogram_die(die);
}
printf("\n");
next:
ret = dwarf_child(die, &child, &err);
if (ret == DW_DLV_ERROR) return -2;
if (ret == DW_DLV_OK) {
dump_recursive_die(dbg, child, d+1);
}
ret = dwarf_siblingof(dbg, die, &die, &err);
if (ret == DW_DLV_NO_ENTRY) break;
if (ret != DW_DLV_OK) return -3;
}
return 0;
}
int dwarf_file(Elf *elf) {
Dwarf_Debug dbg;
Dwarf_Die die;
Dwarf_Error err;
int ret;
Dwarf_Unsigned cu_header_length = 0;
Dwarf_Unsigned abbrev_offset = 0;
Dwarf_Half version_stamp = 0;
Dwarf_Half address_size = 0;
Dwarf_Unsigned next_cu_offset = 0;
ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dbg, &err);
if (ret != DW_DLV_OK) return -1;
// Iterate compilation units.
while ((ret =
dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp,
&abbrev_offset, &address_size,
&next_cu_offset, &err))
== DW_DLV_OK) {
ret = dwarf_siblingof(dbg, NULL, &die, &err);
if (ret == DW_DLV_OK) {
printf("vvv\n");
dump_recursive_die(dbg, die, 0);
printf("\n^^^\n");
} else if (ret == DW_DLV_NO_ENTRY) {
continue;
} else {
printf("x %d\n", ret);
return -2;
}
}
printf("/ %d\n", ret);
if (ret == DW_DLV_ERROR) return -3;
return 0;
}
int dump(const char *filename) {
printf("%s\n", filename);
int f;
Elf_Cmd cmd;
Elf *elf;
elf_version(EV_CURRENT);
f = open(filename, O_RDONLY);
if (f < 0) return -1;
cmd = ELF_C_READ;
elf = elf_begin(f, cmd, (Elf *)0);
dwarf_file(elf);
elf_end(elf);
return 0;
}
int main(int argc, char *argv[]) {
struct hoge_t hogehoge;
class hogera_t hogehogera;
hogehoge.x_member = 10;
if (argc > 1) {
dump(argv[1]);
} else {
dump(argv[0]);
}
printf("%d\n", hogehoge.x_member);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment