I'm writing a utility and Im using libunwind for walking call stack as suggested in http://www.nongnu.org/libunwind/man/libunwind(3).html
void backtrace (void) {
unw_cursor_t cursor;
unw_context_t context;
unw_word_t instructionPointer;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
while (unw_step(&cursor) > 0) {
unw_get_reg(&cursor, UNW_REG_IP, &instructionPointer);
if( isUnique( instructionPointer ) ) {
char name[ 255 ] = {'\0'};
unw_word_t offset;
unw_get_proc_name( &cursor, name, sizeof( name ), &offset );
record( instructionPointer, name );
}
}
}
( I took isUnique and record out to make reading easier, you can find them them below )
I was expecting to have only one instructionPointer per name. But, I'm getting more than one:
139894098909857 -> dl_open_worker
139894098910090 -> dl_open_worker
..... (more lines)
..... (more lines)
..... (more lines)
139893967715894 -> __do_global_ctors_aux
139893966114427 -> _init
139893961300241 -> _ZN8Shiboken6Module6createEPKcPv
139893967235163 -> initQtCore
139894093505625 -> _PyImport_LoadDynamicModule
139893961275008 -> _ZN8Shiboken11Conversions4initEv
139893961237083 -> _ZN8Shiboken4initEv
139893961275033 -> _ZN8Shiboken11Conversions4initEv
139893961275059 -> _ZN8Shiboken11Conversions4initEv
139893961275084 -> _ZN8Shiboken11Conversions4initEv
139893961275113 -> _ZN8Shiboken11Conversions4initEv
139893961275138 -> _ZN8Shiboken11Conversions4initEv
139893961275160 -> _ZN8Shiboken11Conversions4initEv
139893961275182 -> _ZN8Shiboken11Conversions4initEv
139893961275208 -> _ZN8Shiboken11Conversions4initEv
139893961275233 -> _ZN8Shiboken11Conversions4initEv
139893961275255 -> _ZN8Shiboken11Conversions4initEv
I probably misunderstand something and wasn't able to find relevant information. Is there a correct way to do this? Any explanation to why this is happening?
bool isUnique( uint64_t instructionPointer )
{
std::unique_lock<std::mutex> scopedLock( mutex );
// instructionPointerSet is unordered_set<uint64_t>
return instructionPointerSet.insert( instructionPointer ).second;
}
void record( uint64_t instructionPointer, const char * name )
{
std::unique_lock<std::mutex> scopedLock( mutex );
// symbols is std::vector<std::pair<uint64_t, std::string>>
symbols.push_back( std::make_tuple( instructionPointer, std::string(name) ) );
}
Many thanks.