#include #include #include #include using namespace std; volatile int optim_stopper = 0; void dump_my_stack(int thread_id) { DwarfInterpret& dw = DwarfInterpret::acquire(); DwarfInterpret::UnwindContext unw_context = DwarfInterpret::get_current_unwind_context(); MemoryMap mmap; while(true) { Dl_info dl_inf; int dl_rc = dladdr((void *) unw_context.rip, &dl_inf); printf("[%d] >> PC = %lX ", thread_id, unw_context.rip); MemoryMap::MapEntry cur_map_entry = mmap[mmap.id_of_address(unw_context.rip)]; uintptr_t inelf_pc = unw_context.rip - cur_map_entry.mem_region.begin + cur_map_entry.offset; printf("(in ELF: 0x%lX, func %s, path %s) <<\n", inelf_pc, (dl_rc && dl_inf.dli_sname) ? dl_inf.dli_sname : "(no symbol)", cur_map_entry.pathname.c_str()); fflush(stdout); try { unw_context = dw.unwind_context(unw_context); } catch(const DwarfInterpret::FirstUnwindFrame& e) { // We're reached the end of the stack return; } } } void fill_my_stack(int stack_depth, int thread_id) { if(stack_depth == 0) { dump_my_stack(thread_id); return; } std::this_thread::sleep_for(100ms); fill_my_stack(stack_depth - 1, thread_id); } int main(int argc, char** argv) { MemoryMap mmap; cout << "Dumping memory map… (" << mmap.size() << " entries)" << endl; for(const auto& entry: mmap) { entry.dump(cout); } cout << "End memory map" << endl; int stack_depth = 5; if(argc >= 2) stack_depth = atoi(argv[1]); fill_my_stack(1, 0); std::thread th_stackwalk1(fill_my_stack, stack_depth, 1); std::thread th_stackwalk2(fill_my_stack, stack_depth - 1, 2); th_stackwalk1.join(); th_stackwalk2.join(); return 0; }