Created
January 20, 2012 06:25
-
-
Save dmikurube/1645716 to your computer and use it in GitHub Desktop.
Core image archaeologist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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