diff --git a/mrw/stacktrace.cpp b/mrw/stacktrace.cpp
index 24f1979..493ed4a 100644
--- a/mrw/stacktrace.cpp
+++ b/mrw/stacktrace.cpp
@@ -8,61 +8,15 @@
@copy © Marc Wäckerlin
@license LGPL, see file COPYING
- $Log$
- Revision 1.14 2005/03/11 23:22:58 marc
- It's multithreaded now, thanks to a boost mutex
-
- Revision 1.13 2005/02/28 07:28:37 marc
- typo
-
- Revision 1.12 2005/02/28 07:14:03 marc
- change in getting section size for SUN Solaris (old bfd.h)
-
- Revision 1.11 2005/02/18 15:48:56 marc
- Dynamic loading of libbfd, no more dependency on specific libbfd version!
-
- Revision 1.10 2005/01/28 07:51:24 marc
- improved and corrected trace formatting
-
- Revision 1.9 2005/01/07 00:34:38 marc
- some changes for solaris
-
- Revision 1.8 2004/12/20 13:22:25 marc
- mrw string now throws exceptions, catch needed
-
- Revision 1.7 2004/10/13 10:47:15 marc
- no more need for ldd in StackTrace, read from /proc/self/maps
-
- Revision 1.6 2004/10/11 15:58:51 marc
- First version with working support for shared libraries!
-
- Revision 1.5 2004/10/07 16:59:12 marc
- new method createSymtable that takes a list of arguments
- -> untested!
-
- Revision 1.4 2004/10/07 09:32:45 marc
- correction in parameter (const&)
-
- Revision 1.3 2004/08/28 16:21:25 marc
- mrw-c++-0.92 (mrw)
- - new file: version.cpp
- - new file header for all sources
- - work around warning in mrw::auto
- - possibility to compile without log4cxx
- - work around bugs in demangle.h and libiberty.h
- - corrections in documentation
- - added simple tracing mechanism
- - more warnings
- - small corrections in Auto<>::Free and a new test for it
- - possibility to compile without stack trace
-
*/
#include
#include
#include
#include
#include
-#include
+#ifndef NO_LTDL
+# include
+#endif
#include
#include
#include
@@ -80,36 +34,28 @@
#include
#endif
#include
-extern "C" {
-
- /// @bug redefined in libiberty.h
-# define HAVE_DECL_BASENAME 1
- /// @bug redefined in libiberty.h
-# define HAVE_DECL_ASPRINTF 1
- /// @bug redefined in libiberty.h
-# define HAVE_DECL_VASPRINTF 1
-/** @bug
-
- - in file file: /usr/include/demangle.h
- - of package: binutils-2.15.90.0.1.1-31
-
- Someone unfortunately abused the C++ keyword @c typename as
- variable name to @c cplus_demangle_fill_builtin_type, so I have
- to work around it.
- */
-# define typename anotherNameThatsNotAKeyword
-# include
-# undef typename
-// // copied from demangle.h because of compiler warnings in libliberty.h
-// // (... throws different exception)
-// #define DMGL_PARAMS (1 << 0) /* Include function args */
-// #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
-// /// @bug demangle.h includes libiberty.h which throws different
-// /// exceptions for the same functions than other standard libraries,
-// /// so I can't include demangle.h!
-// extern char * cplus_demangle(const char *, int);
-}
#include
+#if HAVE_DEMANGLE_H
+/* the defines work around wrong definitions in libiberty.h */
+#define HAVE_DECL_BASENAME 1
+#define HAVE_DECL_FFS 1
+#define HAVE_DECL_ASPRINTF 1
+#define HAVE_DECL_VASPRINTF 1
+#define HAVE_DECL_SNPRINTF 1
+#define HAVE_DECL_VSNPRINTF 1
+#define HAVE_DECL_STRVERSCMP 1
+# include
+#else
+# define DMGL_PARAMS (1 << 0) /* Include function args */
+# define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
+ extern "C" {
+ extern char * cplus_demangle(const char *, int);
+ }
+#endif
+
+#if (__GNUC__==3 && __GNUC_MINOR__<4 || __GNUC__<3) && _REENTRANT && !_MT
+#define _MT
+#endif
namespace mrw {
//----------------------------------------------------------------------------
@@ -202,9 +148,10 @@ const mrw::StackTrace& mrw::StackTrace::print(std::ostream& os) const
//----------------------------------------------------------------------------
mrw::StackTrace::CodePos mrw::StackTrace::translate(void* addr)
throw(std::bad_exception) {
-#ifdef _REENTRANT
+#ifdef _MT
boost::recursive_mutex::scoped_lock lock(_mutex);
#endif
+ static const CodePos UNKNOWN(addr, "????", "????", 0);
assert(sizeof(bfd_vma)>=sizeof(void*));
bfd_vma vma_addr(reinterpret_cast(addr));
std::map::iterator
@@ -212,7 +159,7 @@ mrw::StackTrace::CodePos mrw::StackTrace::translate(void* addr)
if (it==_addrs.begin() || (--it)->first > vma_addr ||
_dic.find(it->second)==_dic.end() ||
_dic[it->second][it->first].first <= vma_addr)
- return CodePos(addr, "????", "????", 0);
+ return UNKNOWN;
static const char* file(0);
static const char* function(0);
unsigned int line;
@@ -222,7 +169,7 @@ mrw::StackTrace::CodePos mrw::StackTrace::translate(void* addr)
_syms[it->second],
vma_addr - it->first,
&file, &function, &line))
- return CodePos(addr, "????", "????", 0);
+ return UNKNOWN;
return CodePos(addr, mrw::demangle(_bfd[it->second], function),
file?file:"????", line);
}
@@ -230,11 +177,22 @@ mrw::StackTrace::CodePos mrw::StackTrace::translate(void* addr)
//----------------------------------------------------------------------------
bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs)
throw(std::bad_exception) {
-#ifdef _REENTRANT
+#ifdef _MT
boost::recursive_mutex::scoped_lock lock(_mutex);
#endif
if (_dic.find(fname)!=_dic.end()) return true; // already loaded
try {
+#if NO_LTDL
+ static bfd*(*bfd_openr)(const char*, const char*) =
+ ::bfd_openr;
+ static bfd_boolean(*bfd_check_format)(bfd*, bfd_format) =
+ ::bfd_check_format;
+ static bfd_boolean(*bfd_check_format_matches)(bfd*, bfd_format, char***) =
+ ::bfd_check_format_matches;
+ static void(*bfd_map_over_sections)
+ (bfd*, void(*)(bfd*, asection*, void*), void*) =
+ ::bfd_map_over_sections;
+#else
static DynamicLibrary lib("libbfd");
static bfd*(*bfd_openr)(const char*, const char*) =
(bfd*(*)(const char*, const char*))lib.symbol("bfd_openr");
@@ -247,6 +205,7 @@ bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs)
(bfd*, void(*)(bfd*, asection*, void*), void*) =
(void(*)(bfd*, void(*)(bfd*, asection*, void*), void*))
lib.symbol("bfd_map_over_sections");
+#endif
if (fname=="") return createSymtable(filename());
AutoBfd abfd((*bfd_openr)(fname.c_str(), 0));
long memsz(-1);
@@ -256,19 +215,27 @@ bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs)
!(bfd_get_file_flags(const_cast(static_cast(abfd)))
&HAS_SYMS) ||
(memsz=bfd_get_symtab_upper_bound
- (const_cast(static_cast(abfd))))<0)
+ (const_cast(static_cast(abfd))))<0) {
+ _error = "cannot map bfd symbols - 'bfd_get_file_flags' failed "
+ "for file: \""+fname+'"';
return false;
+ }
mrw::AutoPtr syms(new asymbol*[memsz]);
if (bfd_canonicalize_symtab(const_cast(static_cast(abfd)),
- syms)<0)
+ syms)<0) {
+ _error = "cannot map bfd symbols - 'bfd_canonicalize_symtab' failed"
+ "for file: \""+fname+'"';
return false;
+ }
_bfd[fname] = abfd;
_syms[fname] = syms;
_dic[fname];
std::pair fileoffs = std::make_pair(fname, offs);
(*bfd_map_over_sections)(_bfd[fname], buildSectionMap, &fileoffs);
return true;
- } catch (...) {
+ } catch (const std::exception& x) {
+ _error = std::string("exception received: \"")+x.what()+"\", "
+ "while processing file: \""+fname+'"';
return false; // shared library for bfd not found or similar
}
}
@@ -276,7 +243,7 @@ bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs)
//----------------------------------------------------------------------------
bool mrw::StackTrace::createSymtable(const mrw::StackTrace::BinFiles& files)
throw(std::bad_exception) {
-#ifdef _REENTRANT
+#ifdef _MT
boost::recursive_mutex::scoped_lock lock(_mutex);
#endif
bool success(true);
@@ -290,8 +257,12 @@ bool mrw::StackTrace::createSymtable(const mrw::StackTrace::BinFiles& files)
//----------------------------------------------------------------------------
int mrw::StackTrace::bfdClose(bfd* abfd) throw() {
try {
+#if NO_LTDL
+ static int(*bfd_close)(bfd*) = ::bfd_close;
+#else
static DynamicLibrary lib("");
static int(*bfd_close)(bfd*) = (int(*)(bfd*))lib.symbol("bfd_close");
+#endif
return (*bfd_close)(abfd);
} catch (...) {
return -1; // dynamic library loading problems
@@ -324,7 +295,11 @@ mrw::StackTrace::BinFiles mrw::StackTrace::filename()
range.resize(range.find_first_not_of("0123456789abcdefABCDEF"));
void* addr(0);
range>>addr;
- if (lib.size() && addr>0) res<0)
+ res<
mrw::StackTrace::_addrs;
std::map mrw::StackTrace::_bfd;
std::map > mrw::StackTrace::_syms;
-#ifdef _REENTRANT
+#ifdef _MT
boost::recursive_mutex mrw::StackTrace::_mutex;
#endif
+std::string mrw::StackTrace::_error;