Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 02170f7

Browse files
committed
[sanitizer] Include inlined frames into __sanitizer_symbolize_pc output
Summary: Behavior for existing used is not changing as the first line is going to be the same, and it was invalid to try to read more lines. New clients can read until they get empty string. Reviewers: eugenis, morehouse Subscribers: kubamracek, eraman, llvm-commits Differential Revision: https://reviews.llvm.org/D52743 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@343554 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 8762081 commit 02170f7

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

include/sanitizer/common_interface_defs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ extern "C" {
124124

125125
// Symbolizes the supplied 'pc' using the format string 'fmt'.
126126
// Outputs at most 'out_buf_size' bytes into 'out_buf'.
127+
// If 'out_buf' is not empty then output is zero or more non empty C strings
128+
// followed by single empty C string. Multiple strings can be returned if PC
129+
// corresponds to inlined function. Inlined frames are printed in the order
130+
// from "most-inlined" to the "least-inlined", so the last frame should be the
131+
// not inlined function.
132+
// Inlined frames can be removed with 'symbolize_inline_frames=0'.
127133
// The format syntax is described in
128134
// lib/sanitizer_common/sanitizer_stacktrace_printer.h.
129135
void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,

lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,25 @@ void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf,
114114
return;
115115
}
116116
InternalScopedString frame_desc(GetPageSizeCached());
117-
RenderFrame(&frame_desc, fmt, 0, frame->info,
118-
common_flags()->symbolize_vs_style,
119-
common_flags()->strip_path_prefix);
120-
internal_strncpy(out_buf, frame_desc.data(), out_buf_size);
121-
out_buf[out_buf_size - 1] = 0;
117+
uptr frame_num = 0;
118+
// Reserve one byte for the final 0.
119+
char *out_end = out_buf + out_buf_size - 1;
120+
for (SymbolizedStack *cur = frame; cur && out_buf < out_end;
121+
cur = cur->next) {
122+
frame_desc.clear();
123+
RenderFrame(&frame_desc, fmt, frame_num++, cur->info,
124+
common_flags()->symbolize_vs_style,
125+
common_flags()->strip_path_prefix);
126+
if (!frame_desc.length())
127+
continue;
128+
// Reserve one byte for the terminating 0.
129+
uptr n = out_end - out_buf - 1;
130+
internal_strncpy(out_buf, frame_desc.data(), n);
131+
out_buf += __sanitizer::Min<uptr>(n, frame_desc.length());
132+
*out_buf++ = 0;
133+
}
134+
CHECK(out_buf <= out_end);
135+
*out_buf = 0;
122136
}
123137

124138
SANITIZER_INTERFACE_ATTRIBUTE
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %clangxx -O3 %s -o %t
2+
// RUN: %env_tool_opts=strip_path_prefix=/TestCases/ %run %t 2>&1 | FileCheck %s
3+
// RUN: %env_tool_opts=strip_path_prefix=/TestCases/:symbolize_inline_frames=0 \
4+
// RUN: %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-NOINLINE
5+
6+
#include <sanitizer/common_interface_defs.h>
7+
#include <stdio.h>
8+
#include <string.h>
9+
10+
char buffer[10000];
11+
12+
__attribute__((noinline)) static void Symbolize() {
13+
__sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", buffer,
14+
sizeof(buffer));
15+
for (char *p = buffer; strlen(p); p += strlen(p) + 1)
16+
printf("%s\n", p);
17+
}
18+
19+
// CHECK-NOINLINE: {{0x[0-9a-f]+}} in main symbolize_pc_inline.cc:[[@LINE+2]]
20+
// CHECK: [[ADDR:0x[0-9a-f]+]] in C2 symbolize_pc_inline.cc:[[@LINE+1]]
21+
static inline void C2() { Symbolize(); }
22+
23+
// CHECK: [[ADDR]] in C3 symbolize_pc_inline.cc:[[@LINE+1]]
24+
static inline void C3() { C2(); }
25+
26+
// CHECK: [[ADDR]] in C4 symbolize_pc_inline.cc:[[@LINE+1]]
27+
static inline void C4() { C3(); }
28+
29+
// CHECK: [[ADDR]] in main symbolize_pc_inline.cc:[[@LINE+1]]
30+
int main() { C4(); }

0 commit comments

Comments
 (0)