Open MrMage opened 5 years ago
@MrMage this shouldn't actually be hard. I believe if we make a script similar (will be much easier) to this one, then we could use lldb
(on your Mac for example) for the symbolication instead of addr2line
and that should give you the line numbers.
The linked script does quite a lot more than we need because the current output already gives us everything we need which is:
from just the library file name + the offset it is possible to get exact file/line information. For some reason though addr2line doesn't seem to be able to get that out of the DWARF that Swift produces. But lldb definitely can do that.
AFAIK, libunwind
parses ELF symbols, but does not expose API that returns line number in source file.
So, if we want to get line number in source file, we need to use another functions other than provided by libunwind
.
Call addr2line
executable
SymbolFormatter
might be able to call addr2line
. Symbol.module
as executable and Symbol.address
as address can be passed to addr2line
.
For following entry:
/Users/norio/github/SwiftBacktrace/.build/x86_64-unknown-linux/debug/SwiftBacktracePackageTests.xctest(SwiftBacktrace.backtrace(Swift.Int, formatter: SwiftBacktrace.BacktraceFormatter) -> Swift.Array
+0xd8) [0x0000000000423718]
It can be:
$ addr2line -e .build/x86_64-unknown-linux/debug/SwiftBacktracePackageTests.xctest 0x0000000000423718
/Users/norio/github/SwiftBacktrace/Sources/SwiftBacktrace/SwiftBacktrace.swift:3
libbfd
instead of calling addr2line
addr2line
seems to use libbfd
. (source code?)If I do, I might use the latter. 🤔
Thank you for these insights! I have filed an issue with Stackdriver Error reporting now asking for the correct stack trace format for parsing. Until they reply, I could probably get by with manually symbolicating the stack traces as you guys described. In any case, this is not a super-high priority; hard crashes should be fairly rare, after all.
FYI, in case anyone is interested, this is the formatter I am using right now to get my stack straces sort-of parsed by Google Stackdriver:
let stackdriverStyleFormat = SymbolFormatter { symbol -> String in
let (module, name, _, _) = symbol
let sanitizedName = name
// All these need to be replaced to make Stackdriver happy. Characters we can keep: $.<>
.replacingOccurrences(of: "(", with: "[")
.replacingOccurrences(of: ")", with: "]")
.replacingOccurrences(of: " ", with: "_")
.replacingOccurrences(of: "?", with: "0")
.replacingOccurrences(of: "->", with: "_returns_")
.replacingOccurrences(of: "-", with: "_")
.replacingOccurrences(of: "@", with: "")
.replacingOccurrences(of: ":", with: "_")
.replacingOccurrences(of: "#", with: "")
return " at \(sanitizedName) (\(module):1:1)"
}
addSignalHandler {
JSONLogger.sharedInstance.fatal("UnknownCrash\n"
+ backtrace(500, formatter: .init(stackdriverStyleFormat.compose(.default)))
.joined(separator: "\n"))
}
This library is super helpful for getting symbolicating stack traces on Linux, thank you so much!
I'd like to create a custom
SymbolFormatter
that outputs stack traces in Ruby format, as these could presumably be parsed by Google Stackdriver Error Reporting. However, for that I would need each symbol's corresponding source file name and line number as well.Is there any possibility of retrieving these with
SwiftBacktrace
? I do not mind compiling my binary with debug symbols (-Xswiftc -g
).