diff --git a/INSTALL b/INSTALL index f869bc324..9fc9ad915 100644 --- a/INSTALL +++ b/INSTALL @@ -68,9 +68,10 @@ Usage: configure [OPTIONS] Compiler Options: -c++= ............................ specify the C++ compiler. options [CC|KCC|g++|*xlC*|cxx|pgCC|pgcpp|FCC|guidec++|aCC|c++|ecpc| - icpc|scgcc|scpathCC|pathCC|orCC]. + icpc|scgcc|scpathCC|pathCC|orCC|x86_64-w64-mingw32-g++]. -cc= ................................ specify the C compiler. - options [cc|gcc|scgcc|KCC|pgcc|guidec|*xlc*|ecc|pathcc|orcc]. + options [cc|gcc|scgcc|KCC|pgcc|guidec|*xlc*|ecc|pathcc|orcc| + x86_64-w64-mingw32-gcc]. -fortran= ..................... specify the Fortran compiler. options [gnu|sgi|ibm|ibm64|hp|cray|pgi|absoft|fujitsu|sun|compaq| g95|open64|kai|nec|hitachi|intel|absoft|lahey|nagware|pathscale] diff --git a/README.minGW b/README.minGW index e919bc897..a613d7e74 100644 --- a/README.minGW +++ b/README.minGW @@ -1,23 +1,19 @@ -== Info for Building TAU with the minGW cross-compilers for use on -32-bit Windows == +== Building TAU with the MinGW cross-compilers for 32- or 64-bit Windows == Requirements: -* i586-mingw32msvc-gcc -* i586-mingw32msvc-g++ -* i586-mingw32msvc-ar - -in your path. +MinGW compilers must be in your path. For example (64-bit): +* x86_64-w64-mingw32-gcc +* x86_64-w64-mingw32-g++ +* x86_64-w64-mingw32-ar +* x86_64-w64-mingw32-ld +* x86_64-w64-mingw32-ranlib Limitations: -* Only static libraries -* No symbol demangling * No signal processing +* No event-based sampling (EBS) Instructions: -%> ./configure -DISABLESHARED -%> patch include/Makefile minGW.patch - -Libraries will be placed in 'mingw32/lib'. +See ./configure -help. diff --git a/configure b/configure index 3eec9f8ee..bf5c8f50d 100755 --- a/configure +++ b/configure @@ -6483,6 +6483,10 @@ else fi fi +if [ $cxx_compiler = x86_64-w64-mingw32-g++ ]; then + extra_linker_args="${extralinker_args}#-Wl,--enable-auto-image-base" +fi + fixmakeargs="$fixmakeargs extra_linker_args=$extra_linker_args" diff --git a/include/Makefile b/include/Makefile index 279b99b8e..fff9c67bc 100644 --- a/include/Makefile +++ b/include/Makefile @@ -824,7 +824,7 @@ HPCTOOLKIT_LINK= # continually keep an eye on similar situations for Mac OS X until # we can find a permanent fix. EXTRA_LINKER_ARGS= -#MINGW#EXTRA_LINKER_ARGS=--enable-auto-image-base #ENDIF# +#MINGW#EXTRA_LINKER_ARGS=-Wl,--enable-auto-image-base #ENDIF# #APPLECXX#EXTRA_LINKER_ARGS = -rdynamic#ENDIF# TAU_LINKER_OPT14=$(UPCC_LINK_PREFIX)$(EXTRA_LINKER_ARGS) @@ -841,6 +841,7 @@ BFDLIBS= #COMPINST_INTEL9#TAU_COMPINST_OPTION=$(UPCC_C_PREFIX)-tcollect #ENDIF# #COMPINST_INTEL9#TAU_COMPINST_LINKING= #ENDIF# #COMPINST_GNU#TAU_COMPINST_OPTION=$(UPCC_PREFIX)-g $(UPCC_C_PREFIX)-finstrument-functions #ENDIF# +#MINGW#TAU_COMPINST_OPTION=$(UPCC_PREFIX)-gstabs3 $(UPCC_C_PREFIX)-finstrument-functions #ENDIF# #TAU_BFD#TAU_LINKER_OPT13=$(TAU_BFDLIB) #ENDIF# #COMPINST_PGI#TAU_COMPINST_OPTION=$(UPCC_C_PREFIX)-Mprof=func #ENDIF# #COMPINST_PGI#TAU_COMPINST_LINKING=$(UPCC_LINK_PREFIX)-Mprof=func #ENDIF# diff --git a/include/Profile/TauBfd.h b/include/Profile/TauBfd.h index 42fef14a2..e826137e7 100644 --- a/include/Profile/TauBfd.h +++ b/include/Profile/TauBfd.h @@ -1,14 +1,6 @@ #ifndef _TAU_BFD_H #define _TAU_BFD_H -/* *CWL* Temporary fix. An appropriate reconciliation of the semantics of the two versions - will need to be explored and implemented at some point */ - -/*********************************** - * ******* TAU MINGW VERSION ******* - ***********************************/ -#ifdef TAU_MINGW - #include #include @@ -20,15 +12,44 @@ #define TAU_BFD_NULL_MODULE_HANDLE (-1) #define TAU_BFD_INVALID_MODULE (-2) +// Deprecated flag maintained for backwards compatibility. +// In past, TauBfd could only resolve up to 3000 symbols +// and this flag would indicate that some symbols were not +// resolved. This has since been fixed so all relevant +// symbols are resolved efficiently. Hence, this flag no +// longer has any meaning. +#define TAU_BFD_SYMTAB_LOAD_UNRESOLVED 2 + +// Deprecated flags maintained for backwards compatibility. +// In past, these flags were used to try to avoid duplicating +// common data. TauBfd.cpp has since been updated so that +// there is no duplication of data in any case, so these +// flags no longer have any meaning. +#define TAU_BFD_KEEP_GLOBALS 0 +#define TAU_BFD_REUSE_GLOBALS 1 + +// Iterator function type. Accepts a symbol address and name. +// The name should be an approximation of the full name, for example, +// the contents of asymbol::name from BFD. TauBfd.cpp will +// discover the correct name as needed. +typedef void (*TauBfdIterFn)(unsigned long, const char *); + +// Deprecated iterator function type. Accepts a symbol addresss, +// name, filename, and line number. In past, this was used to +// iterate over all module symbol tables as the modules were +// "touched" by a function call and set the full demangled +// function name, filename, line and line number for every symbol +// in the module (up to 3000). That approach was not scalable. +// In the new approach, the symbol name is quickly approximated. +// The expensive BFD search for the full function name, filename +// and line number is only performed as needed. For large +// applications, the new approach is orders of magnitude faster +// than the old. Hence, it is recommended that this not be used. +typedef void (*DeprecatedTauBfdIterFn)(unsigned long, const char*, const char*, int); + typedef int tau_bfd_handle_t; typedef int tau_bfd_module_handle_t; -/* An iterator function that will take in values generated: */ -/* function name, file name, line number */ -/* by BFD functionality and do some user-defined work on them. */ -typedef struct HashNode * (*TauBfdIterFn)( - unsigned long, const char *, const char *, int); - struct TauBfdAddrMap { TauBfdAddrMap() : @@ -39,8 +60,14 @@ struct TauBfdAddrMap unsigned long _offset, char const * _name) : start(_start), end(_end), offset(_offset) { - strncpy(name, _name, sizeof(name)); - name[sizeof(name)-1] = '\0'; + // Safely copy the name string and always + // end with a NUL char. + int end = 1; + if(_name != NULL) { + strncpy(name, _name, sizeof(name)); + end = sizeof(name); + } + name[end-1] = '\0'; } unsigned long start; @@ -52,19 +79,31 @@ struct TauBfdAddrMap struct TauBfdInfo { TauBfdInfo() : - probeAddr(0), filename(NULL), funcname(NULL), lno(-1) + probeAddr(0), filename(NULL), funcname(NULL), lineno(-1) { } TauBfdInfo(unsigned long _probeAddr, char const * _filename, - char const * _funcname, int _lno) : + char const * _funcname, int _lineno) : probeAddr(_probeAddr), filename(_filename), - funcname(_funcname), lno(_lno) + funcname(_funcname), lineno(_lineno) { } - uintptr_t probeAddr; + // Makes all fields safe to query + void secure(unsigned long addr) { + probeAddr = addr; + lineno = 0; + if(funcname == NULL) { + char routine[256]; + sprintf(routine, "addr=<%p>", addr); + funcname = strdup(routine); + } + if(filename == NULL) filename = "(unknown)"; + } + + unsigned long probeAddr; char const * filename; char const * funcname; - unsigned int lno; + int lineno; }; @@ -72,99 +111,68 @@ struct TauBfdInfo // Main interface functions // +// Initialize TauBFD void Tau_bfd_initializeBfdIfNecessary(); + +// Register a BFD unit (i.e. an executable and its shared libraries) tau_bfd_handle_t Tau_bfd_registerUnit(); + +// Return true if the given handle is valid bool Tau_bfd_checkHandle(tau_bfd_handle_t handle); + +// Scan the BFD unit for address maps void Tau_bfd_updateAddressMaps(tau_bfd_handle_t handle); + +// Forward lookup of symbol information for a given address. +// Searches the appropriate shared libraries and/or the executable +// for information. bool Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, - uintptr_t probeAddr, TauBfdInfo & info); -bool Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, - uintptr_t probeAddr, TauBfdInfo & info); -//int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, -// tau_bfd_module_handle_t moduleHandle, TauBfdIterFn fn); + unsigned long probeAddr, TauBfdInfo & info); + +// Fast scan of the executable symbol table. int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, TauBfdIterFn fn); +// Fast scan of a module symbol table. +// Note that it's usually not worth doing this since it is unlikely +// that all symbols in the module will be required in a single +// application (e.g. a shared library in a large application). +// Instead, use Tau_bfd_resolveBfdInfo as needed. +int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, + tau_bfd_module_handle_t moduleHandle,TauBfdIterFn fn); + // // Query functions // -std::vector & Tau_bfd_getAddressMaps(tau_bfd_handle_t handle); - -TauBfdAddrMap const * Tau_bfd_getAddressMap( - tau_bfd_handle_t handle, uintptr_t probeAddr); +// Get the address maps in the specified BFD unit +std::vector const & +Tau_bfd_getAddressMaps(tau_bfd_handle_t handle); -tau_bfd_module_handle_t Tau_bfd_getModuleHandle( - tau_bfd_handle_t handle, uintptr_t probeAddr); +// Find the address map that probably contains the given address +TauBfdAddrMap const * +Tau_bfd_getAddressMap(tau_bfd_handle_t handle, unsigned long probeAddr); -/****************************************** - * ******* END OF TAU MINGW VERSION ******* - ******************************************/ +// Get the module that possibly defines the given address +tau_bfd_module_handle_t +Tau_bfd_getModuleHandle(tau_bfd_handle_t handle, unsigned long probeAddr); -#else /* TAU_MINGW */ - -/************************************** - * ******* ORIGINAL BFD VERSION ******* - **************************************/ - -#define TAU_BFD_SYMTAB_LOAD_FAILED 0 -#define TAU_BFD_SYMTAB_LOAD_SUCCESS 1 -#define TAU_BFD_SYMTAB_LOAD_UNRESOLVED 2 - -#define TAU_BFD_NULL_HANDLE -1 -#define TAU_BFD_NULL_MODULE_HANDLE -1 -#define TAU_BFD_INVALID_MODULE -2 - -#define TAU_BFD_KEEP_GLOBALS 0 -#define TAU_BFD_REUSE_GLOBALS 1 - -typedef int tau_bfd_handle_t; -typedef int tau_bfd_module_handle_t; - -/* An iterator function that will take in values generated: */ -/* function name, file name, line number */ -/* by BFD functionality and do some user-defined work on them. */ -typedef void (*TauBfdIterFn)(unsigned long, const char *, const char *, int); - -typedef struct { - unsigned long start, end, offset; - char name[512]; -} TauBfdAddrMap; - -typedef struct { - unsigned long probeAddr; - char *filename; - char *funcname; - int lineno; -} TauBfdInfo; +// +// Deprecated interface functions maintained for backwards compatibility. +// These should be phased out soon since they do unnecessary work and +// have lead to memory leaks. +// -/* Main interface functions */ -void Tau_bfd_initializeBfdIfNecessary(); tau_bfd_handle_t Tau_bfd_registerUnit(int flag); -bool Tau_bfd_checkHandle(tau_bfd_handle_t handle); -void Tau_bfd_updateAddressMaps(tau_bfd_handle_t handle); -TauBfdInfo *Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, - unsigned long probe_addr); -TauBfdInfo *Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, - unsigned long probe_addr); +TauBfdInfo * Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, + unsigned long probe_addr); +TauBfdInfo * Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, + unsigned long probe_addr); int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, - tau_bfd_module_handle_t moduleHandle, - int maxProbe, - TauBfdIterFn fn); -int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, - int maxProbe, - TauBfdIterFn fn); - -/* Query functions */ -vector *Tau_bfd_getAddressMaps(tau_bfd_handle_t handle); -int Tau_bfd_getAddressMap(tau_bfd_handle_t handle, - unsigned long probe_addr, TauBfdAddrMap *mapInfo); -tau_bfd_module_handle_t Tau_bfd_getModuleHandle(tau_bfd_handle_t handle, - unsigned long probe_addr); - -/********************************************* - * ******* END OF ORIGINAL BFD VERSION ******* - *********************************************/ - -#endif /* TAU_MINGW */ + tau_bfd_module_handle_t moduleHandle, int maxProbe, + DeprecatedTauBfdIterFn fn); +int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, int maxProbe, + DeprecatedTauBfdIterFn fn); +int Tau_bfd_getAddressMap(tau_bfd_handle_t handle, unsigned long probe_addr, + TauBfdAddrMap * mapInfo); #endif /* _TAU_BFD_H */ diff --git a/src/Profile/Comp_gnu.cpp b/src/Profile/Comp_gnu.cpp index ce61798d5..f44a85994 100644 --- a/src/Profile/Comp_gnu.cpp +++ b/src/Profile/Comp_gnu.cpp @@ -28,14 +28,6 @@ ** compiler instrumentation ** ** ** *****************************************************************************/ - -/* *CWL* Temporary fix. An appropriate reconciliation of the semantics of the two versions - will need to be explored and implemented at some point */ - -/*********************************** - * ******* TAU MINGW VERSION ******* - ***********************************/ -#ifdef TAU_MINGW #ifndef TAU_XLC @@ -85,25 +77,15 @@ static tau_bfd_handle_t bfdUnitHandle = TAU_BFD_NULL_HANDLE; struct HashNode { - HashNode() : - addr(0), name(NULL), fname(NULL), - lno(0), fi(NULL), excluded(false) - { } - - HashNode(size_t _addr, char const * _name, char const * _fname, - size_t _lno, FunctionInfo * _fi, bool _excluded) : - addr(_addr), name(_name), fname(_fname), - lno(_lno), fi(_fi), excluded(_excluded) + HashNode() : fi(NULL), excluded(false) { } - unsigned long addr; ///< Function address - char const * name; ///< Function name - char const * fname; ///< Filename - unsigned int lno; ///< Line number + TauBfdInfo info; ///< Filename, line number, etc. FunctionInfo * fi; ///< Function profile information bool excluded; ///< Is function excluded from profiling? }; +#if 0 class AddressNameHash { @@ -143,6 +125,10 @@ class AddressNameHash }; static AddressNameHash htab; +#endif + +typedef std::map HashTable; +HashTable htab; /* * Get symbol table by using BFD @@ -164,40 +150,26 @@ static void issueBfdWarningIfNecessary() { } } -HashNode * updateHashTable(unsigned long addr, const char *funcname, - const char *filename, int lineno) +void updateHashTable(unsigned long addr, const char *funcname) { - // Hash symbol information while excluding: - bool exclude = ( + HashNode & hn = htab[addr]; + hn.info.funcname = funcname; + hn.excluded = funcname && ( // Intel compiler static initializer - (strcmp(funcname, "__sti__$E") == 0) || + (strcmp(funcname, "__sti__$E") == 0) // Tau Profile wrappers - strstr(funcname, "Tau_Profile_Wrapper") || + || strstr(funcname, "Tau_Profile_Wrapper") // GNU libstdc++ symbols - (strstr(funcname, "__gnu_cxx") == funcname) || + || strstr(funcname, "__gnu_cxx") +#if defined(TAU_WINDOWS) && defined(TAU_MINGW) // MinGW symbols - (strstr(funcname, "__mingw_") == funcname) || - (strstr(funcname, "__w64-mingw") == funcname) || - (strstr(funcname, "___w64-mingw") == funcname) + || strstr(funcname, "__mingw_") + || strstr(funcname, "__w64-mingw") + || strstr(funcname, "___w64-mingw") +#endif ); - - return htab.put(addr, funcname, filename, lineno, exclude); } -/* - * Get symbol table via BFD - */ -static void get_symtab(void) -{ - if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - bfdUnitHandle = Tau_bfd_registerUnit(); - } - - TAU_VERBOSE("Comp_gnu: get_symtab loading executable symbol table\n"); - - // Fast scan of the executable's symbol table - Tau_bfd_processBfdExecInfo(bfdUnitHandle, updateHashTable); -} static TauBfdAddrMap * getAddressMap(unsigned long addr) { @@ -205,8 +177,9 @@ static TauBfdAddrMap * getAddressMap(unsigned long addr) bfdUnitHandle = Tau_bfd_registerUnit(); } - // if Tau_bfd_registerUnit has been called, maps have been previously loaded - vector & addressMap = Tau_bfd_getAddressMaps(bfdUnitHandle); + // if Tau_bfd_registerUnit has been called, maps have been loaded + vector const & addressMap = + Tau_bfd_getAddressMaps(bfdUnitHandle); for (size_t i = 0; i < addressMap.size(); i++) { if (addr >= addressMap[i]->start && addr <= addressMap[i]->end) { return addressMap[i]; @@ -249,19 +222,16 @@ bool tauGetFilenameAndLineNo(unsigned long addr) TauBfdInfo info; tau_symbol_found = Tau_bfd_resolveBfdInfo(bfdUnitHandle, addr, info); - if (!tau_symbol_found) { - // Try again with the executable module. - tau_symbol_found = Tau_bfd_resolveBfdExecInfo(bfdUnitHandle, addr, info); - } - if (tau_symbol_found) { - tau_line_no = info.lno; + tau_line_no = info.lineno; if (info.funcname) { + // Is this leaking memory? tau_funcname = strdup(info.funcname); } else { tau_funcname = NULL; } if (info.filename) { + // Is this leaking memory? tau_filename = strdup(info.filename); } else { tau_filename = NULL; @@ -361,139 +331,6 @@ int tauPrintAddr(int i, char *token, unsigned long addr) { return 0; } -static FunctionInfo * createFunctionInfo(HashNode * hn, unsigned long addr) -{ - // Don't do work when we don't have to - if(hn->fi) return hn->fi; - - if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - bfdUnitHandle = Tau_bfd_registerUnit(); - } - - RtsLayer::LockDB(); // lock, then check again - // *CWL* - why? Because another thread could be creating this now. - // Lock-and-check-again is more efficient than Lock-first-check-later. - if (hn->fi == NULL) { - - char const * filename = hn->fname; - - // Resolve function info if it hasn't already been retrieved - if (!filename) { - filename = "(unknown)"; - - TauBfdInfo info; - bool resolved = Tau_bfd_resolveBfdExecInfo(bfdUnitHandle, addr, info); - - if (resolved) { - if (info.filename) { - filename = info.filename; - } - if (info.funcname) { - hn->name = info.funcname; - } - hn->lno = info.lno; - } - } - - char routine[strlen(hn->name) + strlen(filename) + 128]; - sprintf(routine, "%s [{%s} {%d,0}]", hn->name, filename, hn->lno); - - void *handle = NULL; - TAU_PROFILER_CREATE(handle, routine, "", TAU_DEFAULT); - hn->fi = (FunctionInfo*)handle; - } - RtsLayer::UnLockDB(); - - return hn->fi; -} - -static HashNode *createHashNode(unsigned long addr) -{ - // Note: It is assumed that no hash node for addr exists - -// TAU_VERBOSE("createHashNode: addr = [%p]\n", addr); - if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - bfdUnitHandle = Tau_bfd_registerUnit(); - } - - // Get info from BFD about this address - TauBfdInfo info; - bool resolved = Tau_bfd_resolveBfdInfo(bfdUnitHandle, addr, info); - - HashNode * hn = NULL; - if (resolved) { - hn = updateHashTable(addr, info.funcname, info.filename, info.lno); - - RtsLayer::LockDB(); // lock, then check again - // *CWL* - why? Because another thread could be creating this now. - // Lock-and-check-again is more efficient than Lock-first-check-later. - if (hn->fi == NULL) { - char routine[strlen(hn->name) + strlen(hn->fname) + 128]; - sprintf(routine, "%s [{%s} {%d,0}]", hn->name, hn->fname, hn->lno); - // Create function info for the new node - void *handle = NULL; - TAU_PROFILER_CREATE(handle, routine, "", TAU_DEFAULT); - hn->fi = (FunctionInfo*)handle; - } - RtsLayer::UnLockDB(); - } else { - hn = htab.put(addr, "(unknown)", "(unknown)", 0); - - RtsLayer::LockDB(); // lock, then check again - // *CWL* - why? Because another thread could be creating this now. - // Lock-and-check-again is more efficient than Lock-first-check-later. - if (hn->fi == NULL) { - // Couldn't map the address to the function name. - // Give up and make a node named by address. - char routine[2048]; - sprintf(routine, "addr=<%p>", (void*)(uintptr_t)addr); - // Create function info for the new node - void * handle = NULL; - TAU_PROFILER_CREATE(handle, routine, "", TAU_DEFAULT); - hn->fi = (FunctionInfo*)handle; - } - RtsLayer::UnLockDB(); - } - return hn; - -#if 0 - // Load the module symbol table - tau_bfd_module_handle_t moduleHandle = - Tau_bfd_getModuleHandle(bfdUnitHandle, (uintptr_t)addr); - if (moduleHandle != TAU_BFD_NULL_MODULE_HANDLE) { - int result = Tau_bfd_processBfdModuleInfo(bfdUnitHandle, - moduleHandle, updateHashTable); - if (result == TAU_BFD_SYMTAB_LOAD_FAILED) { - TAU_VERBOSE("createHashNode: Failed to load symtab for Module %d."); - // Note: don't fall back to executable because we scanned the exe - // in initialization. Repeating the scan won't find anything new. - } - } - - // Get the newly created hash node - HashNode * hn = htab.get(addr); - - if(hn) { - // Create function info if needed - createFunctionInfo(hn, addr); - } else { - // Couldn't map the address to the function name. - // Give up and make a node named by address. - char routine[2048]; - sprintf(routine, "addr=<%p>", (void*)(uintptr_t)addr); - hn = htab.put(addr, "(unknown)", "(unknown)", 0); - - // Create function info for the new node - void * handle = NULL; - TAU_PROFILER_CREATE(handle, routine, "", TAU_DEFAULT); - hn->fi = (FunctionInfo*)handle; - } - - return hn; -#endif -} - - static int executionFinished = 0; void runOnExit() { executionFinished = 1; @@ -539,9 +376,6 @@ void __pat_tp_func_return(const void *ea, const void *ra); #endif /* SICORTEX || TAU_SCOREP */ void __cyg_profile_func_enter(void* func, void* callsite) { - int i; - int tid; - #ifndef TAU_BFD issueBfdWarningIfNecessary(); #endif /* TAU_BFD */ @@ -550,19 +384,19 @@ void __cyg_profile_func_enter(void* func, void* callsite) return; } - HashNode *hn; void * funcptr = func; #ifdef __ia64__ funcptr = *( void ** )func; #endif + unsigned long addr = Tau_convert_ptr_to_unsigned_long(funcptr); - tid = Tau_get_tid(); + int tid = Tau_get_tid(); if (gnu_init) { gnu_init = false; // initialize array of flags that prevent re-entry - for (i = 0; i < TAU_MAX_THREADS; i++) { + for (int i = 0; i < TAU_MAX_THREADS; i++) { compInstDisabled[i] = 0; } @@ -578,7 +412,11 @@ void __cyg_profile_func_enter(void* func, void* callsite) } // Create hashtable entries for all symbols in the executable - get_symtab(); + // via a fast scan of the executable's symbol table. + // It makes sense to load the entire symbol table because all + // symbols in the executable are likely to be encountered + // during the run + Tau_bfd_processBfdExecInfo(bfdUnitHandle, updateHashTable); TheUsingCompInst() = 1; TAU_PROFILE_SET_NODE(0); @@ -601,19 +439,33 @@ void __cyg_profile_func_enter(void* func, void* callsite) } compInstDisabled[tid] = 1; - // Check for unhashed address. - // Since the executable symbol table has already been processed, - // the address is either resolvable in another module, or unresolvable. - if ((hn = htab.get(funcptr)) == NULL) { -// TAU_VERBOSE("Previously unhashed funcptr [%p]\n", -// Tau_convert_ptr_to_unsigned_long(funcptr)); - hn = createHashNode(Tau_convert_ptr_to_unsigned_long(funcptr)); - } + // Get previously hashed info, or efficiently create + // a new hash node if it didn't already exist + HashNode & hn = htab[addr]; // Start the timer if it's not an excluded function - if (!hn->excluded) { - createFunctionInfo(hn, Tau_convert_ptr_to_unsigned_long(funcptr)); - Tau_start_timer(hn->fi, 0, tid); + if (!hn.excluded) { + if(hn.fi == NULL) { + RtsLayer::LockDB(); // lock, then check again + // *CWL* - why? Because another thread could be creating this now. + // Lock-and-check-again is more efficient than Lock-first-check-later. + if (hn.fi == NULL) { + // Resolve function info if it hasn't already been retrieved + if(hn.info.probeAddr == 0) { + Tau_bfd_resolveBfdInfo(bfdUnitHandle, addr, hn.info); + } + + char routine[strlen(hn.info.funcname) + strlen(hn.info.filename) + 128]; + sprintf(routine, "%s [{%s} {%d,0}]", hn.info.funcname, + hn.info.filename, hn.info.lineno); + + void *handle = NULL; + TAU_PROFILER_CREATE(handle, routine, "", TAU_DEFAULT); + hn.fi = (FunctionInfo*)handle; + } + RtsLayer::UnLockDB(); + } + Tau_start_timer(hn.fi, 0, tid); } // finished in this routine, allow entry @@ -639,42 +491,34 @@ void ___cyg_profile_func_enter(void* func, void* callsite) { #if (defined(TAU_SICORTEX) || defined(TAU_SCOREP)) #pragma weak __cyg_profile_func_exit #endif /* SICORTEX || TAU_SCOREP */ -void __cyg_profile_func_exit(void* func, void* callsite) { - int tid; - +void __cyg_profile_func_exit(void* func, void* callsite) +{ #ifndef TAU_BFD - issueBfdWarningIfNecessary(); + issueBfdWarningIfNecessary(); #endif /* TAU_BFD */ - tid = Tau_get_tid(); - Tau_global_incr_insideTAU_tid(tid); + int tid = Tau_get_tid(); + Tau_global_incr_insideTAU_tid(tid); - // prevent entry into cyg_profile functions while inside entry - tid = Tau_get_tid(); - if (compInstDisabled[tid]) { - return; - } + // prevent entry into cyg_profile functions while inside entry + if (compInstDisabled[tid]) { + return; + } - if (executionFinished) { - return; - } - HashNode *hn; - void * funcptr = func; + if (executionFinished) { + return; + } + + void * funcptr = func; #ifdef __ia64__ - funcptr = *( void ** )func; + funcptr = *( void ** )func; #endif - if ( (hn = htab.get(funcptr)) ) { - if (hn->excluded) { - Tau_global_decr_insideTAU_tid(tid); - return; - } - - Tau_stop_timer(hn->fi, tid); - } else { - //printf ("NOT FOUND! : "); - } - Tau_global_decr_insideTAU_tid(tid); + HashNode & hn = htab[Tau_convert_ptr_to_unsigned_long(funcptr)]; + if (!hn.excluded) { + Tau_stop_timer(hn.fi, tid); + } + Tau_global_decr_insideTAU_tid(tid); } void _cyg_profile_func_exit(void* func, void* callsite) { @@ -692,650 +536,3 @@ void __pat_tp_func_return(const void *ea, const void *ra) { } // extern "C" #endif /* TAU_XLC */ - -/****************************************** - * ******* END OF TAU MINGW VERSION ******* - ******************************************/ - -#else /* TAU_MINGW */ - -/************************************** - * ******* ORIGINAL BFD VERSION ******* - **************************************/ - -#ifndef TAU_XLC - -#include -#include -#include -#ifdef __GNUC__ -#include -#endif /* __GNUC__ */ -using namespace std; - - -#include - -#include -#include -// #include -#include -#include -#ifdef TAU_OPENMP -# include -#endif /* TAU_OPENMP */ - -#ifndef TAU_MAX_SYMBOLS_TO_BE_RESOLVED -#define TAU_MAX_SYMBOLS_TO_BE_RESOLVED 3000 -#endif /* TAU_MAX_SYMBOLS_TO_BE_RESOLVED */ - -#include - -#ifdef __APPLE__ -#include -#endif /* __APPLE__ */ - - -static int gnu_init = 1; /* is initialization needed? */ - -static int compInstDisabled[TAU_MAX_THREADS]; - -static tau_bfd_handle_t bfdUnitHandle = TAU_BFD_NULL_HANDLE; - -/* - *----------------------------------------------------------------------------- - * Simple hash table to map function addresses to region names/identifier - *----------------------------------------------------------------------------- - */ - -typedef struct HN { - unsigned long id; /* hash code (address of function */ - const char* name; /* associated function name */ - const char* fname; /* file name */ - int lno; /* line number */ - FunctionInfo *fi; - int excluded; - struct HN* next; -} HashNode; - -#define HASH_MAX 1021 - -static HashNode* htab[HASH_MAX]; - -/* - * Stores function name `n' under hash code `h' - */ - -static HashNode* hash_get(unsigned long h); - -// This version is used for when the FI cannot be immediately resolved. -static void hash_put(unsigned long h, const char* n, const char* fn, int lno, - int excluded = 0) { - // already found, do not add. - if (hash_get(h) != NULL) { - return; - } - long id = h % HASH_MAX; - HashNode *add = (HashNode*)malloc(sizeof(HashNode)); - add->id = h; - add->name = n ? (const char*)strdup(n) : n; - add->fname = fn ? (const char*)strdup(fn) : fn; - add->lno = lno; - add->fi = NULL; - add->excluded = excluded; - add->next = htab[id]; - htab[id] = add; -} - -static void hash_put(unsigned long h, HashNode *add) { - long id = h % HASH_MAX; - add->next = htab[id]; - htab[id] = add; -} - -/* - * Lookup hash code `h' - * Returns hash table entry if already stored, otherwise NULL - */ - -static HashNode* hash_get(unsigned long h) { - long id = h % HASH_MAX; - HashNode *curr = htab[id]; - while ( curr ) { - if ( curr->id == h ) { - return curr; - } - curr = curr->next; - } - return NULL; -} - - -/* - * Get symbol table by using BFD - */ - -static const char *tau_filename; -static const char *tau_funcname; -static unsigned int tau_line_no; -static int tau_symbol_found; - -extern "C" int Tau_get_backtrace_off_by_one_correction(void); - -static void issueBfdWarningIfNecessary() { - static bool warningIssued = false; - if (!warningIssued) { - fprintf(stderr,"TAU Warning: Comp_gnu - BFD is not available during TAU build. Symbols may not be resolved!\n"); - warningIssued = true; - } -} - -void updateHashTable(unsigned long addr, - const char *funcname, const char *filename, - int lineno) { - // Simply hash encountered symbol information while excluding - // certain symbols. - if ((strstr(funcname, "Tau_Profile_Wrapper")) || - (strcmp(funcname, "__sti__$E") == 0)) { - /* exclude Tau Profile wrappers */ - /* exclude intel compiler static initializer */ - hash_put(addr, funcname, filename, lineno, 1); - } else { - hash_put(addr, funcname, filename, lineno); - } -} - -/* - * Get symbol table either by using BFD or by parsing nm-file - */ -static void get_symtab(void) { - if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - bfdUnitHandle = Tau_bfd_registerUnit(TAU_BFD_REUSE_GLOBALS); - } - /* char *path = Tau_bfd_getExecutablePath(bfdUnitHandle); */ - /* Open the executable path */ - /* get_symtab_bfd(path, 0); */ - TAU_VERBOSE("Comp_gnu: get_symtab loading executable symbol table\n"); - // Pre-process each of the executable's symbols up to a limit - Tau_bfd_processBfdExecInfo(bfdUnitHandle, - TAU_MAX_SYMBOLS_TO_BE_RESOLVED, - updateHashTable); -} - -vector *addressMap = NULL; - -static TauBfdAddrMap *getAddressMap(unsigned long addr) { - if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - bfdUnitHandle = Tau_bfd_registerUnit(TAU_BFD_REUSE_GLOBALS); - } - // if Tau_bfd_registerUnit has been called, maps have been previously loaded - addressMap = Tau_bfd_getAddressMaps(bfdUnitHandle); - for (unsigned int i=0;isize();i++) { - if (addr >= (*addressMap)[i].start && addr <= (*addressMap)[i].end) { - return &((*addressMap)[i]); - } - } - - // Wasn't found in any ranges, try updating the maps. - // NOTE: *CWL* - This simplified means of detecting epoch changes will - // suffer from pathological cases where a function's address in - // one dynamically loaded module can coincide with another - // function's address in another dynamically loaded module. - // - // Sampling CANNOT take this approach to epoch changes. It must - // rely on traps to dlopen calls. - Tau_bfd_updateAddressMaps(bfdUnitHandle); - addressMap = Tau_bfd_getAddressMaps(bfdUnitHandle); - - for (unsigned int i=0;isize();i++) { - if (addr >= (*addressMap)[i].start && addr <= (*addressMap)[i].end) { - return &((*addressMap)[i]); - } - } - - TAU_VERBOSE("Comp_gnu: getAddressMap - failed to find address [%p] after 2 tries\n", addr); - // Still not found? Give up - return NULL; -} - - -bool tauGetFilenameAndLineNo(unsigned long addr) { - bool success = false; - TAU_VERBOSE("tauGetFilenameAndLineNo: addr=%p\n", addr); - if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - bfdUnitHandle = Tau_bfd_registerUnit(TAU_BFD_REUSE_GLOBALS); - } - TauBfdInfo *resolvedInfo = - Tau_bfd_resolveBfdInfo(bfdUnitHandle, addr); - if (resolvedInfo == NULL) { - // Try again with the executable module. - resolvedInfo = Tau_bfd_resolveBfdExecInfo(bfdUnitHandle, addr); - } - if (resolvedInfo != NULL) { - success = true; - tau_symbol_found = true; - tau_line_no = resolvedInfo->lineno; - if (resolvedInfo->funcname != NULL) { - tau_funcname = strdup(resolvedInfo->funcname); - } else { - tau_funcname = NULL; - } - if (resolvedInfo->filename != NULL) { - tau_filename = strdup(resolvedInfo->filename); - } else { - tau_filename = NULL; - } - } else { - tau_symbol_found = false; - tau_line_no = 0; - tau_funcname = NULL; - tau_filename = NULL; - } - return success; -} - -int tauPrintAddr(int i, char *token, unsigned long addr) { - static int flag = 0; - if (flag == 0) { - flag = 1; - } - char field[2048]; - char metadata[256]; - char *dem_name = NULL; - char demangled_name[2048], line_info[2048]; - char cmd[2048]; - FILE *pipe_fp; - TauBfdAddrMap *map = getAddressMap(addr); - line_info[0]=0; - - /* Do we have a demangled name? */ - if (dem_name == (char *) NULL) { - char *subtoken=token; - int i = 0; - while (*subtoken!= '(' && i < strlen(token)) { - subtoken++; i++; - } - subtoken--; /* move the pointer to before the ( so we can use strtok */ - TAU_VERBOSE("Subtoken=%s\n", subtoken); - char *subs=strtok(subtoken,"(+"); - subs = strtok(NULL,"+"); - if (subs == (char *) NULL) subs = token; -#ifndef __GNUC__ - sprintf(cmd, "c++filt %s", subs); - TAU_VERBOSE("popen %s\n", cmd); - pipe_fp = popen(cmd, "r"); - //fscanf(pipe_fp,"%s", demangled_name); - int ret = fread(demangled_name, 1, 1024, pipe_fp); - TAU_VERBOSE("name = %s, Demangled name = %s, ret = %d\n", token, demangled_name, ret); - pclose(pipe_fp); - dem_name = demangled_name; -#else /* __GNUC__ */ - std::size_t len=1024; - int stat; - char *out_buf= (char *) malloc (len); - char *name = abi::__cxa_demangle(subs, out_buf, &len, &stat); - if (stat == 0) dem_name = out_buf; - else dem_name = subs; - TAU_VERBOSE("DEM_NAME subs= %s dem_name= %s, name = %s, len = %d, stat=%d\n", subs, dem_name, name, len, stat); -#endif /* __GNUC__ */ - - } - if (dem_name == (char *) NULL) dem_name = token; - TAU_VERBOSE("tauPrintAddr: final demangled name [%s]\n", dem_name); - -#ifdef TAU_EXE - if (map != NULL) { - sprintf(cmd, "addr2line -e %s 0x%lx", map->name, addr); - TAU_VERBOSE("popen %s\n", cmd); - pipe_fp = popen(cmd, "r"); - fscanf(pipe_fp,"%s", line_info); - TAU_VERBOSE("cmd = %s, line number = %s\n", cmd, line_info); - pclose(pipe_fp); - sprintf(field, "[%s] [%s] [%s]", dem_name, line_info, map->name); - } -#endif /* TAU_EXE */ - /* The reason the TAU_BFD tag is still here is to allow for alternatives */ -#ifdef TAU_BFD - tauGetFilenameAndLineNo(addr); - if (tau_symbol_found) { - TAU_VERBOSE("tauPrintAddr: Symbol found for [addr=%p]\n", addr); - sprintf(field, "[%s] [%s:%d] [%s]", tau_funcname, tau_filename, tau_line_no, map->name); - } else { - TAU_VERBOSE("tauPrintAddr: Symbol for [addr=%p] not found\n", addr); - if (dem_name != NULL && map != NULL) { - // Get address from gdb if possible - TAU_VERBOSE("tauPrintAddr: Getting information from GDB instead\n"); - sprintf(field, "[%s] [Addr=%p] [%s]", dem_name, - addr+Tau_get_backtrace_off_by_one_correction(), map->name); - } else { - TAU_VERBOSE("tauPrintAddr: No Information Available\n"); - sprintf(field, "[%s] [addr=%p]", dem_name, - addr+Tau_get_backtrace_off_by_one_correction()); - } - } -#else - issueBfdWarningIfNecessary(); -#endif /* TAU_BFD */ - sprintf(metadata, "BACKTRACE %3d", i-1); - TAU_METADATA(metadata, field); - return 0; -} - -static HashNode *createHashNode(unsigned long addr) { - // Pre-condition: hn will ALWAYS be NULL on initial entry. - // This function is only called if addr cannot be found in - // some HashNode. - TAU_VERBOSE("createHashNode: addr = [%p]\n", addr); - if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - bfdUnitHandle = Tau_bfd_registerUnit(TAU_BFD_REUSE_GLOBALS); - } - tau_bfd_module_handle_t moduleHandle = - Tau_bfd_getModuleHandle(bfdUnitHandle, addr); - if (moduleHandle != TAU_BFD_NULL_MODULE_HANDLE) { - TAU_VERBOSE("createHashNode: Trying Module %d for address [%p]\n", - moduleHandle, addr); - int result; - result = Tau_bfd_processBfdModuleInfo(bfdUnitHandle, moduleHandle, - TAU_MAX_SYMBOLS_TO_BE_RESOLVED, - updateHashTable); - if (result == TAU_BFD_SYMTAB_LOAD_FAILED) { - // try again with the executable. - TAU_VERBOSE("createHashNode: Failed to load symtab, trying again with executable.\n"); - Tau_bfd_processBfdExecInfo(bfdUnitHandle, - TAU_MAX_SYMBOLS_TO_BE_RESOLVED, - updateHashTable); - } - HashNode *hn = hash_get(addr); - if (hn != NULL) { - if (hn->fi == NULL) { - // remove the path - const char *filename = hn->fname; - if (filename) { - while (strchr(filename,'/') != NULL) { - filename = strchr(filename,'/')+1; - } - } else { - filename = "(unknown)"; - // No name! Attempt to resolve the address - TauBfdInfo *info = Tau_bfd_resolveBfdInfo(bfdUnitHandle, addr); - // If the general solution fails, we try the executable-only - if (info == NULL) { - info = Tau_bfd_resolveBfdExecInfo(bfdUnitHandle, addr); - } - if (info->filename != NULL) { - filename = strdup(info->filename); - } - if ((info->funcname != NULL) && (hn->name == NULL)) { - hn->name = strdup(info->funcname); - } - hn->lno = info->lineno; - } - char routine[2048]; - sprintf (routine, "%s [{%s} {%d,0}]", hn->name, filename, hn->lno); - void *handle=NULL; - TAU_PROFILER_CREATE(handle, routine, "", TAU_DEFAULT); - hn->fi = (FunctionInfo*) handle; - } - return hn; - } - } - // Unmapped or subsequently unresolved Address - - // Unknown name for FI based on addr - char routine[2048]; - sprintf (routine, "addr=<%p>", (void*)addr); - void *handle=NULL; - TAU_PROFILER_CREATE(handle, routine, "", TAU_DEFAULT); - - HashNode *add = (HashNode*)malloc(sizeof(HashNode)); - add->id = addr; - add->name = "UNKNOWN"; - add->fname = "UNKNOWN"; - add->lno = -1; - add->fi = (FunctionInfo*) handle; - add->excluded = 0; - hash_put(addr, add); - return add; -} - - -static int executionFinished = 0; -void runOnExit() { - executionFinished = 1; - Tau_destructor_trigger(); -} - -#if (defined(TAU_SICORTEX) || defined(TAU_SCOREP)) -#pragma weak __cyg_profile_func_enter -#endif /* SICORTEX || TAU_SCOREP */ -extern "C" void __cyg_profile_func_enter(void* func, void* callsite) { - int i; - int tid; - -#ifndef TAU_BFD - issueBfdWarningIfNecessary(); -#endif /* TAU_BFD */ - - if (executionFinished) { - return; - } - - HashNode *hn; - void * funcptr = func; -#ifdef __ia64__ - funcptr = *( void ** )func; -#endif - - tid = Tau_get_tid(); - - if (gnu_init) { - gnu_init = 0; - - // initialize array of flags that prevent re-entry - for (i=0; iexcluded) { - // finished in this routine, allow entry - compInstDisabled[tid] = 0; - Tau_global_decr_insideTAU_tid(tid); - return; - } - if (hn->fi == NULL) { - - RtsLayer::LockDB(); // lock, then check again - // *CWL* - why? Because another thread could be creating this now. - // Lock-and-check-again is more efficient than - // Lock-first-check-later. - if ( hn->fi == NULL) { - // remove the path - const char *filename = hn->fname; - if (filename) { - while (strchr(filename,'/') != NULL) { - filename = strchr(filename,'/')+1; - } - } else { - // *CWL* - filename can be NULL for a hashed address when it - // is considered too expensive to resolve ALL symbols in an - // executable or module when creating the hashtable for caching - // purposes. In this case, we fall back to resolving the symbol - // as and when the address is encountered. - filename = "(unknown)"; - if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - bfdUnitHandle = Tau_bfd_registerUnit(TAU_BFD_REUSE_GLOBALS); - } - TauBfdInfo *info = Tau_bfd_resolveBfdInfo(bfdUnitHandle, - Tau_convert_ptr_to_unsigned_long(funcptr)); - if (info == NULL) { - // Try again with executable - info = Tau_bfd_resolveBfdExecInfo(bfdUnitHandle, - Tau_convert_ptr_to_unsigned_long(funcptr)); - } - if (info != NULL) { - if (info->filename != NULL) { - filename = strdup(info->filename); - } - if (info->funcname != NULL) { - hn->name = strdup(info->funcname); - } - hn->lno = info->lineno; - free(info); - } - /* - for(i=0; isection->vma+syms[i]->value) == funcptr)) { - unsigned int linenumber; - bfd_find_nearest_line(BfdImage, bfd_get_section(syms[i]), syms, - syms[i]->value, &filename, &hn->name, &linenumber); - hn->lno = linenumber; - break; - } - } - */ - - } - - char *routine; - if (filename == NULL) filename=strdup("unknown"); - routine = (char*) malloc (strlen(hn->name)+strlen(filename)+1024); - sprintf (routine, "%s [{%s} {%d,0}]", hn->name, filename, hn->lno); - void *handle=NULL; - TAU_PROFILER_CREATE(handle, routine, "", TAU_DEFAULT); - free(routine); - hn->fi = (FunctionInfo*) handle; - } - RtsLayer::UnLockDB(); - } - Tau_start_timer(hn->fi,0, tid); - } else { - - RtsLayer::LockDB(); // lock, then check again - - if ( (hn = hash_get(Tau_convert_ptr_to_unsigned_long(funcptr)))) { - Tau_start_timer(hn->fi, 0, tid); - } else { - TAU_VERBOSE("Previously unhashed funcptr [%p]\n",Tau_convert_ptr_to_unsigned_long(funcptr)); - HashNode *node = createHashNode(Tau_convert_ptr_to_unsigned_long(funcptr)); - Tau_start_timer(node->fi, 0, tid); - } - - RtsLayer::UnLockDB(); - - } - - if ( gnu_init ) { - // we register this here at the end so that it is called - // before the VT objects are destroyed. Objects are destroyed and atexit targets are - // called in the opposite order in which they are created and registered. - - // Note: This doesn't work work VT with MPI, they re-register their atexit routine - // During MPI_Init. - atexit(runOnExit); - } - - // finished in this routine, allow entry - compInstDisabled[tid] = 0; - Tau_global_decr_insideTAU_tid(tid); -} - -extern "C" void _cyg_profile_func_enter(void* func, void* callsite) { - __cyg_profile_func_enter(func, callsite); -} - -extern "C" void __pat_tp_func_entry(const void *ea, const void *ra) { - __cyg_profile_func_enter((void *)ea, (void *)ra); - -} - - -extern "C" void ___cyg_profile_func_enter(void* func, void* callsite) { - __cyg_profile_func_enter(func, callsite); -} - - -#if (defined(TAU_SICORTEX) || defined(TAU_SCOREP)) -#pragma weak __cyg_profile_func_exit -#endif /* SICORTEX || TAU_SCOREP */ -extern "C" void __cyg_profile_func_exit(void* func, void* callsite) { - int tid; - -#ifndef TAU_BFD - issueBfdWarningIfNecessary(); -#endif /* TAU_BFD */ - - tid = Tau_get_tid(); - Tau_global_incr_insideTAU_tid(tid); - - // prevent entry into cyg_profile functions while inside entry - tid = Tau_get_tid(); - if (compInstDisabled[tid]) { - return; - } - - if (executionFinished) { - return; - } - HashNode *hn; - void * funcptr = func; -#ifdef __ia64__ - funcptr = *( void ** )func; -#endif - - if ( (hn = hash_get(Tau_convert_ptr_to_unsigned_long(funcptr))) ) { - if (hn->excluded) { - Tau_global_decr_insideTAU_tid(tid); - return; - } - - Tau_stop_timer(hn->fi, tid); - } else { - //printf ("NOT FOUND! : "); - } - Tau_global_decr_insideTAU_tid(tid); -} - -extern "C" void _cyg_profile_func_exit(void* func, void* callsite) { - __cyg_profile_func_exit(func, callsite); -} - -extern "C" void ___cyg_profile_func_exit(void* func, void* callsite) { - __cyg_profile_func_exit(func, callsite); -} - -extern "C" void __pat_tp_func_return(const void *ea, const void *ra) { - __cyg_profile_func_exit((void *)ea, (void *)ra); -} - -#endif /* TAU_XLC */ - -/********************************************* - * ******* END OF ORIGINAL BFD VERSION ******* - *********************************************/ - -#endif /* TAU_MINGW */ diff --git a/src/Profile/Makefile b/src/Profile/Makefile index 3fc556500..aa5a1104b 100644 --- a/src/Profile/Makefile +++ b/src/Profile/Makefile @@ -440,8 +440,9 @@ $(INSTALLDEST)/$(TAU_DISABLE): $(TAU_DISABLE) $(TAU_DISABLE_SHARED) cd $(INSTALLDEST) @if [ -d $(TAU_DISABLE_SHAREDDIR) ] ; then true; \ else mkdir $(TAU_DISABLE_SHAREDDIR); fi - cd $(TAU_DISABLE_SHAREDDIR) ; rm -f libTAU$(TAU_SHLIBX) + cd $(TAU_DISABLE_SHAREDDIR) ; rm -f libTAU$(TAU_SHLIBX) TAU.dll cd $(TAU_DISABLE_SHAREDDIR) ; ln -s ../$(TAU_DISABLE_SHARED) libTAU$(TAU_SHLIBX) + cd $(TAU_DISABLE_SHAREDDIR) ; ln -s ../$(TAU_DISABLE_SHARED) TAU.dll $(TAU_SHAREDDIR)/$(TAU_CUDA_LIB): $(TAU_CUDA_LIB) @echo Installing $? in $(TAU_SHAREDDIR) @@ -478,12 +479,14 @@ $(INSTALLDEST)/$(TAU_SHLIB): $(TAU_SHLIB) @if [ -d $(INSTALLDEST) ] ; then true; \ else mkdir $(INSTALLDEST) ;fi $(TAU_INSTALL) $? $(INSTALLDEST) - $(RM) $(INSTALLDEST)/libTAU$(TAU_SHLIBX) + $(RM) $(INSTALLDEST)/libTAU$(TAU_SHLIBX) $(INSTALLDEST)/TAU.dll cd $(INSTALLDEST) && ln -s $(TAU_SHLIB) libTAU$(TAU_SHLIBX) + cd $(INSTALLDEST) && ln -s $(TAU_SHLIB) TAU.dll @if [ -d $(TAU_SHAREDDIR) ] ; then true; \ else mkdir $(TAU_SHAREDDIR); fi - cd $(TAU_SHAREDDIR) ; rm -f libTAU$(TAU_SHLIBX) + cd $(TAU_SHAREDDIR) ; rm -f libTAU$(TAU_SHLIBX) TAU.dll cd $(TAU_SHAREDDIR) ; ln -s ../$(TAU_SHLIB) libTAU$(TAU_SHLIBX) + cd $(TAU_SHAREDDIR) ; ln -s ../$(TAU_SHLIB) TAU.dll ls $(TAU_SHAREDDIR) $(INSTALLDEST)/libTauMpi$(TAU_CONFIG)$(LSX): libTauMpi$(TAU_CONFIG)$(LSX) @@ -525,8 +528,9 @@ $(TAU_SHAREDDIR)/pytau$(TAU_SHLIBX): $(TAU_SHLIB) $(RM) $(TAU_SHAREDDIR)/* cd $(TAU_SHAREDDIR) && ln -s ../$(TAU_SHLIB) $(TAUPYTHON) && ln -s ../$(TAU_SHLIB) ctau_impl$(TAU_SHLIBX) cd $(TAU_SHAREDDIR) && ln -s ../tau.py . && ln -s ../ltau.py . - cd $(TAU_SHAREDDIR) ; rm -f libTAU$(TAU_SHLIBX) + cd $(TAU_SHAREDDIR) ; rm -f libTAU$(TAU_SHLIBX) TAU.dll cd $(TAU_SHAREDDIR) && ln -s ../$(TAU_SHLIB) libTAU$(TAU_SHLIBX) + cd $(TAU_SHAREDDIR) && ln -s ../$(TAU_SHLIB) TAU.dll cd $(INSTALLDEST) && ln -s shared$(TAU_CONFIG) bindings$(TAU_CONFIG) $(INSTALLDEST)/libpgnod_prof.a : diff --git a/src/Profile/TauBfd.cpp b/src/Profile/TauBfd.cpp index 95d9aed20..33cf567e6 100644 --- a/src/Profile/TauBfd.cpp +++ b/src/Profile/TauBfd.cpp @@ -1,11 +1,3 @@ -/* *CWL* Temporary fix. An appropriate reconciliation of the semantics of the two versions - will need to be explored and implemented at some point */ - -/*********************************** - * ******* TAU MINGW VERSION ******* - ***********************************/ -#ifdef TAU_MINGW - #ifdef TAU_BFD #include @@ -131,15 +123,16 @@ struct TauBfdUnit struct LocateAddressData { - LocateAddressData(TauBfdModule * _module) : - found(false), module(_module) + LocateAddressData(TauBfdModule * _module, TauBfdInfo & _info) : + found(false), module(_module), info(_info) { } bool found; TauBfdModule * module; - TauBfdInfo info; + TauBfdInfo & info; }; + // Internal function prototypes static bool Tau_bfd_internal_loadSymTab(TauBfdUnit *unit, int moduleIndex); static bool Tau_bfd_internal_loadExecSymTab(TauBfdUnit *unit); @@ -346,7 +339,7 @@ static void Tau_bfd_internal_updateWindowsMaps(TauBfdUnit *unit) TauBfdAddrMap * map = new TauBfdAddrMap; map->start = Tau_convert_ptr_to_unsigned_long(modInfo.lpBaseOfDll); map->end = map->start + modInfo.SizeOfImage; - map->offset = 0; // TODO: What's this supposed to be? + map->offset = 0; // Get the full module path name for the map if(GetModuleFileNameEx(hProc, hMod[i], map->name, sizeof(map->name)) == 0) { @@ -392,14 +385,15 @@ void Tau_bfd_updateAddressMaps(tau_bfd_handle_t handle) unit->modules.size()); } -vector & Tau_bfd_getAddressMaps(tau_bfd_handle_t handle) +vector const & +Tau_bfd_getAddressMaps(tau_bfd_handle_t handle) { Tau_bfd_checkHandle(handle); return bfdUnits[handle]->addressMaps; } tau_bfd_module_handle_t Tau_bfd_getModuleHandle(tau_bfd_handle_t handle, - uintptr_t probeAddr) + unsigned long probeAddr) { if (!Tau_bfd_checkHandle(handle)) { return TAU_BFD_INVALID_MODULE; @@ -431,112 +425,101 @@ Tau_bfd_getAddressMap(tau_bfd_handle_t handle, unsigned long probe_addr) // Probe for BFD information given a single address. bool Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, - uintptr_t probeAddr, TauBfdInfo & info) + unsigned long probeAddr, TauBfdInfo & info) { if (!Tau_bfd_checkHandle(handle)) { - return false; - } - TauBfdUnit *unit = bfdUnits[handle]; - - int matchingIdx = Tau_bfd_internal_getModuleIndex(unit, probeAddr); - if (matchingIdx == -1) { + info.secure(probeAddr); return false; } - if (!Tau_bfd_internal_loadSymTab(unit, matchingIdx)) { - return false; - } + TauBfdUnit * unit = bfdUnits[handle]; + TauBfdModule * module; + unsigned long addr0; + unsigned long addr1; - TauBfdModule *module = Tau_bfd_internal_getModuleFromIdx(unit, matchingIdx); + // Discover if we are searching in the executable or a module + int matchingIdx = Tau_bfd_internal_getModuleIndex(unit, probeAddr); + if (matchingIdx != -1) { + if (!Tau_bfd_internal_loadSymTab(unit, matchingIdx)) { + info.secure(probeAddr); + return false; + } + module = Tau_bfd_internal_getModuleFromIdx(unit, matchingIdx); - // Calculate first and second search addresses + // Calculate search addresses for module search #if defined(TAU_WINDOWS) && defined(TAU_MINGW) - unsigned long firstAddr = probeAddr; - unsigned long secondAddr = Tau_bfd_internal_getOffsetAddress( - unit, matchingIdx, probeAddr); + addr0 = probeAddr; + addr1 = Tau_bfd_internal_getOffsetAddress(unit, matchingIdx, probeAddr); #else - unsigned long firstAddr = Tau_bfd_internal_getOffsetAddress( - unit, matchingIdx, probeAddr); - unsigned long secondAddr = probeAddr; + addr0 = Tau_bfd_internal_getOffsetAddress(unit, matchingIdx, probeAddr); + addr1 = probeAddr; #endif + } else { + if (!Tau_bfd_internal_loadExecSymTab(unit)) { + info.secure(probeAddr); + return false; + } + module = unit->executableModule; + + // Calculate search addresses for executable search + // Only the first address is valid for the executable + addr0 = probeAddr; + addr1 = 0; + } // Convert address to something bfd can use. char hex_pc_string[100]; - sprintf(hex_pc_string, "%p", firstAddr); + sprintf(hex_pc_string, "%p", addr0); // Search BFD sections for address - LocateAddressData data(module); - data.info.probeAddr = bfd_scan_vma(hex_pc_string, NULL, 16); + LocateAddressData data(module, info); + info.probeAddr = bfd_scan_vma(hex_pc_string, NULL, 16); bfd_map_over_sections(module->bfdImage, Tau_bfd_internal_locateAddress, &data); - if (!data.found) { - // if not initially found, try again with second address - if (firstAddr != secondAddr) { -// TAU_VERBOSE("Tau_bfd_resolveBfdInfo: " -// "Trying alternate address [%p] from address [%p]\n", -// secondAddr, firstAddr); - sprintf(hex_pc_string, "%p", secondAddr); - data.info.probeAddr = bfd_scan_vma(hex_pc_string, NULL, 16); + // If the data wasn't found where we expected and we are searching + // in a module, try a few more addresses + if (!data.found && (module != unit->executableModule)) { + // Try the second address + if (addr0 != addr1) { + sprintf(hex_pc_string, "%p", addr1); + info.probeAddr = bfd_scan_vma(hex_pc_string, NULL, 16); bfd_map_over_sections(module->bfdImage, Tau_bfd_internal_locateAddress, &data); } - } - bool resolved = data.found && (data.info.funcname != NULL); - if (resolved) { - info = data.info; -#if defined(HAVE_GNU_DEMANGLE) && HAVE_GNU_DEMANGLE - char const * demangled = bfd_demangle(module->bfdImage, - info.funcname, DEMANGLE_FLAGS); - if (demangled) { - info.funcname = demangled; + // Try the executable + if(!data.found && Tau_bfd_internal_loadExecSymTab(unit)) { + sprintf(hex_pc_string, "%p", probeAddr); + info.probeAddr = bfd_scan_vma(hex_pc_string, NULL, 16); + bfd_map_over_sections(unit->executableModule->bfdImage, + Tau_bfd_internal_locateAddress, &data); } -#endif - } - return resolved; -} - -bool Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, - uintptr_t probeAddr, TauBfdInfo & info) -{ - if (!Tau_bfd_checkHandle(handle)) { - return false; } - TauBfdUnit * unit = bfdUnits[handle]; - TauBfdModule * module = unit->executableModule; - if (!Tau_bfd_internal_loadExecSymTab(unit)) { - return false; - } - - // Convert address to something bfd can use. - char hex_pc_string[100]; - sprintf(hex_pc_string, "%p", probeAddr); - - // Search BFD sections for address - // If we can only fail once for the executable - LocateAddressData data(module); - data.info.probeAddr = bfd_scan_vma(hex_pc_string, NULL, 16); - bfd_map_over_sections(module->bfdImage, Tau_bfd_internal_locateAddress, &data); - - bool resolved = data.found && (data.info.funcname != NULL); + bool resolved = data.found && (info.funcname != NULL); if (resolved) { - info = data.info; #if defined(HAVE_GNU_DEMANGLE) && HAVE_GNU_DEMANGLE - char const * demangled = bfd_demangle(module->bfdImage, - info.funcname, DEMANGLE_FLAGS); + char const * demangled = + bfd_demangle(module->bfdImage, info.funcname, DEMANGLE_FLAGS); if (demangled) { info.funcname = demangled; } + if(info.filename == NULL) { + info.filename = "(unknown)"; + } #endif + } else { + // Couldn't resolve the address. + // Fill in fields as best we can. + info.secure(info.probeAddr); } return resolved; } -static void Tau_bfd_internal_iterateOverSymTab( - TauBfdModule * module, TauBfdIterFn fn) +static void Tau_bfd_internal_iterateOverSymtab(TauBfdModule * module, + TauBfdIterFn fn, unsigned long offset) { - for(asymbol ** s=module->syms; *s; s++) - { + // Apply the iterator function to all symbols in the table + for(asymbol ** s=module->syms; *s; s++) { asymbol const & asym = **s; // Skip useless symbols (e.g. line numbers) @@ -549,7 +532,7 @@ static void Tau_bfd_internal_iterateOverSymTab( // Calculate symbol address unsigned long addr = asym.section->vma + asym.value; - // Get symbol name + // Get apprixmate symbol name char const * name = asym.name; if(name[0] == '.') { char const * mark = strchr((char*)name, '$'); @@ -558,79 +541,84 @@ static void Tau_bfd_internal_iterateOverSymTab( // Apply the iterator function // Names will be resolved and demangled later - fn(addr, name, NULL, 0); + fn(addr+offset, name); } - - module->processCode = TAU_BFD_SYMTAB_LOAD_SUCCESS; } -#if 0 -// Run a unit-defined iterator through symbols discovered in a Bfd module. -// If there are too many symbols in the module, we will avoid resolving -// the symbols but allow the iterator to perform its work. -int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, - tau_bfd_module_handle_t moduleHandle, TauBfdIterFn fn) +int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, TauBfdIterFn fn) { if (!Tau_bfd_checkHandle(handle)) { return TAU_BFD_SYMTAB_LOAD_FAILED; } TauBfdUnit * unit = bfdUnits[handle]; - int moduleIndex = (int)moduleHandle; - char const * moduleName = unit->addressMaps[moduleIndex]->name; - TauBfdModule * module = Tau_bfd_internal_getModuleFromIdx(unit, moduleIndex); + char const * execName = unit->executablePath; + TauBfdModule * module = unit->executableModule; - // Only process each module once. + // Only process the executable once. if(module->processCode != TAU_BFD_SYMTAB_NOT_LOADED) { - TAU_VERBOSE("Tau_bfd_processBfdModuleInfo: " - "%s was already processed (code %d). Will not reprocess.\n", - moduleName, module->processCode); + TAU_VERBOSE("Tau_bfd_processBfdExecInfo: " + "%s already processed (code %d). Will not reprocess.\n", + execName, module->processCode); return module->processCode; } - TAU_VERBOSE("Tau_bfd_processBfdModuleInfo: processing %s\n", moduleName); + TAU_VERBOSE("Tau_bfd_processBfdExecInfo: processing executable %s\n", execName); - // Make sure module symbol table is loaded - if (!Tau_bfd_internal_loadSymTab(unit, moduleIndex)) { + // Make sure executable symbol table is loaded + if (!Tau_bfd_internal_loadExecSymTab(unit)) { module->processCode = TAU_BFD_SYMTAB_LOAD_FAILED; return module->processCode; } - // Apply the iterator function to all symbols in the table - Tau_bfd_internal_iterateOverSymTab(module, fn); + // Process the symbol table + Tau_bfd_internal_iterateOverSymtab(module, fn, 0); + + module->processCode = TAU_BFD_SYMTAB_LOAD_SUCCESS; return module->processCode; } -#endif -int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, TauBfdIterFn fn) +int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, + tau_bfd_module_handle_t moduleHandle,TauBfdIterFn fn) { if (!Tau_bfd_checkHandle(handle)) { return TAU_BFD_SYMTAB_LOAD_FAILED; } TauBfdUnit * unit = bfdUnits[handle]; - char const * execName = unit->executablePath; - TauBfdModule * module = unit->executableModule; + unsigned int moduleIdx = (unsigned int)moduleHandle; + TauBfdModule * module = Tau_bfd_internal_getModuleFromIdx(unit, moduleIdx); + char const * name = unit->addressMaps[moduleIdx]->name; - // Only process the executable once. + // Only process the module once. if(module->processCode != TAU_BFD_SYMTAB_NOT_LOADED) { - TAU_VERBOSE("Tau_bfd_processBfdExecInfo: " + TAU_VERBOSE("Tau_bfd_processBfdModuleInfo: " "%s already processed (code %d). Will not reprocess.\n", - execName, module->processCode); + name, module->processCode); return module->processCode; } - TAU_VERBOSE("Tau_bfd_processBfdExecInfo: processing executable %s\n", execName); + TAU_VERBOSE("Tau_bfd_processBfdModuleInfo: processing module %s\n", name); - // Make sure executable symbol table is loaded - if (!Tau_bfd_internal_loadExecSymTab(unit)) { + // Make sure symbol table is loaded + if (!Tau_bfd_internal_loadSymTab(unit, moduleHandle)) { module->processCode = TAU_BFD_SYMTAB_LOAD_FAILED; return module->processCode; } - // Apply the iterator function to all symbols in the table - Tau_bfd_internal_iterateOverSymTab(module, fn); + unsigned int offset; +#if defined(TAU_WINDOWS) && defined(TAU_MINGW) + offset = 0; +#else + offset = unit->addressMaps[moduleIdx]->start; +#endif + + // Process the symbol table + Tau_bfd_internal_iterateOverSymtab(module, fn, offset); + + module->processCode = TAU_BFD_SYMTAB_LOAD_SUCCESS; return module->processCode; } + static bool Tau_bfd_internal_loadSymTab(TauBfdUnit *unit, int moduleIndex) { if ((moduleIndex == TAU_BFD_NULL_MODULE_HANDLE) || @@ -656,7 +644,7 @@ static bool Tau_bfd_internal_loadExecSymTab(TauBfdUnit *unit) static int Tau_bfd_internal_getModuleIndex( TauBfdUnit *unit, unsigned long probe_addr) { - vector & addressMaps = unit->addressMaps; + vector const & addressMaps = unit->addressMaps; for (int i = 0; i < addressMaps.size(); i++) { if (probe_addr >= addressMaps[i]->start && probe_addr <= addressMaps[i]->end) @@ -674,8 +662,8 @@ static unsigned long Tau_bfd_internal_getOffsetAddress( return (probe_addr - unit->addressMaps[moduleIndex]->start); } -static TauBfdModule *Tau_bfd_internal_getModuleFromIdx( - TauBfdUnit *unit, int moduleIndex) +static TauBfdModule * +Tau_bfd_internal_getModuleFromIdx(TauBfdUnit * unit, int moduleIndex) { if (moduleIndex == -1) { return unit->executableModule; @@ -747,11 +735,6 @@ static char const * Tau_bfd_internal_getExecutablePath() return path; } - -// This is the mapping function to be applied across sections for random -// probing addresses to be supplied in some global variable. In this -// module, the global variables are compartmentalized by unit and pointed -// to by the variable currentModule. static void Tau_bfd_internal_locateAddress(bfd * bfdptr, asection * section, void * dataPtr) { @@ -779,852 +762,208 @@ static void Tau_bfd_internal_locateAddress(bfd * bfdptr, // The section contains this address, so try to resolve info data.found = bfd_find_nearest_line(bfdptr, section, data.module->syms, (data.info.probeAddr - vma), - &data.info.filename, &data.info.funcname, &data.info.lno); + &data.info.filename, &data.info.funcname, + (unsigned int*)&data.info.lineno); } -#endif /* TAU_BFD */ - -/****************************************** - * ******* END OF TAU MINGW VERSION ******* - ******************************************/ - -#else /* TAU_MINGW */ - -/************************************** - * ******* ORIGINAL BFD VERSION ******* - **************************************/ - -#ifdef TAU_BFD - -#include -#include -#if defined(HAVE_GNU_DEMANGLE) && HAVE_GNU_DEMANGLE -#define HAVE_DECL_BASENAME 1 -#include -#endif /* HAVE_GNU_DEMANGLE */ -#include - -#ifdef TAU_BGP -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif /* _GNU_SOURCE */ -#include -#endif /* TAU_BGP */ - -#include -#include -#include -#include -#include -#include -using namespace std; - -class TauBfdModule { -public: - bfd *bfdImage; - asymbol **syms; - int nr_all_syms; - - // per-pc global mapping variables - const char *located_filename; - const char *located_funcname; - unsigned int located_lineno; - bool symbol_found; - bfd_vma curr_pc; - - // For EBS book-keeping - bool bfdOpen; // once open, symtabs are loaded and never released - char *demangled_funcname; - -public: - TauBfdModule() { - bfdImage = NULL; - syms = NULL; - nr_all_syms = 0; - - located_lineno = 0; - symbol_found = false; - - bfdOpen = false; - demangled_funcname = NULL; - }; - ~TauBfdModule() { - free(bfdImage); - free(syms); - }; -}; - -typedef struct { - int type; - char *executablePath; - TauBfdModule *executableModule; - vector *addressMaps; - vector *modules; -} TauBfdUnit; -#define TAU_MAX_BFD_UNITS 64 - -// Global Variables -int bfdUnitCount = 0; -TauBfdUnit *bfdUnits[TAU_MAX_BFD_UNITS]; -static TauBfdModule *currentModule = NULL; - -// Internal function prototypes -static bool Tau_bfd_internal_loadSymTab(TauBfdUnit *unit, int moduleIndex); -static bool Tau_bfd_internal_loadExecSymTab(TauBfdUnit *unit); -static int Tau_bfd_internal_getModuleIndex(TauBfdUnit *unit, - unsigned long probe_addr); -static TauBfdModule *Tau_bfd_internal_getModuleFromIdx(TauBfdUnit *unit, - int moduleIndex); -static unsigned long Tau_bfd_internal_getOffsetAddress(TauBfdUnit *unit, - int moduleIndex, - unsigned long probe_addr); -static void Tau_bfd_internal_addExeAddressMap(); -static void Tau_bfd_internal_locateAddress(bfd *bfdptr, - asection *section, - void *data ATTRIBUTE_UNUSED); -static int Tau_bfd_internal_getBGPJobID(const char *path, char *name); -static char *Tau_bfd_internal_getExecutablePath(); -static void Tau_bfd_internal_updateProcSelfMaps(TauBfdUnit *unit); -static void Tau_bfd_internal_updateBGPMaps(TauBfdUnit *unit); - -#ifdef TAU_BGP -static int Tau_bfd_internal_BGP_dl_iter_callback(struct dl_phdr_info *info, - size_t size, - void *data); -#endif /* TAU_BGP */ - -// Main interface functions -void Tau_bfd_initializeBfdIfNecessary() { - static bool bfdInitialized = false; - if (!bfdInitialized) { - bfd_init(); - bfdInitialized = true; - } -} +// +// Deprecated interface functions maintained for backwards compatibility. +// These should be phased out soon since they do unnecessary work and +// have lead to memory leaks. +// tau_bfd_handle_t Tau_bfd_registerUnit(int flag) { - tau_bfd_handle_t ret = bfdUnitCount; - bfdUnits[bfdUnitCount] = (TauBfdUnit*)malloc(sizeof(TauBfdUnit)); - bfdUnits[bfdUnitCount]->type = flag; - - bfdUnits[bfdUnitCount]->modules = new vector(); - bfdUnits[bfdUnitCount]->addressMaps = new vector(); - - // These fields should always be available. - bfdUnits[bfdUnitCount]->executablePath = - Tau_bfd_internal_getExecutablePath(); - bfdUnits[bfdUnitCount]->executableModule = new TauBfdModule(); - - TAU_VERBOSE("Tau_bfd_registerUnit: Unit %d registered and initialized\n", - bfdUnitCount); - // Initialize the first address maps for the unit. - bfdUnitCount++; - Tau_bfd_updateAddressMaps(ret); - return ret; + return Tau_bfd_registerUnit(); } -bool Tau_bfd_checkHandle(tau_bfd_handle_t handle) { - if (handle == TAU_BFD_NULL_HANDLE) { - TAU_VERBOSE("TauBfd: Warning - attempt to use uninitialized BFD handle\n"); - return false; - } - if (handle >= bfdUnitCount) { - TAU_VERBOSE("TauBfd: Warning - invalid BFD unit handle %d, max value %d\n", handle, bfdUnitCount); - return false; - } - // TAU_VERBOSE("TauBfd: Valid BFD Handle\n"); - return true; -} - -static void Tau_bfd_internal_updateProcSelfMaps(TauBfdUnit *unit) { -// *CWL* - This is important! We DO NOT want to use /proc/self/maps on -// the BGP because the information acquired comes from the I/O nodes -// and not the compute nodes. You could end up with an overlapping -// range for address resolution if used! -#ifndef TAU_BGP - // Note: Linux systems only. - FILE *mapsfile = fopen("/proc/self/maps", "r"); - char line[4096]; - // count is used for TAU_VERBOSE only - int count = 0; - while (!feof(mapsfile)) { - fgets(line, 4096, mapsfile); - unsigned long start, end, offset; - char module[4096]; - char perms[5]; - module[0] = 0; - - sscanf(line, "%lx-%lx %s %lx %*s %*u %[^\n]", - &start, &end, perms, &offset, module); - if (*module && ((strcmp(perms, "r-xp") == 0) || - (strcmp(perms, "rwxp") == 0))) { - TAU_VERBOSE("[%d] Module: %s, %p-%p (%d)\n", - count++, module, start, end, offset); - TauBfdAddrMap map; - map.start = start; - map.end = end; - map.offset = offset; - sprintf(map.name, "%s", module); - unit->addressMaps->push_back(map); - if (unit->type == TAU_BFD_KEEP_GLOBALS) { - // create a mirror module structure for each address map - TauBfdModule *bfdModule = new TauBfdModule(); - unit->modules->push_back(bfdModule); - } - } - } - fclose(mapsfile); -#endif /* TAU_BGP */ -} - -#ifdef TAU_BGP -static int Tau_bfd_internal_BGP_dl_iter_callback(struct dl_phdr_info *info, - size_t size, - void *data) { - if (strcmp("", info->dlpi_name) == 0) { - TAU_VERBOSE("Tau_bfd_internal_BGP_dl_iter_callback: Nameless module. Ignored.\n"); - return 0; - } - TauBfdUnit *unit = (TauBfdUnit *)data; - TauBfdAddrMap map; - map.start = (unsigned long)info->dlpi_addr; - // assumption - the max of the physical addresses of each segment added - // to the memory size yields the end of the address range. - // It is unclear if any of the other factors affect it. - unsigned long max_addr = 0x0; - for (int j=0; jdlpi_phnum; j++) { - unsigned long local_max = - (unsigned long)info->dlpi_phdr[j].p_paddr + - (unsigned long)info->dlpi_phdr[j].p_memsz; - if (local_max > max_addr) { - max_addr = local_max; +TauBfdInfo * Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, + unsigned long probe_addr) +{ + TauBfdInfo * info = new TauBfdInfo; + if(Tau_bfd_resolveBfdInfo(handle, probe_addr, *info)) { + return info; } - } - map.end = map.start + max_addr; - map.offset = 0; // assume. - sprintf(map.name, "%s", info->dlpi_name); - TAU_VERBOSE("BGP Module: %s, %p-%p (%d)\n", - map.name, map.start, map.end, map.offset); - unit->addressMaps->push_back(map); - if (unit->type == TAU_BFD_KEEP_GLOBALS) { - // create a mirror module structure for each address map - TauBfdModule *bfdModule = new TauBfdModule(); - unit->modules->push_back(bfdModule); - } - return 0; -} -#endif /* TAU_BGP */ - -static void Tau_bfd_internal_updateBGPMaps(TauBfdUnit *unit) { -#ifdef TAU_BGP - dl_iterate_phdr(Tau_bfd_internal_BGP_dl_iter_callback, (void *)unit); -#endif /* TAU_BGP */ + delete info; + return NULL; } -void Tau_bfd_updateAddressMaps(tau_bfd_handle_t handle) { - if (!Tau_bfd_checkHandle(handle)) { - return; - } - // TAU_VERBOSE("Tau_bfd_updateAddressMaps: Updating object maps\n"); - TauBfdUnit *unit = bfdUnits[handle]; - - // Clear old information from vector. This relies on the fact that - // addressMaps are non-pointer structures - // modules are class objects with properly written destructors - unit->addressMaps->clear(); - if (unit->type != TAU_BFD_REUSE_GLOBALS) { - unit->modules->clear(); - } - -#ifdef TAU_BGP - Tau_bfd_internal_updateBGPMaps(unit); -#else - Tau_bfd_internal_updateProcSelfMaps(unit); -#endif /* TAU_BGP */ - - // We must have at least one module structure to host globals for BFD - // operations. - // Note that TAU_BFD_KEEP_GLOBALS may still create 0 module entries if - // there are zero address maps (which is allowed). - TAU_VERBOSE("Tau_bfd_updateAddressMaps: %d modules discovered\n", - unit->modules->size()); - if (unit->modules->size() == 0) { - TauBfdModule *bfdModule = new TauBfdModule(); - unit->modules->push_back(bfdModule); - } -} - -vector *Tau_bfd_getAddressMaps(tau_bfd_handle_t handle) { - if (!Tau_bfd_checkHandle(handle)) { - return NULL; - } - - // If we have a valid bfd handle, addressMaps is always available. - return bfdUnits[handle]->addressMaps; -} - -tau_bfd_module_handle_t Tau_bfd_getModuleHandle(tau_bfd_handle_t handle, - unsigned long probe_addr) { - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_INVALID_MODULE; - } - TauBfdUnit *unit = bfdUnits[handle]; - int matchingIdx = Tau_bfd_internal_getModuleIndex(unit, probe_addr); - if (matchingIdx == -1) { - return TAU_BFD_NULL_MODULE_HANDLE; - } else { - return (tau_bfd_module_handle_t)matchingIdx; - } -} +TauBfdInfo * Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, + unsigned long probe_addr) +{ + TauBfdInfo * info = new TauBfdInfo; -int Tau_bfd_getAddressMap(tau_bfd_handle_t handle, - unsigned long probe_addr, TauBfdAddrMap *mapInfo) { - if (!Tau_bfd_checkHandle(handle)) { - return 0; - } - // TAU_VERBOSE("Tau_bfd_updateAddressMaps: Updating object maps\n"); - TauBfdUnit *unit = bfdUnits[handle]; - int matchingIdx = Tau_bfd_internal_getModuleIndex(unit, probe_addr); - if (matchingIdx == -1) { - return TAU_BFD_NULL_MODULE_HANDLE; - } - mapInfo->start = (*unit->addressMaps)[matchingIdx].start; - mapInfo->end = (*unit->addressMaps)[matchingIdx].end; - mapInfo->offset = (*unit->addressMaps)[matchingIdx].offset; - strcpy(mapInfo->name, (*unit->addressMaps)[matchingIdx].name); + // Tau_bfd_resolveBfdInfo works on both executables and modules + if(Tau_bfd_resolveBfdInfo(handle, probe_addr, *info)) { + return info; + } + delete info; + return NULL; } -// Probe for BFD information given a single address. -TauBfdInfo *Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, - unsigned long probe_addr) { - if (!Tau_bfd_checkHandle(handle)) { - return NULL; - } - TauBfdUnit *unit = bfdUnits[handle]; - int matchingIdx = Tau_bfd_internal_getModuleIndex(unit, probe_addr); - // TAU_VERBOSE("Tau_bfd_resolveBfdInfo: Matching module index %d for addr [%p]\n", matchingIdx, probe_addr); - - if (matchingIdx == -1) { - return NULL; - } - - if (!Tau_bfd_internal_loadSymTab(unit, matchingIdx)) { - return NULL; - } - - // Convert address to something bfd can use. - char hex_pc_string[100]; - sprintf(hex_pc_string, "%p", probe_addr); - - TauBfdModule *module = Tau_bfd_internal_getModuleFromIdx(unit, matchingIdx); +int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, + tau_bfd_module_handle_t moduleHandle, int maxProbe, + DeprecatedTauBfdIterFn fn) +{ + bool do_getsrc; + if (!Tau_bfd_checkHandle(handle)) { + return TAU_BFD_SYMTAB_LOAD_FAILED; + } + TauBfdUnit *unit = bfdUnits[handle]; - module->curr_pc = bfd_scan_vma(hex_pc_string, NULL, 16); - module->symbol_found = false; - if (module->demangled_funcname != NULL) { - free(module->demangled_funcname); - } - module->demangled_funcname = NULL; - currentModule = module; // set up global variable for mapping over BFD - bfd_map_over_sections(module->bfdImage, - Tau_bfd_internal_locateAddress, 0); - if (!module->symbol_found) { - // if not initially found, try again with offset address. - unsigned long offsetAddr = Tau_bfd_internal_getOffsetAddress(unit, - matchingIdx, - probe_addr); - TAU_VERBOSE("Tau_bfd_resolveBfdInfo: Trying alternate address [%p] from address [%p]\n", offsetAddr, probe_addr); - if (offsetAddr != probe_addr) { - // try only if they are not the same - sprintf(hex_pc_string, "%p", offsetAddr); - module->curr_pc = bfd_scan_vma(hex_pc_string, NULL, 16); - bfd_map_over_sections(module->bfdImage, - Tau_bfd_internal_locateAddress, 0); - } - } + int moduleIndex = (int) moduleHandle; + char const * moduleName = unit->addressMaps[moduleIndex]->name; + unsigned long offset = unit->addressMaps[moduleIndex]->start; + TauBfdModule * module = Tau_bfd_internal_getModuleFromIdx(unit, moduleIndex); - // If we fail again, then there's nothing we can do about it. - if (module->symbol_found && - (module->located_funcname != (char *)NULL)) { + TAU_VERBOSE("Tau_bfd_processModuleInfo (deprecated): processing %s\n", moduleName); + bool success = Tau_bfd_internal_loadSymTab(unit, moduleIndex); + if (!success) { + return TAU_BFD_SYMTAB_LOAD_FAILED; + } else { + asymbol **syms = module->syms; + int nr_all_syms = module->nr_all_syms; + + do_getsrc = true; + if (nr_all_syms > maxProbe) { + TAU_VERBOSE("Tau_bfd_processBfdModuleInfo (deprecated): " + "Too many [%d] symbols in module [%s]. " + "Not resolving details.\n", + nr_all_syms, moduleName); + do_getsrc = false; + } + for (int i = 0; i < nr_all_syms; ++i) { + char* dem_name = 0; + unsigned long addr; + const char* filename; + const char* funcname; + unsigned int lno; + + /* get filename and linenumber from debug info */ + /* needs -g */ + filename = NULL; + lno = 0; + if (do_getsrc) { + bfd_find_nearest_line(module->bfdImage, + bfd_get_section(syms[i]), syms, + syms[i]->value, &filename, &funcname, &lno); + } + + /* calculate function address */ + addr = syms[i]->section->vma + syms[i]->value; + + /* use demangled name if possible */ #if defined(HAVE_GNU_DEMANGLE) && HAVE_GNU_DEMANGLE - // could also use bfd_demangle - module->demangled_funcname = - cplus_demangle(module->located_funcname, - DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE | DMGL_TYPES); - /* - TAU_VERBOSE("Tau_bfd_resolveBfdInfo: [%s] demangles to [%s]\n", - module->located_funcname, - module->demangled_funcname); - */ + dem_name = cplus_demangle(syms[i]->name, DMGL_PARAMS | DMGL_ANSI + | DMGL_VERBOSE | DMGL_TYPES); #endif /* HAVE_GNU_DEMANGLE */ - TauBfdInfo *info = (TauBfdInfo *)malloc(sizeof(TauBfdInfo)); - if (module->located_filename != NULL) { - info->filename = strdup(module->located_filename); - } else { - info->filename = NULL; - } - if (module->demangled_funcname != NULL) { - info->funcname = strdup(module->demangled_funcname); - } else { - info->funcname = strdup(module->located_funcname); - } - info->lineno = module->located_lineno; - TAU_VERBOSE("Tau_bfd_resolveBfdInfo: Addr [%p] symbol found [%s|%s|%d]\n", - probe_addr, info->filename, info->funcname, info->lineno); - currentModule = NULL; // reset the global - return info; - } - currentModule = NULL; // reset the global - return NULL; -} - -TauBfdInfo *Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, - unsigned long probe_addr) { - if (!Tau_bfd_checkHandle(handle)) { - return NULL; - } - TauBfdUnit *unit = bfdUnits[handle]; - - if (!Tau_bfd_internal_loadExecSymTab(unit)) { - return NULL; - } - - // Convert address to something bfd can use. - char hex_pc_string[100]; - sprintf(hex_pc_string, "%p", probe_addr); - TauBfdModule *module = unit->executableModule; - - module->curr_pc = bfd_scan_vma(hex_pc_string, NULL, 16); - module->symbol_found = false; - if (module->demangled_funcname != NULL) { - free(module->demangled_funcname); - } - module->demangled_funcname = NULL; - currentModule = module; // set up global variable for mapping over BFD - bfd_map_over_sections(module->bfdImage, - Tau_bfd_internal_locateAddress, 0); - // If we can only fail once for the executable - if (module->symbol_found && - (module->located_funcname != (char *)NULL)) { -#if defined(HAVE_GNU_DEMANGLE) && HAVE_GNU_DEMANGLE - // could also use bfd_demangle - module->demangled_funcname = - cplus_demangle(module->located_funcname, - DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE | DMGL_TYPES); - TAU_VERBOSE("Tau_bfd_resolveBfdExecInfo: [%s] demangles to [%s]\n", - module->located_funcname, - module->demangled_funcname); -#endif /* HAVE_GNU_DEMANGLE */ - TauBfdInfo *info = (TauBfdInfo *)malloc(sizeof(TauBfdInfo)); - if (module->located_filename != NULL) { - info->filename = strdup(module->located_filename); - } else { - info->filename = NULL; - } - if (module->demangled_funcname != NULL) { - info->funcname = strdup(module->demangled_funcname); - } else { - info->funcname = strdup(module->located_funcname); - } - info->lineno = module->located_lineno; - TAU_VERBOSE("Tau_bfd_resolveBfdExecInfo: Addr [%p] symbol found [%s|%s|%d]\n", - probe_addr, info->filename, info->funcname, info->lineno); - currentModule = NULL; // reset the global - return info; - } - currentModule = NULL; // reset the global - return NULL; + const char *name = syms[i]->name; + if (dem_name) { + name = dem_name; + } + fn(offset + addr, name, filename, lno); + } + } + if (do_getsrc) { + return TAU_BFD_SYMTAB_LOAD_SUCCESS; + } else { + return TAU_BFD_SYMTAB_LOAD_UNRESOLVED; + } } -// Run a unit-defined iterator through symbols discovered in a Bfd module. -// If there are too many symbols in the module, we will avoid resolving -// the symbols but allow the iterator to perform its work. -int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, - tau_bfd_module_handle_t moduleHandle, - int symbolLimit, - TauBfdIterFn fn) { - bool do_getsrc; - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_SYMTAB_LOAD_FAILED; - } - TauBfdUnit *unit = bfdUnits[handle]; - - int moduleIndex = (int)moduleHandle; - char *moduleName = (*unit->addressMaps)[moduleIndex].name; - unsigned long offset = (*unit->addressMaps)[moduleIndex].start; - TauBfdModule *module = Tau_bfd_internal_getModuleFromIdx(unit, moduleIndex); - - TAU_VERBOSE("Tau_bfd_processModuleInfo: processing %s\n", moduleName); - bool success = Tau_bfd_internal_loadSymTab(unit, moduleIndex); - if (!success) { - return TAU_BFD_SYMTAB_LOAD_FAILED; - } else { - asymbol **syms = module->syms; - int nr_all_syms = module->nr_all_syms; - - do_getsrc = true; - if (nr_all_syms > symbolLimit) { - TAU_VERBOSE("Tau_bfd_processBfdModuleInfo: Too many [%d] symbols in module [%s]. Not resolving details.\n", nr_all_syms, moduleName); - do_getsrc = false; - } - for (int i=0; ibfdImage, - bfd_get_section(syms[i]), syms, - syms[i]->value, &filename, &funcname, &lno); - } - - /* calculate function address */ - addr = syms[i]->section->vma+syms[i]->value; - - /* use demangled name if possible */ -#if defined(HAVE_GNU_DEMANGLE) && HAVE_GNU_DEMANGLE - dem_name = cplus_demangle(syms[i]->name, - DMGL_PARAMS | DMGL_ANSI - | DMGL_VERBOSE | DMGL_TYPES); -#endif /* HAVE_GNU_DEMANGLE */ - - const char *name = syms[i]->name; - if (dem_name) { - name = dem_name; - } - fn(offset+addr, name, filename, lno); - } - } - if (do_getsrc) { - return TAU_BFD_SYMTAB_LOAD_SUCCESS; - } else { - return TAU_BFD_SYMTAB_LOAD_UNRESOLVED; - } -} +int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, int maxProbe, + DeprecatedTauBfdIterFn fn) +{ + bool do_getsrc; -int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, - int symbolLimit, - TauBfdIterFn fn) { - bool do_getsrc; + if (!Tau_bfd_checkHandle(handle)) { + return TAU_BFD_SYMTAB_LOAD_FAILED; + } + TauBfdUnit *unit = bfdUnits[handle]; + char const * execName = unit->executablePath; + unsigned long offset = 0; + TauBfdModule *module = unit->executableModule; - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_SYMTAB_LOAD_FAILED; - } - TauBfdUnit *unit = bfdUnits[handle]; - char *execName = unit->executablePath; - unsigned long offset = 0; - TauBfdModule *module = unit->executableModule; - - TAU_VERBOSE("Tau_bfd_processBfdExecInfo: processing executable %s\n", - execName); - bool success = Tau_bfd_internal_loadExecSymTab(unit); - if (!success) { - return TAU_BFD_SYMTAB_LOAD_FAILED; - } else { - asymbol **syms = module->syms; - int nr_all_syms = module->nr_all_syms; - - do_getsrc = true; - if (nr_all_syms > symbolLimit) { - TAU_VERBOSE("Tau_bfd_processBfdExecInfo: Too many [%d] symbols in executable [%s]. Not resolving.\n", nr_all_syms, execName); - do_getsrc = false; - } - for (int i=0; ibfdImage, - bfd_get_section(syms[i]), syms, - syms[i]->value, &filename, &funcname, &lno); - } - - /* calculate function address */ - addr = syms[i]->section->vma+syms[i]->value; - - /* use demangled name if possible */ -#if defined(HAVE_GNU_DEMANGLE) && HAVE_GNU_DEMANGLE - dem_name = cplus_demangle(syms[i]->name, - DMGL_PARAMS | DMGL_ANSI - | DMGL_VERBOSE | DMGL_TYPES); + TAU_VERBOSE("Tau_bfd_processBfdExecInfo (deprecated): processing executable %s\n", + execName); + bool success = Tau_bfd_internal_loadExecSymTab(unit); + if (!success) { + return TAU_BFD_SYMTAB_LOAD_FAILED; + } else { + asymbol **syms = module->syms; + int nr_all_syms = module->nr_all_syms; + + do_getsrc = true; + if (nr_all_syms > maxProbe) { + TAU_VERBOSE("Tau_bfd_processBfdExecInfo (deprecated): " + "Too many [%d] symbols in executable [%s]. Not resolving.\n", + nr_all_syms, execName); + do_getsrc = false; + } + for (int i = 0; i < nr_all_syms; ++i) { + char* dem_name = 0; + unsigned long addr; + const char* filename; + const char* funcname; + unsigned int lno; + + /* get filename and linenumber from debug info */ + /* needs -g */ + filename = NULL; + lno = 0; + if (do_getsrc) { + bfd_find_nearest_line(module->bfdImage, + bfd_get_section(syms[i]), syms, + syms[i]->value, &filename, &funcname, &lno); + } + + /* calculate function address */ + addr = syms[i]->section->vma + syms[i]->value; + + /* use demangled name if possible */ +#if defined(HAVE_GNU_DEMANGLE) && HAVE_GNU_DEMANGLE + dem_name = cplus_demangle(syms[i]->name, DMGL_PARAMS | DMGL_ANSI + | DMGL_VERBOSE | DMGL_TYPES); #endif /* HAVE_GNU_DEMANGLE */ - - const char *name = syms[i]->name; - if (dem_name) { - name = dem_name; - } - fn(offset+addr, name, filename, lno); - } - } - if (do_getsrc) { - return TAU_BFD_SYMTAB_LOAD_SUCCESS; - } else { - return TAU_BFD_SYMTAB_LOAD_UNRESOLVED; - } -} - -bool Tau_bfd_internal_loadSymTab(TauBfdUnit *unit, int moduleIndex) { - int size; - - // No such module. - if ((moduleIndex == TAU_BFD_NULL_MODULE_HANDLE) || - (moduleIndex == TAU_BFD_INVALID_MODULE)) { - return false; - } - char *name = ((*unit->addressMaps)[moduleIndex]).name; - TauBfdModule *module = Tau_bfd_internal_getModuleFromIdx(unit, moduleIndex); - - // Symbol table is already open, safe to return true. - if (module->bfdOpen) { - return true; - } - - Tau_bfd_initializeBfdIfNecessary(); - module->bfdImage = bfd_openr(name, 0); - if (module->bfdImage == NULL) { - TAU_VERBOSE("Tau_bfd_internal_loadSymTab: Failed to open module [%s]\n", name); - return false; - } - - if (!bfd_check_format(module->bfdImage, bfd_object)) { - TAU_VERBOSE("Tau_bfd_internal_loadSymTab: bfd format check failed [%s]\n", name); - return false; - } - if (!(bfd_get_file_flags(module->bfdImage) & HAS_SYMS)) { - TAU_VERBOSE("Tau_bfd_internal_loadSymTab: bfd has no symbols [%s]\n", name); - return false; - } - size = bfd_get_symtab_upper_bound(module->bfdImage); - if (size < 1) { - TAU_VERBOSE("Tau_bfd_internal_loadSymTab: bfd_get_symtab_upper_bound() < 1\n"); - return false; - } - - module->syms = (asymbol **)malloc(size); - module->nr_all_syms = bfd_canonicalize_symtab(module->bfdImage, - module->syms); - if (module->nr_all_syms < 1) { - TAU_VERBOSE("Tau_bfd_internal_loadSymTab: No canonical symbols found in [%s]\n", - name); - return false; - } - - module->bfdOpen = true; - return true; -} - -bool Tau_bfd_internal_loadExecSymTab(TauBfdUnit *unit) { - int size; - - char *execPath = unit->executablePath; - TauBfdModule *module = unit->executableModule; - // Executable symbol table is already loaded. Safe to return true. - if (module->bfdOpen) { - return true; - } - - Tau_bfd_initializeBfdIfNecessary(); - module->bfdImage = bfd_openr(execPath, 0); - if (module->bfdImage == NULL) { - TAU_VERBOSE("Tau_bfd_internal_loadExecSymTab: Failed to open module [%s]\n", execPath); - return false; - } - - if (!bfd_check_format(module->bfdImage, bfd_object)) { - TAU_VERBOSE("Tau_bfd_internal_loadExecSymTab: bfd format check failed [%s]\n", execPath); - return false; - } - - if (!(bfd_get_file_flags(module->bfdImage) & HAS_SYMS)) { - TAU_VERBOSE("Tau_bfd_internal_loadExecSymTab: bfd has no symbols [%s]\n", execPath); - return false; - } - - size = bfd_get_symtab_upper_bound(module->bfdImage); - if (size < 1) { - TAU_VERBOSE("Tau_bfd_internal_loadExecSymTab: bfd_get_symtab_upper_bound() < 1\n"); - return false; - } - - module->syms = (asymbol **)malloc(size); - module->nr_all_syms = bfd_canonicalize_symtab(module->bfdImage, - module->syms); - if (module->nr_all_syms < 1) { - TAU_VERBOSE("Tau_bfd_internal_loadExecSymTab: No canonical symbols found in [%s]\n", - execPath); - return false; - } - - module->bfdOpen = true; - return true; -} - -// Internal BFD helper functions -static int Tau_bfd_internal_getModuleIndex(TauBfdUnit *unit, - unsigned long probe_addr) { - int ret = -1; - vector *addressMaps = unit->addressMaps; - for (int i=0;isize();i++) { - if (probe_addr >= (*addressMaps)[i].start && - probe_addr <= (*addressMaps)[i].end) { - return i; - } - } - return ret; -} - -static unsigned long Tau_bfd_internal_getOffsetAddress(TauBfdUnit *unit, - int moduleIndex, - unsigned long probe_addr) { - if (moduleIndex == TAU_BFD_NULL_MODULE_HANDLE) { - return probe_addr; - } - vector *addressMaps = unit->addressMaps; - return (probe_addr - (*addressMaps)[moduleIndex].start); -} - -static TauBfdModule *Tau_bfd_internal_getModuleFromIdx(TauBfdUnit *unit, - int moduleIndex) { - TauBfdModule *module = NULL; - if (moduleIndex == -1) { - return unit->executableModule; - } - if (unit->type == TAU_BFD_REUSE_GLOBALS) { - module = (*(unit->modules))[0]; - } else { - module = ((*unit->modules))[moduleIndex]; - } - return module; -} - -static int Tau_bfd_internal_getBGPJobID(const char *path, char *name) { - DIR *pdir = NULL; - pdir = opendir(path); - if (pdir == NULL) { - return -1; - } - - struct dirent *pent = NULL; - int i; - for (i=0; i < 3; i++) { - pent = readdir(pdir); - if (pent == NULL) { - return -1; - } - } - - strcpy(name, pent->d_name); - closedir(pdir); - return 0; -} - -static int Tau_bfd_internal_getBGPExePath(char *path) { - int rc; - char jobid[256]; - rc = Tau_bfd_internal_getBGPJobID("/jobs", jobid); - if (rc != 0) { - return -1; - } - sprintf (path, "/jobs/%s/exe", jobid); - return 0; + const char *name = syms[i]->name; + if (dem_name) { + name = dem_name; + } + fn(offset + addr, name, filename, lno); + } + } + if (do_getsrc) { + return TAU_BFD_SYMTAB_LOAD_SUCCESS; + } else { + return TAU_BFD_SYMTAB_LOAD_UNRESOLVED; + } } -static char *Tau_bfd_internal_getExecutablePath() { - char path[4096]; - int rc; - -#ifndef TAU_BFD - fprintf(stderr, "TAU: Warning! BFD not found, symbols will not be resolved\n"); - fprintf(stderr, "Please re-configure TAU with -bfd=download to support runtime symbol resolution using the BFD library.\n"); - return NULL; -#endif +// +// Deprecated query functions maintained for backwards compatibility. +// These should be phased out soon since they do unnecessary work and +// have lead to memory leaks. +// - /* System dependent methods to find the executable */ +int Tau_bfd_getAddressMap(tau_bfd_handle_t handle, unsigned long probe_addr, + TauBfdAddrMap * mapInfo) +{ + if (!Tau_bfd_checkHandle(handle)) { + return 0; + } - /* Default: Linux systems */ - sprintf(path, "%s", "/proc/self/exe"); - -#ifdef TAU_AIX - sprintf(path, "/proc/%d/object/a.out", getpid()); -#endif - -#ifdef TAU_BGP - rc = Tau_bfd_internal_getBGPExePath(path); - if (rc != 0) { - fprintf(stderr, "Tau_bfd_internal_getExecutablePath: Warning! Cannot find BG/P executable path [%s], symbols will not be resolved\n", path); - return NULL; - } -#endif - -#ifdef __APPLE__ - uint32_t size = sizeof(path); - _NSGetExecutablePath(path, &size); -#endif + TauBfdUnit * unit = bfdUnits[handle]; + int matchingIdx = Tau_bfd_internal_getModuleIndex(unit, probe_addr); + if (matchingIdx == -1) { + return TAU_BFD_NULL_MODULE_HANDLE; + } - char *retPath = strdup(path); - return retPath; + mapInfo->start = unit->addressMaps[matchingIdx]->start; + mapInfo->end = unit->addressMaps[matchingIdx]->end; + mapInfo->offset = unit->addressMaps[matchingIdx]->offset; + strcpy(mapInfo->name, unit->addressMaps[matchingIdx]->name); } -// This is the mapping function to be applied across sections for random -// probing addresses to be supplied in some global variable. In this -// module, the global variables are compartmentalized by unit and pointed -// to by the variable currentModule. -static void Tau_bfd_internal_locateAddress(bfd *bfdptr, - asection *section, - void *data ATTRIBUTE_UNUSED) { - if (currentModule == NULL) { - TAU_VERBOSE("Tau_bfd_internal_locateAddress: No current module\n"); - return; - } - bfd_vma vma_addr; - bfd_size_type size; - - if (currentModule->symbol_found) { - return; - } - - if ((bfd_get_section_flags(bfdptr, section) & SEC_ALLOC) == 0) { - return; - } - - vma_addr = bfd_get_section_vma(bfdptr, section); - - if (currentModule->curr_pc < vma_addr) { - return; - } - - size = bfd_get_section_size(section); - if (currentModule->curr_pc >= vma_addr + size) { - return; - } - - currentModule->symbol_found = - bfd_find_nearest_line(bfdptr, section, - currentModule->syms, - currentModule->curr_pc - vma_addr, - &(currentModule->located_filename), - &(currentModule->located_funcname), - &(currentModule->located_lineno)); -} #endif /* TAU_BFD */ - -/********************************************* - * ******* END OF ORIGINAL BFD VERSION ******* - *********************************************/ - -#endif /* TAU_MINGW */ diff --git a/src/Profile/TauBfdUnimplemented.cpp b/src/Profile/TauBfdUnimplemented.cpp index 0a109fde7..bbf0d86ea 100644 --- a/src/Profile/TauBfdUnimplemented.cpp +++ b/src/Profile/TauBfdUnimplemented.cpp @@ -1,11 +1,3 @@ -/* *CWL* Temporary fix. An appropriate reconciliation of the semantics of the two versions - will need to be explored and implemented at some point */ - -/*********************************** - * ******* TAU MINGW VERSION ******* - ***********************************/ -#ifdef TAU_MINGW - // *CWL* This code is used for two (rather different) purposes. // // 1. When a shared library for BFD is not available and -optShared @@ -28,11 +20,16 @@ using namespace std; #define TAU_BFD_UNIMPLEMENTED_HANDLE -1337 #define TAU_BFD_UNIMPLEMENTED_MODULE_HANDLE -11337 +static vector addressMaps; + // Empty interface functions static void Tau_bfd_internal_issueBfdWarningIfNecessary() { static bool warningIssued = false; if (!warningIssued) { - fprintf(stderr,"TAU Warning: BFD is not available in at least one part of this TAU-instrumented application! Please check to see if BFD is not shared or not present. Expect some missing BFD functionality.\n"); + fprintf(stderr,"TAU Warning: BFD is not available in at least one part " + "of this TAU-instrumented application! Please check to see if " + "BFD is not shared or not present. Expect some missing BFD " + "functionality.\n"); warningIssued = true; } } @@ -41,230 +38,129 @@ void Tau_bfd_initializeBfdIfNecessary() { Tau_bfd_internal_issueBfdWarningIfNecessary(); } -tau_bfd_handle_t Tau_bfd_registerUnit(int flag) { +tau_bfd_handle_t Tau_bfd_registerUnit() { Tau_bfd_internal_issueBfdWarningIfNecessary(); - addressMaps = new vector(); return TAU_BFD_UNIMPLEMENTED_HANDLE; } bool Tau_bfd_checkHandle(tau_bfd_handle_t handle) { Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (handle == TAU_BFD_UNIMPLEMENTED_HANDLE) { - return true; - } - return false; + return (handle == TAU_BFD_UNIMPLEMENTED_HANDLE); } void Tau_bfd_updateAddressMaps(tau_bfd_handle_t handle) { Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return; - } + Tau_bfd_checkHandle(handle); } -vector *Tau_bfd_getAddressMaps(tau_bfd_handle_t handle) { +std::vector const & +Tau_bfd_getAddressMaps(tau_bfd_handle_t handle) { Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return NULL; - } return addressMaps; } +TauBfdAddrMap const * +Tau_bfd_getAddressMap(tau_bfd_handle_t handle, unsigned long probe_addr) +{ + Tau_bfd_internal_issueBfdWarningIfNecessary(); + return NULL; +} + tau_bfd_module_handle_t Tau_bfd_getModuleHandle(tau_bfd_handle_t handle, - uintptr_t probeAddr) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_NULL_MODULE_HANDLE; - } - return TAU_BFD_UNIMPLEMENTED_MODULE_HANDLE; + unsigned long probeAddr) +{ + Tau_bfd_internal_issueBfdWarningIfNecessary(); + if (!Tau_bfd_checkHandle(handle)) { + return TAU_BFD_NULL_MODULE_HANDLE; + } + return TAU_BFD_UNIMPLEMENTED_MODULE_HANDLE; } bool Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, - uintptr_t probe_addr, TauBfdInfo & info) + unsigned long probeAddr, TauBfdInfo & info) { Tau_bfd_internal_issueBfdWarningIfNecessary(); + info.secure(probeAddr); return false; } -bool Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, - uintptr_t probe_addr, TauBfdInfo & info) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - return false; -} - int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, - tau_bfd_module_handle_t moduleHandle, TauBfdIterFn fn) + tau_bfd_module_handle_t moduleHandle,TauBfdIterFn fn) { Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_SYMTAB_LOAD_FAILED; + if (Tau_bfd_checkHandle(handle)) { + return TAU_BFD_SYMTAB_LOAD_SUCCESS; } - return TAU_BFD_SYMTAB_LOAD_UNRESOLVED; + return TAU_BFD_SYMTAB_LOAD_FAILED; } int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, TauBfdIterFn fn) { Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_SYMTAB_LOAD_FAILED; + if (Tau_bfd_checkHandle(handle)) { + return TAU_BFD_SYMTAB_LOAD_SUCCESS; } - return TAU_BFD_SYMTAB_LOAD_UNRESOLVED; + return TAU_BFD_SYMTAB_LOAD_FAILED; } -/****************************************** - * ******* END OF TAU MINGW VERSION ******* - ******************************************/ - -#else /* TAU_MINGW */ -/************************************** - * ******* ORIGINAL BFD VERSION ******* - **************************************/ - -// *CWL* This code is used for two (rather different) purposes. // -// 1. When a shared library for BFD is not available and -optShared -// is required as an option to build the application. +// Deprecated interface functions maintained for backwards compatibility. +// These should be phased out soon since they do unnecessary work and +// have lead to memory leaks. // -// 2. When BFD is not available at all (the interface is still required). - -/* Not exactly empty. Support for address maps are independent of BFD */ -#include -#include - -#include -#include -#include -#include -#include -#include -using namespace std; - -#define TAU_BFD_UNIMPLEMENTED_HANDLE -1337 -#define TAU_BFD_UNIMPLEMENTED_MODULE_HANDLE -11337 - -vector *addressMaps; - -// Empty interface functions -static void Tau_bfd_internal_issueBfdWarningIfNecessary() { - static bool warningIssued = false; - if (!warningIssued) { - fprintf(stderr,"TAU Warning: BFD is not available in at least one part of this TAU-instrumented application! Please check to see if BFD is not shared or not present. Expect some missing BFD functionality.\n"); - warningIssued = true; - } -} - -void Tau_bfd_initializeBfdIfNecessary() { - Tau_bfd_internal_issueBfdWarningIfNecessary(); -} tau_bfd_handle_t Tau_bfd_registerUnit(int flag) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - addressMaps = new vector(); - return TAU_BFD_UNIMPLEMENTED_HANDLE; -} - -bool Tau_bfd_checkHandle(tau_bfd_handle_t handle) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (handle == TAU_BFD_UNIMPLEMENTED_HANDLE) { - return true; - } - return false; -} - -void Tau_bfd_updateAddressMaps(tau_bfd_handle_t handle) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return; - } - TAU_VERBOSE("Tau_bfd_updateAddressMaps: Updating object maps\n"); - - addressMaps->clear(); - // Note: Linux systems only. - FILE *mapsfile = fopen("/proc/self/maps", "r"); - if (mapsfile == NULL) { - return; - } - char line[4096]; - while (!feof(mapsfile)) { - fgets(line, 4096, mapsfile); - unsigned long start, end, offset; - char module[4096]; - char perms[5]; - module[0] = 0; - - sscanf(line, "%lx-%lx %s %lx %*s %*u %[^\n]", - &start, &end, perms, &offset, module); - if (*module && ((strcmp(perms, "r-xp") == 0) || - (strcmp(perms, "rwxp") == 0))) { - TAU_VERBOSE("got %s, %p-%p (%d)\n", module, start, end, offset); - TauBfdAddrMap map; - map.start = start; - map.end = end; - map.offset = offset; - sprintf(map.name, "%s", module); - addressMaps->push_back(map); - } - } - fclose(mapsfile); -} - -vector *Tau_bfd_getAddressMaps(tau_bfd_handle_t handle) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return NULL; - } - return addressMaps; + return Tau_bfd_registerUnit(); } -tau_bfd_module_handle_t Tau_bfd_getModuleHandle(tau_bfd_handle_t handle, - unsigned long probe_addr) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_NULL_MODULE_HANDLE; - } - return TAU_BFD_UNIMPLEMENTED_MODULE_HANDLE; -} +TauBfdInfo * Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, + unsigned long probe_addr) +{ + Tau_bfd_internal_issueBfdWarningIfNecessary(); -// Probe for BFD information given a single address. -TauBfdInfo *Tau_bfd_resolveBfdInfo(tau_bfd_handle_t handle, - unsigned long probe_addr) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - return NULL; + TauBfdInfo * info = new TauBfdInfo; + Tau_bfd_resolveBfdInfo(handle, probe_addr, *info); + return info; } -TauBfdInfo *Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, - unsigned long probe_addr) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - return NULL; +TauBfdInfo * Tau_bfd_resolveBfdExecInfo(tau_bfd_handle_t handle, + unsigned long probe_addr) +{ + Tau_bfd_internal_issueBfdWarningIfNecessary(); + return NULL; } -// Run a unit-defined iterator through symbols discovered in a Bfd module. -// If there are too many symbols in the module, we will avoid resolving -// the symbols but allow the iterator to perform its work. int Tau_bfd_processBfdModuleInfo(tau_bfd_handle_t handle, - tau_bfd_module_handle_t moduleHandle, - int symbolLimit, - TauBfdIterFn fn) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_SYMTAB_LOAD_FAILED; - } - return TAU_BFD_SYMTAB_LOAD_UNRESOLVED; + tau_bfd_module_handle_t moduleHandle, int maxProbe, + DeprecatedTauBfdIterFn fn) +{ + Tau_bfd_internal_issueBfdWarningIfNecessary(); + if (Tau_bfd_checkHandle(handle)) { + return TAU_BFD_SYMTAB_LOAD_SUCCESS; + } + return TAU_BFD_SYMTAB_LOAD_FAILED; } -int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, - int symbolLimit, - TauBfdIterFn fn) { - Tau_bfd_internal_issueBfdWarningIfNecessary(); - if (!Tau_bfd_checkHandle(handle)) { - return TAU_BFD_SYMTAB_LOAD_FAILED; - } - return TAU_BFD_SYMTAB_LOAD_UNRESOLVED; +int Tau_bfd_processBfdExecInfo(tau_bfd_handle_t handle, int maxProbe, + DeprecatedTauBfdIterFn fn) +{ + Tau_bfd_internal_issueBfdWarningIfNecessary(); + if (Tau_bfd_checkHandle(handle)) { + return TAU_BFD_SYMTAB_LOAD_SUCCESS; + } + return TAU_BFD_SYMTAB_LOAD_FAILED; } -/********************************************* - * ******* END OF ORIGINAL BFD VERSION ******* - *********************************************/ +// +// Deprecated query functions maintained for backwards compatibility. +// These should be phased out soon since they do unnecessary work and +// have lead to memory leaks. +// -#endif /* TAU_MINGW */ +int Tau_bfd_getAddressMap(tau_bfd_handle_t handle, unsigned long probe_addr, + TauBfdAddrMap * mapInfo) +{ + Tau_bfd_internal_issueBfdWarningIfNecessary(); + return 0; +} diff --git a/src/Profile/TauEnv.cpp b/src/Profile/TauEnv.cpp index 2fc1bb730..a4bb74755 100644 --- a/src/Profile/TauEnv.cpp +++ b/src/Profile/TauEnv.cpp @@ -316,7 +316,6 @@ static char * Tau_check_dirname(const char * dir) { } else { sprintf(user,"unknown"); } - free(temp); #endif /* TAU_BGP */ ret = sprintf(logfiledir, "%s/%d/%d/%d/%s_id%s_%d-%d-%d", logdir, (thisTime->tm_year+1900),(thisTime->tm_mon+1), diff --git a/src/Profile/TauSampling.cpp b/src/Profile/TauSampling.cpp index 1521d6fe2..2c9f67b92 100644 --- a/src/Profile/TauSampling.cpp +++ b/src/Profile/TauSampling.cpp @@ -500,55 +500,41 @@ void Tau_sampling_internal_initName2FuncInfoMapIfNecessary() { } } -/* *CWL* - EBS doesn't work with MINGW, so no point trying to - mess around with the modified BFD interface. Settle - for an empty call. Just make TAU build. -*/ -#ifdef TAU_MINGW -CallSiteInfo *Tau_sampling_resolveCallSite(unsigned long addr) { - return NULL; -} -#else /* TAU_MINGW */ -CallSiteInfo *Tau_sampling_resolveCallSite(unsigned long addr) { +CallSiteInfo *Tau_sampling_resolveCallSite(unsigned long addr) +{ CallSiteInfo *callsite; int bfdRet; - // bool resolved = false; char resolvedBuffer[4096]; callsite = (CallSiteInfo *)malloc(sizeof(CallSiteInfo)); callsite->pc = addr; // map current address to the corresponding module - // resolved = Tau_sampling_resolveName(addr, &name, &resolvedModuleIdx); - TauBfdInfo *resolvedInfo = NULL; - // backup information in case we fail to resolve the address to specific - // line numbers. - TauBfdAddrMap addressMap; - sprintf(addressMap.name, "%s", "UNKNOWN"); + + TauBfdInfo resolvedInfo; + char const * mapName = "UNKNOWN"; + TauBfdAddrMap const * addressMap; + bool resolved = false; + #ifdef TAU_BFD - resolvedInfo = - Tau_bfd_resolveBfdInfo(bfdUnitHandle, (unsigned long)addr); + resolved = Tau_bfd_resolveBfdInfo(bfdUnitHandle, addr, resolvedInfo); // backup info - bfdRet = Tau_bfd_getAddressMap(bfdUnitHandle, (unsigned long)addr, - &addressMap); - if (resolvedInfo == NULL) { - resolvedInfo = - Tau_bfd_resolveBfdExecInfo(bfdUnitHandle, (unsigned long)addr); - sprintf(addressMap.name, "%s", "EXEC"); + addressMap = Tau_bfd_getAddressMap(bfdUnitHandle, (unsigned long)addr); + if(addressMap) { + mapName = addressMap->name; } #endif /* TAU_BFD */ - if (resolvedInfo != NULL) { + + if (resolved) { sprintf(resolvedBuffer, "[SAMPLE] %s [{%s} {%d,%d}-{%d,%d}]", - resolvedInfo->funcname, - resolvedInfo->filename, - resolvedInfo->lineno, 0, - resolvedInfo->lineno, 0); + resolvedInfo.funcname, + resolvedInfo.filename, + resolvedInfo.lineno, 0, + resolvedInfo.lineno, 0); } else { if (TauEnv_get_ebs_keep_unresolved_addr()) { - sprintf(resolvedBuffer, "[SAMPLE] UNRESOLVED %s ADDR %p", - addressMap.name, (void *)addr); + sprintf(resolvedBuffer, "[SAMPLE] UNRESOLVED %s ADDR %p", mapName, (void*)addr); } else { - sprintf(resolvedBuffer, "[SAMPLE] UNRESOLVED %s", - addressMap.name); + sprintf(resolvedBuffer, "[SAMPLE] UNRESOLVED %s", mapName); } } callsite->name = strdup(resolvedBuffer); @@ -556,7 +542,6 @@ CallSiteInfo *Tau_sampling_resolveCallSite(unsigned long addr) { callsite->name); return callsite; } -#endif /* TAU_MINGW */ void Tau_sampling_eventStopProfile(int tid, Profiler *profiler, double *stopTime) { @@ -595,10 +580,7 @@ void Tau_sampling_finalizeProfile(int tid) { #ifdef TAU_BFD if (bfdUnitHandle == TAU_BFD_NULL_HANDLE) { - /* *CWL* We don't care if MINGW is active. EBS will not work with it. */ -#ifndef TAU_MINGW - bfdUnitHandle = Tau_bfd_registerUnit(TAU_BFD_KEEP_GLOBALS); -#endif /* TAU_MINGW */ + bfdUnitHandle = Tau_bfd_registerUnit(); } #endif /* TAU_BFD */