Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * 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 :
36 : #include <grpc/support/port_platform.h>
37 : #include <grpc/support/log.h>
38 : #include "src/core/support/string.h"
39 : #include <stdlib.h>
40 : #include <signal.h>
41 :
42 : double g_fixture_slowdown_factor = 1.0;
43 :
44 : #if GPR_GETPID_IN_UNISTD_H
45 : #include <unistd.h>
46 793 : static unsigned seed(void) { return (unsigned)getpid(); }
47 : #endif
48 :
49 : #if GPR_GETPID_IN_PROCESS_H
50 : #include <process.h>
51 : static unsigned seed(void) { return _getpid(); }
52 : #endif
53 :
54 : #if GPR_WINDOWS_CRASH_HANDLER
55 : LONG crash_handler(struct _EXCEPTION_POINTERS *ex_info) {
56 : gpr_log(GPR_DEBUG, "Exception handler called, dumping information");
57 : while (ex_info->ExceptionRecord) {
58 : DWORD code = ex_info->ExceptionRecord->ExceptionCode;
59 : DWORD flgs = ex_info->ExceptionRecord->ExceptionFlags;
60 : PVOID addr = ex_info->ExceptionRecord->ExceptionAddress;
61 : gpr_log("code: %x - flags: %d - address: %p", code, flgs, addr);
62 : ex_info->ExceptionRecord = ex_info->ExceptionRecord->ExceptionRecord;
63 : }
64 : if (IsDebuggerPresent()) {
65 : __debugbreak();
66 : } else {
67 : _exit(1);
68 : }
69 : return EXCEPTION_EXECUTE_HANDLER;
70 : }
71 :
72 : void abort_handler(int sig) {
73 : gpr_log(GPR_DEBUG, "Abort handler called.");
74 : if (IsDebuggerPresent()) {
75 : __debugbreak();
76 : } else {
77 : _exit(1);
78 : }
79 : }
80 :
81 : static void install_crash_handler() {
82 : SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)crash_handler);
83 : _set_abort_behavior(0, _WRITE_ABORT_MSG);
84 : _set_abort_behavior(0, _CALL_REPORTFAULT);
85 : signal(SIGABRT, abort_handler);
86 : }
87 : #elif GPR_POSIX_CRASH_HANDLER
88 : #include <execinfo.h>
89 : #include <stdio.h>
90 : #include <string.h>
91 : #include <grpc/support/useful.h>
92 : #include <errno.h>
93 :
94 : static char g_alt_stack[MINSIGSTKSZ];
95 :
96 : #define MAX_FRAMES 32
97 :
98 : /* signal safe output */
99 0 : static void output_string(const char *string) {
100 0 : size_t len = strlen(string);
101 : ssize_t r;
102 :
103 : do {
104 0 : r = write(STDERR_FILENO, string, len);
105 0 : } while (r == -1 && errno == EINTR);
106 0 : }
107 :
108 0 : static void output_num(long num) {
109 : char buf[GPR_LTOA_MIN_BUFSIZE];
110 0 : gpr_ltoa(num, buf);
111 0 : output_string(buf);
112 0 : }
113 :
114 0 : static void crash_handler(int signum, siginfo_t *info, void *data) {
115 : void *addrlist[MAX_FRAMES + 1];
116 : int addrlen;
117 :
118 0 : output_string("\n\n\n*******************************\nCaught signal ");
119 0 : output_num(signum);
120 0 : output_string("\n");
121 :
122 0 : addrlen = backtrace(addrlist, GPR_ARRAY_SIZE(addrlist));
123 :
124 0 : if (addrlen == 0) {
125 0 : output_string(" no backtrace\n");
126 : } else {
127 0 : backtrace_symbols_fd(addrlist, addrlen, STDERR_FILENO);
128 : }
129 :
130 0 : raise(signum);
131 0 : }
132 :
133 793 : static void install_crash_handler() {
134 : stack_t ss;
135 : struct sigaction sa;
136 :
137 793 : memset(&ss, 0, sizeof(ss));
138 793 : memset(&sa, 0, sizeof(sa));
139 793 : ss.ss_size = sizeof(g_alt_stack);
140 793 : ss.ss_sp = g_alt_stack;
141 793 : GPR_ASSERT(sigaltstack(&ss, NULL) == 0);
142 793 : sa.sa_flags = (int)(SA_SIGINFO | SA_ONSTACK | SA_RESETHAND);
143 793 : sa.sa_sigaction = crash_handler;
144 793 : GPR_ASSERT(sigaction(SIGILL, &sa, NULL) == 0);
145 793 : GPR_ASSERT(sigaction(SIGABRT, &sa, NULL) == 0);
146 793 : GPR_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0);
147 793 : GPR_ASSERT(sigaction(SIGSEGV, &sa, NULL) == 0);
148 793 : }
149 : #else
150 : static void install_crash_handler() {}
151 : #endif
152 :
153 793 : void grpc_test_init(int argc, char **argv) {
154 793 : install_crash_handler();
155 793 : gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f total=%f",
156 : (double)GRPC_TEST_SLOWDOWN_MACHINE_FACTOR,
157 : (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR,
158 : (double)GRPC_TEST_SLOWDOWN_FACTOR);
159 : /* seed rng with pid, so we don't end up with the same random numbers as a
160 : concurrently running test binary */
161 793 : srand(seed());
162 793 : }
|