From bb95a5cf07ac245c3dadfa33254f34f80a9d2cd9 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 27 Aug 2013 15:01:22 -0400 Subject: [PATCH] Add option to step with DWARF --- include/libunwind.h | 2 ++ src/UnwindCursor.hpp | 17 ++++++++++++----- src/libuwind.cxx | 30 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/include/libunwind.h b/include/libunwind.h index ea70420..9b6dc39 100644 --- a/include/libunwind.h +++ b/include/libunwind.h @@ -104,6 +104,8 @@ extern int unw_get_proc_name(unw_cursor_t*, char*, size_t, unw_word_t*) //extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*); #endif +extern int unw_init_local_dwarf(unw_cursor_t*, unw_context_t*); + #if UNW_REMOTE /* diff --git a/src/UnwindCursor.hpp b/src/UnwindCursor.hpp index ad89051..637ef7b 100644 --- a/src/UnwindCursor.hpp +++ b/src/UnwindCursor.hpp @@ -320,6 +320,7 @@ class UnwindCursor virtual bool isSignalFrame(); virtual bool getFunctionName(char* buf, size_t bufLen, unw_word_t* offset); virtual void setInfoBasedOnIPRegister(bool isReturnAddress=false); + virtual void setForceDWARF(bool force); void operator delete(void* p, size_t size) {} @@ -348,7 +349,7 @@ class UnwindCursor bool mustUseDwarf() const { return false; } #endif #else - bool mustUseDwarf() const { R dummy; uint32_t offset; return dwarfWithOffset(dummy, offset); } + bool mustUseDwarf() const { R dummy; uint32_t offset; return fForceDwarf || dwarfWithOffset(dummy, offset); } #endif bool dwarfWithOffset(uint32_t& offset) const { R dummy; return dwarfWithOffset(dummy, offset); } @@ -391,17 +392,18 @@ class UnwindCursor compact_unwind_encoding_t dwarfEncoding(Registers_ppc&) const { return 0; } unw_proc_info_t fInfo; - R fRegisters; - A& fAddressSpace; bool fUnwindInfoMissing; bool fIsSignalFrame; + bool fForceDwarf; + R fRegisters; + A& fAddressSpace; }; typedef UnwindCursor AbstractUnwindCursor; template UnwindCursor::UnwindCursor(unw_context_t* context, A& as) - : fRegisters(context), fAddressSpace(as), fUnwindInfoMissing(false), fIsSignalFrame(false) + : fUnwindInfoMissing(false), fIsSignalFrame(false), fForceDwarf(false), fRegisters(context), fAddressSpace(as) { COMPILE_TIME_ASSERT( sizeof(UnwindCursor) < sizeof(unw_cursor_t) ); @@ -410,7 +412,7 @@ UnwindCursor::UnwindCursor(unw_context_t* context, A& as) template UnwindCursor::UnwindCursor(A& as, thread_t thread) - : fAddressSpace(as), fUnwindInfoMissing(false), fIsSignalFrame(false) + : fUnwindInfoMissing(false), fIsSignalFrame(false), fForceDwarf(false), fAddressSpace(as) { bzero(&fInfo, sizeof(fInfo)); // FIXME @@ -471,6 +473,11 @@ bool UnwindCursor::isSignalFrame() return fIsSignalFrame; } +template +void UnwindCursor::setForceDWARF(bool force) +{ + fForceDwarf = force; +} template bool UnwindCursor::getInfoFromDwarfSection(pint_t pc, pint_t mh, pint_t ehSectionStart, uint32_t sectionLength, uint32_t sectionOffsetOfFDE) diff --git a/src/libuwind.cxx b/src/libuwind.cxx index 8d59507..9a2d4c8 100644 --- a/src/libuwind.cxx +++ b/src/libuwind.cxx @@ -63,12 +63,42 @@ EXPORT int unw_init_local(unw_cursor_t* cursor, unw_context_t* context) // use "placement new" to allocate UnwindCursor in the cursor buffer #if __i386__ new ((void*)cursor) UnwindCursor(context, sThisAddressSpace); + static_assert(sizeof(unw_cursor_t) >= sizeof(UnwindCursor), "libunwind header outdated"); #elif __x86_64__ new ((void*)cursor) UnwindCursor(context, sThisAddressSpace); + static_assert(sizeof(unw_cursor_t) >= sizeof(UnwindCursor), "libunwind header outdated"); #elif __ppc__ new ((void*)cursor) UnwindCursor(context, sThisAddressSpace); + static_assert(sizeof(unw_cursor_t) >= sizeof(UnwindCursor), "libunwind header outdated"); #endif + + AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor; + co->setInfoBasedOnIPRegister(); + + return UNW_ESUCCESS; +} + + +/// +/// create a cursor of a thread in this process given 'context' recorded by unw_getcontext() +/// +EXPORT int unw_init_local_dwarf(unw_cursor_t* cursor, unw_context_t* context) +{ + DEBUG_PRINT_API("unw_init_local(cursor=%p, context=%p)\n", cursor, context); + // use "placement new" to allocate UnwindCursor in the cursor buffer +#if __i386__ + new ((void*)cursor) UnwindCursor(context, sThisAddressSpace); + static_assert(sizeof(unw_cursor_t) >= sizeof(UnwindCursor), "libunwind header outdated"); +#elif __x86_64__ + new ((void*)cursor) UnwindCursor(context, sThisAddressSpace); + static_assert(sizeof(unw_cursor_t) >= sizeof(UnwindCursor), "libunwind header outdated"); +#elif __ppc__ + new ((void*)cursor) UnwindCursor(context, sThisAddressSpace); + static_assert(sizeof(unw_cursor_t) >= sizeof(UnwindCursor), "libunwind header outdated"); +#endif + AbstractUnwindCursor* co = (AbstractUnwindCursor*)cursor; + co->setForceDWARF(true); co->setInfoBasedOnIPRegister(); return UNW_ESUCCESS;