83 #define HAVE_DECL_BASENAME 1 84 #include <libiberty.h> 102 struct FindFilesHelperStruct
111 struct FindAddressHelperStruct
116 TracePoint tracepoint;
121 static void FindAddressInSection ( bfd* aBfd, asection* aSection,
void* aData )
123 FindAddressHelperStruct* lFindAddress = ( FindAddressHelperStruct* ) ( aData );
125 if ( ( bfd_get_section_flags ( aBfd, aSection ) & SEC_ALLOC ) == 0 )
130 bfd_vma vma = bfd_get_section_vma ( aBfd, aSection );
132 if ( lFindAddress->pc < vma )
137 bfd_size_type lSize = bfd_section_size ( aBfd, aSection );
139 if ( lFindAddress->pc >= vma + lSize )
146 const char* lFunction;
150 lFindAddress->found = bfd_find_nearest_line ( aBfd, aSection, lFindAddress->syms, lFindAddress->pc - vma, &lFile, &lFunction, &lLine );
152 if ( !lFindAddress->found )
157 if ( lFunction == NULL || *lFunction ==
'\0' )
159 lFindAddress->tracepoint.function =
"??";
163 if ( !strncmp ( lFunction,
"_Z",2 ) )
166 static int lStatus ( 0 );
167 static std::size_t lSize ( 65536 );
168 static char lDemangled[ 65536 ];
169 abi::__cxa_demangle ( lFunction , lDemangled , &lSize , &lStatus );
173 lFindAddress->tracepoint.function = lFunction;
177 lFindAddress->tracepoint.function = lDemangled;
182 lFindAddress->tracepoint.function = lFunction;
186 if ( lFile == NULL || *lFile ==
'\0' )
188 lFindAddress->tracepoint.file =
"??";
192 lFindAddress->tracepoint.file = lFile;
195 lFindAddress->tracepoint.line = lLine;
201 static bool ProcessFiles (
const char* aFilename, bfd_vma* aAddr,
int aNaddr , TracePoint& aRet )
203 FindAddressHelperStruct lFindAddress;
204 bfd* lBfd = bfd_openr ( aFilename, NULL );
211 if ( bfd_check_format ( lBfd, bfd_archive ) )
213 std::cout << aFilename <<
": can not get addresses from archive" << std::endl;
219 if ( !bfd_check_format_matches ( lBfd, bfd_object, &matching ) )
224 if ( ( bfd_get_file_flags ( lBfd ) & HAS_SYMS ) == 0 )
230 int32_t lSymCount = bfd_read_minisymbols ( lBfd,
false, (
void** ) & lFindAddress.syms, &lSize );
237 if ( lSymCount == 0 )
239 lSymCount = bfd_read_minisymbols ( lBfd,
true , (
void** ) & lFindAddress.syms, &lSize );
244 lFindAddress.pc = aAddr[aNaddr-1];
245 lFindAddress.found =
false;
246 bfd_map_over_sections ( lBfd, FindAddressInSection, &lFindAddress );
248 if ( lFindAddress.found )
256 if ( lFindAddress.syms )
258 free ( lFindAddress.syms );
259 lFindAddress.syms = NULL;
263 aRet = lFindAddress.tracepoint;
269 static int FindMatchingFiles (
struct dl_phdr_info* aInfo,
size_t aSize,
void* aData )
271 FindFilesHelperStruct* match = ( FindFilesHelperStruct* ) ( aData );
273 const ElfW ( Phdr ) *lPhdr;
274 ElfW ( Addr ) lLoadBase = aInfo->dlpi_addr;
275 lPhdr = aInfo->dlpi_phdr;
277 for ( uint32_t n = 0 ; n != aInfo->dlpi_phnum ; ++n , ++lPhdr )
279 if ( lPhdr->p_type == PT_LOAD )
281 ElfW ( Addr ) lVaddr = lPhdr->p_vaddr + lLoadBase;
283 if ( match->address >= (
void* ) ( lVaddr ) && match->address < (
void* ) ( lVaddr + lPhdr->p_memsz ) )
286 match->lFile = aInfo->dlpi_name;
287 match->base = (
void* ) ( aInfo->dlpi_addr );
296 void Backtrace ( std::vector< void* >& aBacktrace )
298 size_t lSize = backtrace ( & ( aBacktrace[0] ) , aBacktrace.size() );
299 aBacktrace.resize ( lSize );
305 boost::mutex mBacktraceMutex;
308 std::vector< TracePoint > BacktraceSymbols (
const std::vector< void* >& aBacktrace )
310 boost::lock_guard<boost::mutex> lLock ( mBacktraceMutex );
311 std::vector< TracePoint > lRet;
312 lRet.reserve ( aBacktrace.size() );
315 for ( std::vector< void* >::const_iterator
x=aBacktrace.begin();
x!=aBacktrace.end(); ++
x )
317 struct FindFilesHelperStruct match;
319 dl_iterate_phdr ( FindMatchingFiles, &match );
320 bfd_vma aAddr = ( std::size_t ) ( *
x ) - ( std::size_t ) ( match.base );
321 TracePoint lTracePoint;
323 if ( ProcessFiles ( ( ( match.lFile && strlen ( match.lFile ) ) ?match.lFile:
"/proc/self/exe" ) , &aAddr, 1 , lTracePoint ) )
325 lRet.push_back ( lTracePoint );