debug: improving stack traces#3558
Conversation
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
|
@zuercher want me to do the same thing on the APPLE path? I'm wary of making changes there since I can't test them. |
| actions like segfaults. Where supported, stack traces will contain resolved | ||
| symbols. On systems where absl::Symbolization is not supported, the stack | ||
| traces written in the log or to stderr contain addresses rather than resolved symbols. | ||
| The `tools/stack_decode.py` script exists to process the output and do symbol resolution |
There was a problem hiding this comment.
Do we still support stack_decode.py where absl::Symbolization is supported? I think the former gives you line numbers..
There was a problem hiding this comment.
The former didn't work at all for me (despite copy-pasting all the various tags from the instructions) which is why I finally got around to doing it inline.
Are you requesting a mode where we disable it? I could add a flag.
There was a problem hiding this comment.
I'm more curious if you can use both together.. Is the absl:: approach able to extract line numbers when we compile -c dbg? That would totally obviate stack_decode.py.
There was a problem hiding this comment.
Unfortunately the traces I posted were with -c dbg so I'm going to go with "no"
I've already tracked down the guy who made these changes in absl, so I can go ask them if they're planning on enhancements. Meanwhile I've made it so stack decode works as well as it has, which is to say not at all for me, but I'm fairly confident it will no longer regress for those who get useful output from it. Before my PR I'd get something of the form
https://pastebin.com/x1KWJjFg
and with my PR and without the latest push it was like
https://pastebin.com/23KrqEmT
witht he latest push it's back to the former #1 ?? ??:0 output which is as much as I can verify :-/
There was a problem hiding this comment.
Yeah, ./tools/stack_decode.py seems to be broken, and I can't get anything out of it.
@alyssawilk Your "good" output is actually output from absl::Symbolize() that wasn't matched against any regex and left as-is. The ./tools/stack_decode.py output starts with Backtrace (most recent call first) from thread 0:.
|
@alyssawilk I'm out most of today or I'd pull it and give it a try. If you're ready to merge before I get a chance, go ahead and merge without __APPLE__ and I'll make a separate PR if it works. |
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
| ENVOY_LOG(critical, "thr<{}> #{} {} {}", thread_id, stack_trace_[i].idx, | ||
| stack_trace_[i].addr, out); | ||
| } else { | ||
| ENVOY_LOG(critical, "thr<{}> #{} (unknown)", thread_id, stack_trace_[i].idx, |
There was a problem hiding this comment.
This should be "thr<{}> #{} {} (unknown)" (missing one {}).
| stack_trace_[i].addr, trace.object_function); | ||
| #else | ||
| ENVOY_LOG(critical, "thr<{}> #{} {}", thread_id, stack_trace_[i].idx, stack_trace_[i].addr); | ||
|
|
| #else | ||
| ENVOY_LOG(critical, "thr<{}> #{} {}", thread_id, stack_trace_[i].idx, stack_trace_[i].addr); | ||
|
|
||
| if (absl::Symbolize(stack_trace_[i].addr, out, 200)) { |
There was a problem hiding this comment.
Nit: use sizeof(out) instead of 200.
| ENVOY_LOG(critical, "Backtrace obj<{}> thr<{}> (use tools/stack_decode.py):", obj_name, | ||
| char out[200]; | ||
| ENVOY_LOG(critical, | ||
| "Backtrace obj<{}> thr<{}> (If unsymbolized, use tools/stack_decode.py):", obj_name, |
There was a problem hiding this comment.
While you're here, should we perhaps flip the order from "Backtrace obj<{}> thr<{}> ..." to "Backtrace thr<{}> obj<{}> ..." to match rest of the output?
|
@alyssawilk @zuercher I'm going to test if this works on macOS (but it's going to take a while, since I'm on dual-core machine). |
|
Looks like macos is already has better stack trace support than I'm adding so I think we're set here. |
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
|
It doesn't work on macOS, it only emits lines with |
| // The stack_decode.py script uses addr2line which isn't readily available and doesn't seem to | ||
| // work when installed. | ||
| ENVOY_LOG(critical, "Backtrace obj<{}> thr<{}>:", obj_name, thread_id); | ||
| ENVOY_LOG(critical, "Backtrace thr<{}> obj<{}>:", thread_id, obj_name); |
There was a problem hiding this comment.
You need to update tools/stack_decode.py for that, sorry!
diff --git a/tools/stack_decode.py b/tools/stack_decode.py
index f141d1c1..2edbc63e 100755
--- a/tools/stack_decode.py
+++ b/tools/stack_decode.py
@@ -29,7 +29,7 @@ def decode_stacktrace_log(input_source):
# bazel-out/local-dbg/bin/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:84]
backtrace_marker = "\[backtrace\] [^\s]+"
trace_begin_re = re.compile(
- "^(.+)%s Backtrace obj<(.+)> thr<(\d+)" % backtrace_marker)
+ "^(.+)%s Backtrace thr<(\d+)> obj<(.+)>" % backtrace_marker)
stackaddr_re = re.compile("%s thr<(\d+)> #\d+ (0x[0-9a-fA-F]+) " % backtrace_marker)
new_object_re = re.compile("%s thr<(\d+)> obj<(.+)>$" % backtrace_marker)
trace_end_re = re.compile("%s end backtrace thread (\d+)" % backtrace_marker)
@@ -42,7 +42,7 @@ def decode_stacktrace_log(input_source):
return # EOF
begin_trace_match = trace_begin_re.search(line)
if begin_trace_match:
- log_prefix, objfile, thread_id = begin_trace_match.groups()
+ log_prefix, thread_id, objfile = begin_trace_match.groups()
traces[thread_id] = Backtrace(log_prefix=log_prefix, obj_list=[])
traces[thread_id].obj_list.append(
AddressList(obj_file=objfile, addresses=[]))
| @@ -104,7 +109,13 @@ class BackwardsTrace : Logger::Loggable<Logger::Id::backtrace> { | |||
| ENVOY_LOG(critical, "thr<{}> #{} {}: {}", thread_id, stack_trace_[i].idx, | |||
There was a problem hiding this comment.
Nit: we're emitting "thr<{}> #{} {}: {}" on macOS and ""thr<{}> #{} {} {}" (without :) on Linux.
Consider removing : from macOS output or adding it to both Linux outputs.
| trace_begin_re = re.compile( | ||
| "^(.+)%s Backtrace obj<(.+)> thr<(\d+)" % backtrace_marker) | ||
| stackaddr_re = re.compile("%s thr<(\d+)> #\d+ (0x[0-9a-fA-F]+)$" % backtrace_marker) | ||
| stackaddr_re = re.compile("%s thr<(\d+)> #\d+ (0x[0-9a-fA-F]+) " % backtrace_marker) |
There was a problem hiding this comment.
Nit: the space at the end is unnecessary here.
There was a problem hiding this comment.
I never trust regex to be greedy so I'm more comfortable leaving it in
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
| trace_begin_re = re.compile( | ||
| "^(.+)%s Backtrace obj<(.+)> thr<(\d+)" % backtrace_marker) | ||
| stackaddr_re = re.compile("%s thr<(\d+)> #\d+ (0x[0-9a-fA-F]+)$" % backtrace_marker) | ||
| "^(.+)%s Backtrace thr<(\d+).*obj<(.+)>" % backtrace_marker) |
There was a problem hiding this comment.
Any particular reason for using "thr<(\d+).*obj<(.+)>" instead of "thr<(\d+)> obj<(.+)>"? We know exactly the format that's emitted.
PiotrSikora
left a comment
There was a problem hiding this comment.
One small nit, but LGTM otherwise.
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
This fixes an ASAN failure when run in a certain environment, as described by abseil/abseil-cpp#118. The failure was added by envoyproxy#3558, which pulled in the same static initializer as described in the original absl issue linked here. Signed-off-by: Greg Greenway <ggreenway@apple.com>
This fixes an ASAN failure when run in a certain environment, as described by abseil/abseil-cpp#118. The failure was added by #3558, which pulled in the same static initializer as described in the original absl issue linked here. Signed-off-by: Greg Greenway <ggreenway@apple.com>
Dumping function names in stack traces where absl::Sybolize is supported.
before: https://pastebin.com/raw/kZihnpSK
after: https://pastebin.com/raw/XcDwcx15
Risk Level: Low (worst case someone gets a borked stack trace and we roll back)
Testing: manual: see pastebin links.
Docs Changes: updated current docs on stack traces
Release Notes: inline.