1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019 Intel Corporation 3 */ 4 5 #include <stdarg.h> 6 #include <rte_log.h> 7 #include <rte_debug.h> 8 #include <rte_windows.h> 9 10 #include <dbghelp.h> 11 12 #define BACKTRACE_SIZE 256 13 14 /* dump the stack of the calling core */ 15 void 16 rte_dump_stack(void) 17 { 18 PVOID stack_trace[BACKTRACE_SIZE] = {0}; 19 USHORT frame_num; 20 BOOL ret; 21 HANDLE process = GetCurrentProcess(); 22 23 ret = SymInitialize(process, NULL, TRUE); 24 if (!ret) { 25 RTE_LOG_WIN32_ERR("SymInitialize()"); 26 return; 27 } 28 29 SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME); 30 31 frame_num = RtlCaptureStackBackTrace(0, BACKTRACE_SIZE, 32 stack_trace, NULL); 33 34 while (frame_num > 0) { 35 DWORD64 address = (DWORD64)(stack_trace[frame_num - 1]); 36 DWORD64 sym_disp = 0; 37 DWORD error_code = 0, lin_disp; 38 char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; 39 PSYMBOL_INFO symbol_info = (PSYMBOL_INFO)buffer; 40 IMAGEHLP_LINE64 line; 41 42 symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO); 43 symbol_info->MaxNameLen = MAX_SYM_NAME; 44 line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); 45 46 ret = SymFromAddr(process, address, &sym_disp, symbol_info); 47 if (!ret) { 48 error_code = GetLastError(); 49 if (error_code == ERROR_INVALID_ADDRESS) { 50 /* Missing symbols, print message */ 51 rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL, 52 "%d: [<missing_symbols>]\n", frame_num--); 53 continue; 54 } else { 55 RTE_LOG_WIN32_ERR("SymFromAddr()"); 56 goto end; 57 } 58 } 59 60 ret = SymGetLineFromAddr64(process, address, &lin_disp, &line); 61 if (!ret) { 62 error_code = GetLastError(); 63 /* If ERROR_INVALID_ADDRESS tag unknown and proceed */ 64 if (error_code != ERROR_INVALID_ADDRESS) { 65 RTE_LOG_WIN32_ERR("SymGetLineFromAddr64()"); 66 goto end; 67 } 68 } 69 70 rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL, 71 "%d: [%s (%s+0x%0llx)[0x%0llX]]\n", frame_num, 72 error_code ? "<unknown>" : line.FileName, 73 symbol_info->Name, sym_disp, symbol_info->Address); 74 frame_num--; 75 } 76 end: 77 ret = SymCleanup(process); 78 if (!ret) 79 RTE_LOG_WIN32_ERR("SymCleanup()"); 80 } 81