blob: d86ed94637c697406b96457fc1bcc6b9823e1904 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include "test/core/util/test_config.h"
35
Craig Tillere1e24752015-01-13 17:26:27 -080036#include <signal.h>
Craig Tillerce2b3082016-03-16 10:43:49 -070037#include <stdbool.h>
Craig Tiller2befb682016-03-16 17:16:02 -070038#include <stdio.h>
39#include <stdlib.h>
Muxi Yancf6eaa72016-11-28 13:43:42 -080040#include <string.h>
Craig Tillerf2876ea2016-11-28 08:57:48 -080041
42#include <grpc/support/alloc.h>
43#include <grpc/support/log.h>
44
Craig Tillerf2876ea2016-11-28 08:57:48 -080045#include "src/core/lib/support/env.h"
Craig Tiller9533d042016-03-25 17:11:06 -070046#include "src/core/lib/support/string.h"
Nicolas "Pixel" Noble80d68c02015-01-13 20:14:43 -080047
Craig Tiller7b9ed352015-08-04 08:55:12 -070048double g_fixture_slowdown_factor = 1.0;
Craig Tillerf2876ea2016-11-28 08:57:48 -080049double g_poller_slowdown_factor = 1.0;
Craig Tiller7b9ed352015-08-04 08:55:12 -070050
Nicolas "Pixel" Noble80d68c02015-01-13 20:14:43 -080051#if GPR_GETPID_IN_UNISTD_H
ctillerb3e33172015-01-05 14:40:53 -080052#include <unistd.h>
Craig Tillera82950e2015-09-22 12:33:20 -070053static unsigned seed(void) { return (unsigned)getpid(); }
Nicolas "Pixel" Noble80d68c02015-01-13 20:14:43 -080054#endif
55
56#if GPR_GETPID_IN_PROCESS_H
57#include <process.h>
Nicolas "Pixel" Noblec4b18a52016-04-15 04:53:54 +020058static unsigned seed(void) { return (unsigned)_getpid(); }
Nicolas "Pixel" Noble80d68c02015-01-13 20:14:43 -080059#endif
ctillerb3e33172015-01-05 14:40:53 -080060
Nicolas "Pixel" Noble717ea0e2015-07-11 22:50:09 +020061#if GPR_WINDOWS_CRASH_HANDLER
Craig Tiller2befb682016-03-16 17:16:02 -070062#include <windows.h>
Craig Tillerb1957922016-03-16 17:22:57 -070063
64#include <tchar.h>
65
Craig Tiller2ed1a9e2016-03-16 20:09:43 -070066// disable warning 4091 - dbghelp.h is broken for msvc2015
67#pragma warning(disable : 4091)
Craig Tillerc9c0b8b2016-03-16 14:57:29 -070068#define DBGHELP_TRANSLATE_TCHAR
69#include <dbghelp.h>
Craig Tillerce2b3082016-03-16 10:43:49 -070070
Craig Tillerc9c0b8b2016-03-16 14:57:29 -070071#ifdef _MSC_VER
Craig Tillerce2b3082016-03-16 10:43:49 -070072#pragma comment(lib, "dbghelp.lib")
Craig Tillerc9c0b8b2016-03-16 14:57:29 -070073#endif
Craig Tillerce2b3082016-03-16 10:43:49 -070074
75static void print_current_stack() {
Craig Tiller2b45cb82016-03-16 10:44:57 -070076 typedef USHORT(WINAPI * CaptureStackBackTraceType)(
77 __in ULONG, __in ULONG, __out PVOID *, __out_opt PULONG);
Craig Tilleradf3a9d2016-03-16 14:59:36 -070078 CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress(
79 LoadLibrary(_T("kernel32.dll")), "RtlCaptureStackBackTrace"));
Craig Tillerce2b3082016-03-16 10:43:49 -070080
Craig Tiller2b45cb82016-03-16 10:44:57 -070081 if (func == NULL) return; // WOE 29.SEP.2010
Craig Tillerce2b3082016-03-16 10:43:49 -070082
Craig Tiller2b45cb82016-03-16 10:44:57 -070083// Quote from Microsoft Documentation:
84// ## Windows Server 2003 and Windows XP:
85// ## The sum of the FramesToSkip and FramesToCapture parameters must be less
86// than 63.
Craig Tillerce2b3082016-03-16 10:43:49 -070087#define MAX_CALLERS 62
88
Craig Tiller2b45cb82016-03-16 10:44:57 -070089 void *callers_stack[MAX_CALLERS];
Craig Tillerce2b3082016-03-16 10:43:49 -070090 unsigned short frames;
Craig Tiller2b45cb82016-03-16 10:44:57 -070091 SYMBOL_INFOW *symbol;
92 HANDLE process;
Craig Tillerce2b3082016-03-16 10:43:49 -070093 process = GetCurrentProcess();
94 SymInitialize(process, NULL, TRUE);
95 frames = (func)(0, MAX_CALLERS, callers_stack, NULL);
Craig Tilleradf3a9d2016-03-16 14:59:36 -070096 symbol =
97 (SYMBOL_INFOW *)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1);
Craig Tillerce2b3082016-03-16 10:43:49 -070098 symbol->MaxNameLen = 255;
99 symbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
100
Craig Tiller2b45cb82016-03-16 10:44:57 -0700101 const unsigned short MAX_CALLERS_SHOWN = 32;
Craig Tillerce2b3082016-03-16 10:43:49 -0700102 frames = frames < MAX_CALLERS_SHOWN ? frames : MAX_CALLERS_SHOWN;
103 for (unsigned int i = 0; i < frames; i++) {
104 SymFromAddrW(process, (DWORD64)(callers_stack[i]), 0, symbol);
Craig Tillerb1957922016-03-16 17:22:57 -0700105 fwprintf(stderr, L"*** %d: %016I64X %ls - %016I64X\n", i,
Craig Tiller2befb682016-03-16 17:16:02 -0700106 (DWORD64)callers_stack[i], symbol->Name, (DWORD64)symbol->Address);
Craig Tillerbb84c6a2016-03-17 10:42:57 -0700107 fflush(stderr);
Craig Tillerce2b3082016-03-16 10:43:49 -0700108 }
109
110 free(symbol);
111}
112
113static void print_stack_from_context(CONTEXT c) {
Craig Tiller2b45cb82016-03-16 10:44:57 -0700114 STACKFRAME s; // in/out stackframe
Craig Tillerce2b3082016-03-16 10:43:49 -0700115 memset(&s, 0, sizeof(s));
116 DWORD imageType;
117#ifdef _M_IX86
118 // normally, call ImageNtHeader() and use machine info from PE header
119 imageType = IMAGE_FILE_MACHINE_I386;
120 s.AddrPC.Offset = c.Eip;
121 s.AddrPC.Mode = AddrModeFlat;
122 s.AddrFrame.Offset = c.Ebp;
123 s.AddrFrame.Mode = AddrModeFlat;
124 s.AddrStack.Offset = c.Esp;
125 s.AddrStack.Mode = AddrModeFlat;
126#elif _M_X64
127 imageType = IMAGE_FILE_MACHINE_AMD64;
128 s.AddrPC.Offset = c.Rip;
129 s.AddrPC.Mode = AddrModeFlat;
130 s.AddrFrame.Offset = c.Rsp;
131 s.AddrFrame.Mode = AddrModeFlat;
132 s.AddrStack.Offset = c.Rsp;
133 s.AddrStack.Mode = AddrModeFlat;
134#elif _M_IA64
135 imageType = IMAGE_FILE_MACHINE_IA64;
136 s.AddrPC.Offset = c.StIIP;
137 s.AddrPC.Mode = AddrModeFlat;
138 s.AddrFrame.Offset = c.IntSp;
139 s.AddrFrame.Mode = AddrModeFlat;
140 s.AddrBStore.Offset = c.RsBSP;
141 s.AddrBStore.Mode = AddrModeFlat;
142 s.AddrStack.Offset = c.IntSp;
143 s.AddrStack.Mode = AddrModeFlat;
144#else
145#error "Platform not supported!"
146#endif
147
148 HANDLE process = GetCurrentProcess();
149 HANDLE thread = GetCurrentThread();
150
Craig Tiller2b45cb82016-03-16 10:44:57 -0700151 SYMBOL_INFOW *symbol =
Craig Tillerc9c0b8b2016-03-16 14:57:29 -0700152 (SYMBOL_INFOW *)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1);
Craig Tillerce2b3082016-03-16 10:43:49 -0700153 symbol->MaxNameLen = 255;
154 symbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
155
Craig Tiller2b45cb82016-03-16 10:44:57 -0700156 while (StackWalk(imageType, process, thread, &s, &c, 0,
157 SymFunctionTableAccess, SymGetModuleBase, 0)) {
158 BOOL has_symbol =
159 SymFromAddrW(process, (DWORD64)(s.AddrPC.Offset), 0, symbol);
Craig Tiller2befb682016-03-16 17:16:02 -0700160 fwprintf(
Craig Tillerb1957922016-03-16 17:22:57 -0700161 stderr, L"*** %016I64X %ls - %016I64X\n", (DWORD64)(s.AddrPC.Offset),
Craig Tiller2befb682016-03-16 17:16:02 -0700162 has_symbol ? symbol->Name : L"<<no symbol>>", (DWORD64)symbol->Address);
Craig Tillerbb84c6a2016-03-17 10:42:57 -0700163 fflush(stderr);
Craig Tillerce2b3082016-03-16 10:43:49 -0700164 }
165
166 free(symbol);
167}
168
169static LONG crash_handler(struct _EXCEPTION_POINTERS *ex_info) {
170 fprintf(stderr, "Exception handler called, dumping information\n");
171 bool try_to_print_stack = true;
172 PEXCEPTION_RECORD exrec = ex_info->ExceptionRecord;
173 while (exrec) {
174 DWORD code = exrec->ExceptionCode;
175 DWORD flgs = exrec->ExceptionFlags;
176 PVOID addr = exrec->ExceptionAddress;
177 if (code == EXCEPTION_STACK_OVERFLOW) try_to_print_stack = false;
178 fprintf(stderr, "code: %x - flags: %d - address: %p\n", code, flgs, addr);
179 exrec = exrec->ExceptionRecord;
180 }
181 if (try_to_print_stack) {
182 print_stack_from_context(*ex_info->ContextRecord);
Craig Tillera82950e2015-09-22 12:33:20 -0700183 }
184 if (IsDebuggerPresent()) {
185 __debugbreak();
186 } else {
187 _exit(1);
188 }
Nicolas "Pixel" Noble717ea0e2015-07-11 22:50:09 +0200189 return EXCEPTION_EXECUTE_HANDLER;
190}
191
Craig Tillerce2b3082016-03-16 10:43:49 -0700192static void abort_handler(int sig) {
Craig Tiller2befb682016-03-16 17:16:02 -0700193 fprintf(stderr, "Abort handler called.\n");
Craig Tillerce2b3082016-03-16 10:43:49 -0700194 print_current_stack(NULL);
Craig Tillera82950e2015-09-22 12:33:20 -0700195 if (IsDebuggerPresent()) {
196 __debugbreak();
197 } else {
198 _exit(1);
199 }
Nicolas "Pixel" Noblee1d95d62015-07-14 02:08:50 +0200200}
201
Craig Tillera82950e2015-09-22 12:33:20 -0700202static void install_crash_handler() {
Craig Tillerce2b3082016-03-16 10:43:49 -0700203 if (!SymInitialize(GetCurrentProcess(), NULL, TRUE)) {
Craig Tiller2befb682016-03-16 17:16:02 -0700204 fprintf(stderr, "SymInitialize failed: %d\n", GetLastError());
Craig Tillerce2b3082016-03-16 10:43:49 -0700205 }
Craig Tillera82950e2015-09-22 12:33:20 -0700206 SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)crash_handler);
207 _set_abort_behavior(0, _WRITE_ABORT_MSG);
208 _set_abort_behavior(0, _CALL_REPORTFAULT);
209 signal(SIGABRT, abort_handler);
Nicolas "Pixel" Noble717ea0e2015-07-11 22:50:09 +0200210}
Craig Tiller2bc37292015-09-28 10:08:21 -0700211#elif GPR_POSIX_CRASH_HANDLER
Craig Tiller2befb682016-03-16 17:16:02 -0700212#include <errno.h>
Craig Tiller2bc37292015-09-28 10:08:21 -0700213#include <execinfo.h>
Craig Tiller2befb682016-03-16 17:16:02 -0700214#include <grpc/support/useful.h>
Craig Tiller2bc37292015-09-28 10:08:21 -0700215#include <stdio.h>
216#include <string.h>
Craig Tiller2bc37292015-09-28 10:08:21 -0700217
Craig Tiller1b409a02016-04-29 11:26:38 -0700218static char g_alt_stack[GPR_MAX(MINSIGSTKSZ, 65536)];
Craig Tiller2bc37292015-09-28 10:08:21 -0700219
220#define MAX_FRAMES 32
221
Craig Tiller4e710f52015-09-30 07:38:49 -0700222/* signal safe output */
223static void output_string(const char *string) {
224 size_t len = strlen(string);
225 ssize_t r;
226
227 do {
228 r = write(STDERR_FILENO, string, len);
229 } while (r == -1 && errno == EINTR);
230}
231
232static void output_num(long num) {
233 char buf[GPR_LTOA_MIN_BUFSIZE];
234 gpr_ltoa(num, buf);
235 output_string(buf);
236}
237
Craig Tiller2bc37292015-09-28 10:08:21 -0700238static void crash_handler(int signum, siginfo_t *info, void *data) {
239 void *addrlist[MAX_FRAMES + 1];
240 int addrlen;
Craig Tiller2bc37292015-09-28 10:08:21 -0700241
Craig Tiller4e710f52015-09-30 07:38:49 -0700242 output_string("\n\n\n*******************************\nCaught signal ");
243 output_num(signum);
244 output_string("\n");
245
Craig Tiller2bc37292015-09-28 10:08:21 -0700246 addrlen = backtrace(addrlist, GPR_ARRAY_SIZE(addrlist));
247
Craig Tiller3a12dcf2015-09-30 07:47:08 -0700248 if (addrlen == 0) {
249 output_string(" no backtrace\n");
250 } else {
Craig Tiller2c0b91d2015-09-30 07:49:59 -0700251 backtrace_symbols_fd(addrlist, addrlen, STDERR_FILENO);
Craig Tiller2bc37292015-09-28 10:08:21 -0700252 }
Craig Tiller2bc37292015-09-28 10:08:21 -0700253
Craig Tiller4bf29282015-12-14 11:25:48 -0800254 /* try to get a core dump for SIGTERM */
255 if (signum == SIGTERM) signum = SIGQUIT;
Craig Tiller2bc37292015-09-28 10:08:21 -0700256 raise(signum);
257}
258
259static void install_crash_handler() {
260 stack_t ss;
261 struct sigaction sa;
Craig Tiller4e710f52015-09-30 07:38:49 -0700262
Craig Tiller2bc37292015-09-28 10:08:21 -0700263 memset(&ss, 0, sizeof(ss));
264 memset(&sa, 0, sizeof(sa));
265 ss.ss_size = sizeof(g_alt_stack);
266 ss.ss_sp = g_alt_stack;
267 GPR_ASSERT(sigaltstack(&ss, NULL) == 0);
268 sa.sa_flags = (int)(SA_SIGINFO | SA_ONSTACK | SA_RESETHAND);
269 sa.sa_sigaction = crash_handler;
270 GPR_ASSERT(sigaction(SIGILL, &sa, NULL) == 0);
271 GPR_ASSERT(sigaction(SIGABRT, &sa, NULL) == 0);
272 GPR_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0);
273 GPR_ASSERT(sigaction(SIGSEGV, &sa, NULL) == 0);
Craig Tiller4bf29282015-12-14 11:25:48 -0800274 GPR_ASSERT(sigaction(SIGTERM, &sa, NULL) == 0);
275 GPR_ASSERT(sigaction(SIGQUIT, &sa, NULL) == 0);
Craig Tiller2bc37292015-09-28 10:08:21 -0700276}
Nicolas "Pixel" Noble717ea0e2015-07-11 22:50:09 +0200277#else
Craig Tillera82950e2015-09-22 12:33:20 -0700278static void install_crash_handler() {}
Nicolas "Pixel" Noble717ea0e2015-07-11 22:50:09 +0200279#endif
280
Craig Tillera82950e2015-09-22 12:33:20 -0700281void grpc_test_init(int argc, char **argv) {
282 install_crash_handler();
Craig Tillerf2876ea2016-11-28 08:57:48 -0800283 { /* poll-cv poll strategy runs much more slowly than anything else */
284 char *s = gpr_getenv("GRPC_POLL_STRATEGY");
285 if (s != NULL && 0 == strcmp(s, "poll-cv")) {
286 g_poller_slowdown_factor = 5.0;
287 }
288 gpr_free(s);
289 }
Craig Tillerf2876ea2016-11-28 08:57:48 -0800290 gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f poll=%f total=%f",
Craig Tillera82950e2015-09-22 12:33:20 -0700291 (double)GRPC_TEST_SLOWDOWN_MACHINE_FACTOR,
Craig Tillerf2876ea2016-11-28 08:57:48 -0800292 (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR, g_poller_slowdown_factor,
Craig Tillera82950e2015-09-22 12:33:20 -0700293 (double)GRPC_TEST_SLOWDOWN_FACTOR);
ctillerb3e33172015-01-05 14:40:53 -0800294 /* seed rng with pid, so we don't end up with the same random numbers as a
295 concurrently running test binary */
Craig Tillera82950e2015-09-22 12:33:20 -0700296 srand(seed());
Craig Tiller190d3602015-02-18 09:23:38 -0800297}