Commits

Anonymous committed 82e3d91

from Rolf: use addr2line in SealDebug

Comments (0)

Files changed (2)

+2009-04-15  Wim Lavrijsen  <WLavrijsen@lbl.gov>
+	* added addr2line functionality in stack trace as provided by Rolf Seuster
+	* added error handling, compiler warning and other fixes for the above patch
+	* tagging CxxUtils-00-00-31
+
 2009-04-15  David Quarrie <David.Quarrie@cern.ch>
 
 	* Tagging CxxUtils-00-00-30

src/SealDebug.cxx

 # include <cstdlib>
 # include <iostream>
 # include <iomanip>
+# include <sstream>                            // wlav
+# include <climits>                            // wlav
 
 # ifdef _WIN32
 #  include <windows.h>
     static const char	trailer [] = "]\n";
     unsigned long	ip = _Unwind_GetIP (ctx);
     unsigned long	ir = _Unwind_GetRegionStart (ctx);
+
 # if HAVE_DLADDR
     Dl_info		info;
     if (dladdr ((void *) ir, &info) && info.dli_fname && info.dli_fname[0])
     void		*trace [MAX_BACKTRACE_DEPTH];
     int			depth = backtrace (trace, MAX_BACKTRACE_DEPTH);
 
-    iovec		bufs [5];
+    iovec		bufs [6];
     int			nbufs = 0;
     char		addrbuf [5 + BitTraits<unsigned long>::HexDigits];
     char		diffbuf [7 + BitTraits<unsigned long>::HexDigits];
 	    unsigned long	symaddr = (unsigned long) info.dli_saddr;
 	    bool		gte = (addr >= symaddr);
 	    unsigned long	diff = (gte ? addr - symaddr : symaddr - addr);
+	    
+	    // RS start
+	    unsigned int length = 0;
+
+	    // difference of two pointers
+            unsigned long libaddr = (unsigned long) info.dli_fbase;
+	    unsigned long relative_address = (addr >= libaddr) ? addr - libaddr : libaddr - addr;
+
+	    // need popen for addr2line ...
+	    FILE *p;
+ 	    char line[ LINE_MAX ];
+
+	    // did we find valid entry ?
+	    if ( strlen(info.dli_fname) > 0 )
+            {
+                std::ostringstream cmd;
+		cmd << "addr2line -e " << info.dli_fname << " " << (void*)relative_address << std::ends;
+
+		length = 1;
+		line[0] = ' ';
+
+		p = popen( cmd.str().c_str(), "r" );
+		// did we succeed to open the pipe?
+		if ( p != NULL )
+                {
+		    // read string from stream and close pipe
+		    char* r = fgets( &line[1], LINE_MAX-2, p );
+		    int stat = pclose(p);
+                    if ( r && stat == 0 ) {
+                        length = strlen(line);
+
+                        // remove this ugly newline at the end, if present
+	                if ( length>1 && line[length-1]=='\n' )
+                            line[length-1] = '\0';
+                    }
+
+                    // don't print anything, if nothing is found
+                    if ( ! r || stat || line[1] == '?' )
+                    {
+                       line[1] = '\0';
+                       length = 0;
+                    }
+
+                }
+            }
+	    // RS end
 
 	    bufs [nbufs].iov_base = addrbuf;
 	    bufs [nbufs].iov_len  = sprintf (addrbuf, " 0x%08lx ", addr);
 	    bufs [nbufs].iov_len  = strlen (symname);
 	    ++nbufs;
 
+	    // RS start
+	    bufs [nbufs].iov_base = line;
+	    bufs [nbufs].iov_len  = length;;
+	    ++nbufs;
+	    // RS end
+
 	    bufs [nbufs].iov_base = diffbuf;
 	    bufs [nbufs].iov_len  = sprintf (diffbuf, " %s 0x%lx [",
 					     gte ? "+" : "-", diff);