diff --git a/bin/addr2line4Mac.py b/bin/addr2line4Mac.py index 7a97c1505..54a40f1a8 100755 --- a/bin/addr2line4Mac.py +++ b/bin/addr2line4Mac.py @@ -4,27 +4,46 @@ import sys filename=sys.argv[1] address=sys.argv[2] import re +from os import environ,path -import subprocess +fullFile=None +if path.exists(filename): + fullFile=filename -p = subprocess.Popen("gdb -batch -x /dev/stdin", - shell=True, - bufsize=0, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - close_fds=True) +for v in ["PATH","LD_LIBRARY_PATH"]: + if not fullFile: + for d in environ[v].split(':'): + if path.exists(path.join(d,filename)): + fullFile=path.join(d,filename) + break -(child_stdin, child_stdout) = (p.stdin, p.stdout) -child_stdin.write("set sharedlibrary preload-libraries no\n") -child_stdin.write("file "+filename+"\n") -child_stdin.write("info line *"+address+"\n") -result=child_stdout.readline() +if not fullFile: + fullFile=filename answer="??:0" -match=re.compile('Line (.+) of "(.+)" starts at').match(result) -if match: - answer=match.group(2)+":"+match.group(1) +if path.exists(fullFile): + import subprocess + + result=subprocess.Popen(["xcrun", "atos", + "-o",fullFile, + address], + stdout=subprocess.PIPE + ).communicate()[0] + match=re.compile('.+ \((.+)\) \((.+)\)').match(result) + if match: + answer=match.group(2)+" "+match.group(1) + else: + import os + result=subprocess.Popen(["xcrun", "atos", + "-p",str(os.getppid()), + address], + stdout=subprocess.PIPE + ).communicate()[0] + match=re.compile('.+ \((.+)\) \((.+)\)').match(result) + if match: + answer=match.group(2)+" "+match.group(1) + print answer, sys.exit(255) diff --git a/src/OSspecific/POSIX/printStack.C b/src/OSspecific/POSIX/printStack.C index c88ae6863..7b28ef9f2 100644 --- a/src/OSspecific/POSIX/printStack.C +++ b/src/OSspecific/POSIX/printStack.C @@ -31,10 +31,13 @@ License #include "readHexLabel.H" #include -#ifndef darwin #include -#endif #include +#include + +#ifdef darwin +#include +#endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -126,14 +129,17 @@ void printSourceFileAndLine myAddress = nStream.str(); } +#ifndef darwin if (filename[0] == '/') +#else + if (1) +#endif { string line = pOpen ( #ifndef darwin "addr2line -f --demangle=auto --exe " #else - // "gaddr2line -f --inline --demangle=auto --exe " "addr2line4Mac.py " #endif + filename @@ -144,119 +150,22 @@ void printSourceFileAndLine if (line == "") { - os << " addr2line failed"; + os << " addr2line failed"; } else if (line == "??:0") { - os << " in " << filename; + os << " in " << filename; } else { string cwdLine(line.replaceAll(cwd() + '/', "")); - string homeLine(cwdLine.replaceAll(home(), '~')); - os << " at " << homeLine.c_str(); + os << " at " << homeLine.c_str(); } } } -#ifdef darwin - -// Trying to emulate the original backtrace and backtrace_symbol from the glibc -// After an idea published by Rush Manbert at http://lists.apple.com/archives/xcode-users/2006/Apr/msg00528.html - -template -void *getStackAddress() -{ - const unsigned int stackLevel=level; - return ( - __builtin_frame_address(level) - ? __builtin_return_address(stackLevel) - : (void *)0 - ); -}; - -#define GET_STACK_ADDRESS(lvl) \ - case lvl: {return getStackAddress(); break; } - -// please don't laugh. For some reason this is necessary (the compiler won't accept it otherwise) -void *getStackAddress(int level) -{ - switch(level) { - GET_STACK_ADDRESS(0); - GET_STACK_ADDRESS(1); - GET_STACK_ADDRESS(2); - GET_STACK_ADDRESS(3); - GET_STACK_ADDRESS(4); - GET_STACK_ADDRESS(5); - GET_STACK_ADDRESS(6); - GET_STACK_ADDRESS(7); - GET_STACK_ADDRESS(8); - GET_STACK_ADDRESS(9); - GET_STACK_ADDRESS(10); - GET_STACK_ADDRESS(11); - GET_STACK_ADDRESS(12); - GET_STACK_ADDRESS(13); - GET_STACK_ADDRESS(14); - GET_STACK_ADDRESS(15); - GET_STACK_ADDRESS(16); - GET_STACK_ADDRESS(17); - GET_STACK_ADDRESS(18); - GET_STACK_ADDRESS(19); - GET_STACK_ADDRESS(20); - GET_STACK_ADDRESS(21); - default: - return (void *)0; - break; - } -} - -unsigned backtrace(void **bt, unsigned maxAddrs) -{ - unsigned valid=0; - bool ok=true; - - for(int level=0;level