Rev 1 | Rev 14 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1 | Rev 11 | ||
|---|---|---|---|
| Line 27... | Line 27... | ||
| 27 | #endif |
27 | #endif |
| 28 | 28 | ||
| 29 | void dr_dprintf(char* fmt_string, ...); |
29 | void dr_dprintf(char* fmt_string, ...); |
| 30 | 30 | ||
| 31 | static int stack_nbr = 0; |
31 | static int stack_nbr = 0; |
| 32 | static char |
32 | static char windows_program_name[1024]; |
| 33 | 33 | ||
| 34 | static char dirname_buf[_MAX_DIR]; |
34 | static char dirname_buf[_MAX_DIR]; |
| 35 | static char fname_buf[_MAX_FNAME]; |
35 | static char fname_buf[_MAX_FNAME]; |
| 36 | 36 | ||
| 37 | int addr2line(char const* const program_name, void const* const addr) { |
37 | static int addr2line(char const* const program_name, void const* const addr) { |
| 38 | char addr2line_cmd[512] = { 0 }; |
38 | char addr2line_cmd[512] = { 0 }; |
| 39 | 39 | ||
| 40 | sprintf(addr2line_cmd, "addr2line -f -p -e %.256s %p", program_name, addr); |
40 | sprintf(addr2line_cmd, "addr2line -f -p -e %.256s %p", program_name, addr); |
| 41 | 41 | ||
| 42 | fprintf(stderr, "%d: ", stack_nbr++); |
42 | fprintf(stderr, "%d: ", stack_nbr++); |
| 43 | return system(addr2line_cmd); |
43 | return system(addr2line_cmd); |
| 44 | } |
44 | } |
| 45 | 45 | ||
| 46 | void print_stacktrace(CONTEXT* context) { |
46 | static void print_stacktrace(CONTEXT* context) { |
| 47 | #ifndef _WIN32 // Pierre-Marie Baty -- looks like this doesn't build right away on Windows |
47 | #ifndef _WIN32 // Pierre-Marie Baty -- looks like this doesn't build right away on Windows |
| 48 | SymInitialize(GetCurrentProcess(), 0, true); |
48 | SymInitialize(GetCurrentProcess(), 0, true); |
| 49 | 49 | ||
| 50 | STACKFRAME frame = { 0 }; |
50 | STACKFRAME frame = { 0 }; |
| 51 | 51 | ||
| Line 64... | Line 64... | ||
| 64 | context, |
64 | context, |
| 65 | 0, |
65 | 0, |
| 66 | SymFunctionTableAccess, |
66 | SymFunctionTableAccess, |
| 67 | SymGetModuleBase, |
67 | SymGetModuleBase, |
| 68 | 0)) { |
68 | 0)) { |
| 69 | addr2line( |
69 | addr2line(windows_program_name, (void*)frame.AddrPC.Offset); |
| 70 | } |
70 | } |
| 71 | 71 | ||
| 72 | SymCleanup(GetCurrentProcess()); |
72 | SymCleanup(GetCurrentProcess()); |
| 73 | #endif // !_WIN32 |
73 | #endif // !_WIN32 |
| 74 | } |
74 | } |
| 75 | 75 | ||
| 76 | LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) { |
76 | static LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS* ExceptionInfo) { |
| 77 | switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { |
77 | switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { |
| 78 | case EXCEPTION_ACCESS_VIOLATION: |
78 | case EXCEPTION_ACCESS_VIOLATION: |
| 79 | fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr); |
79 | fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr); |
| 80 | break; |
80 | break; |
| 81 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: |
81 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: |
| Line 143... | Line 143... | ||
| 143 | /* If this is a stack overflow then we can't walk the stack, so just show |
143 | /* If this is a stack overflow then we can't walk the stack, so just show |
| 144 | where the error happened */ |
144 | where the error happened */ |
| 145 | if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { |
145 | if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { |
| 146 | print_stacktrace(ExceptionInfo->ContextRecord); |
146 | print_stacktrace(ExceptionInfo->ContextRecord); |
| 147 | } else { |
147 | } else { |
| 148 | addr2line( |
148 | addr2line(windows_program_name, (void*)ExceptionInfo->ContextRecord->Eip); |
| 149 | } |
149 | } |
| 150 | 150 | ||
| 151 | return EXCEPTION_EXECUTE_HANDLER; |
151 | return EXCEPTION_EXECUTE_HANDLER; |
| 152 | } |
152 | } |
| 153 | 153 | ||
| 154 | void OS_InstallSignalHandler(char* program_name) { |
154 | void OS_InstallSignalHandler(char* program_name) { |
| 155 | strcpy( |
155 | strcpy(windows_program_name, program_name); |
| 156 | SetUnhandledExceptionFilter(windows_exception_handler); |
156 | SetUnhandledExceptionFilter(windows_exception_handler); |
| 157 | } |
157 | } |
| 158 | 158 | ||
| 159 | FILE* OS_fopen(const char* pathname, const char* mode) { |
159 | FILE* OS_fopen(const char* pathname, const char* mode) { |
| 160 | FILE* f; |
160 | FILE* f; |
| 161 | errno_t err; |
161 | errno_t err; |
| 162 | 162 | ||
| 163 | f = NULL; |
163 | f = NULL; |
| 164 | err = fopen_s(&f, pathname, mode); |
164 | err = fopen_s(&f, pathname, mode); |
| 165 | if (err != 0) { |
165 | if (err != 0) { |
| 166 | fprintf(stderr, "Failed to open \"%s\"", pathname); |
166 | fprintf(stderr, "Failed to open \"%s\" (%s)\n", pathname, strerror(err)); |
| 167 | } |
167 | } |
| 168 | 168 | ||
| 169 | return f; |
169 | return f; |
| 170 | } |
170 | } |
| 171 | 171 | ||