36 #include <glog/logging.h>
39 #ifdef HAVE_EXECINFO_H
40 # include <execinfo.h>
45 #ifdef HAVE_STACKTRACE
52 const int BACKTRACE_STEPS = 6;
59 AddressRange expected_range[BACKTRACE_STEPS];
65 #define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \
67 (prange)->start = &&start_label; \
68 (prange)->end = &&end_label; \
69 CHECK_LT((prange)->start, (prange)->end); \
76 #define DECLARE_ADDRESS_LABEL(a_label) \
77 a_label: do { __asm__ __volatile__(""); } while (0)
82 #define ADJUST_ADDRESS_RANGE_FROM_RA(prange) \
84 void *ra = __builtin_return_address(0); \
85 CHECK_LT((prange)->start, ra); \
86 if (ra > (prange)->end) { \
87 printf("Adjusting range from %p..%p to %p..%p\n", \
88 (prange)->start, (prange)->end, \
89 (prange)->start, ra); \
95 #define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange) \
97 (prange)->start = reinterpret_cast<const void *>(&fn); \
98 (prange)->end = reinterpret_cast<const char *>(&fn) + 256; \
100 #define DECLARE_ADDRESS_LABEL(a_label) do { } while (0)
101 #define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0)
106 static void CheckRetAddrIsInFunction(
void *ret_addr,
const AddressRange &
range)
114 #if defined(__clang__)
115 #pragma clang diagnostic push
116 #pragma clang diagnostic ignored "-Wgnu-label-as-value"
121 const int STACK_LEN = 10;
122 void *stack[STACK_LEN];
125 ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
126 INIT_ADDRESS_RANGE(CheckStackTraceLeaf,
start,
end, &expected_range[0]);
127 DECLARE_ADDRESS_LABEL(
start);
129 printf(
"Obtained %d stack frames.\n",
size);
134 #ifdef HAVE_EXECINFO_H
136 printf(
"Obtained %d stack frames.\n",
size);
137 for (
int i = 0;
i <
size;
i++) {
144 }
p = {&CheckStackTrace};
146 printf(
"CheckStackTrace() addr: %p\n",
p.p2);
150 for (
int i = 0;
i < BACKTRACE_STEPS;
i++) {
151 printf(
"Backtrace %d: expected: %p..%p actual: %p ... ",
152 i, expected_range[
i].
start, expected_range[
i].
end, stack[
i]);
154 CheckRetAddrIsInFunction(stack[
i], expected_range[
i]);
157 DECLARE_ADDRESS_LABEL(
end);
164 ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[2]);
165 INIT_ADDRESS_RANGE(CheckStackTrace4,
start,
end, &expected_range[1]);
166 DECLARE_ADDRESS_LABEL(
start);
167 for (
int j =
i; j >= 0; j--) {
168 CheckStackTraceLeaf();
170 DECLARE_ADDRESS_LABEL(
end);
173 ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[3]);
174 INIT_ADDRESS_RANGE(CheckStackTrace3,
start,
end, &expected_range[2]);
175 DECLARE_ADDRESS_LABEL(
start);
176 for (
int j =
i; j >= 0; j--) {
179 DECLARE_ADDRESS_LABEL(
end);
182 ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[4]);
183 INIT_ADDRESS_RANGE(CheckStackTrace2,
start,
end, &expected_range[3]);
184 DECLARE_ADDRESS_LABEL(
start);
185 for (
int j =
i; j >= 0; j--) {
188 DECLARE_ADDRESS_LABEL(
end);
191 ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[5]);
192 INIT_ADDRESS_RANGE(CheckStackTrace1,
start,
end, &expected_range[4]);
193 DECLARE_ADDRESS_LABEL(
start);
194 for (
int j =
i; j >= 0; j--) {
197 DECLARE_ADDRESS_LABEL(
end);
210 INIT_ADDRESS_RANGE(CheckStackTrace,
start,
end, &expected_range[5]);
211 DECLARE_ADDRESS_LABEL(
start);
212 for (
int j =
i; j >= 0; j--) {
215 DECLARE_ADDRESS_LABEL(
end);
218 #if defined(__clang__)
219 #pragma clang diagnostic pop
224 int main(
int,
char ** argv) {
236 printf(
"PASS (no stacktrace support)\n");
239 #endif // HAVE_STACKTRACE