eal/windows: support exit and panic

Support the debug functions in eal_common_debug.c for Windows.

Implementation of rte_dump_stack to get a backtrace similarly to Unix
and of rte_eal_cleanup in eal.c.

Signed-off-by: Tal Shnaiderman <talshn@mellanox.com>
Tested-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
This commit is contained in:
Tal Shnaiderman 2020-06-23 23:57:21 +03:00 committed by Thomas Monjalon
parent 48be180de6
commit c91717eb75
4 changed files with 78 additions and 9 deletions

View File

@ -276,6 +276,7 @@ if is_windows
endif
add_project_link_arguments('-ladvapi32', '-lsetupapi', language: 'c')
add_project_link_arguments('-ldbghelp', language: 'c')
endif
if get_option('b_lto')

View File

@ -7,6 +7,7 @@ if is_windows
sources += files(
'eal_common_bus.c',
'eal_common_class.c',
'eal_common_debug.c',
'eal_common_devargs.c',
'eal_common_dynmem.c',
'eal_common_errno.c',

View File

@ -274,7 +274,14 @@ __rte_trace_point_register(rte_trace_point_t *trace, const char *name,
return -ENOTSUP;
}
/* Launch threads, called at application init(). */
int
rte_eal_cleanup(void)
{
eal_cleanup_config(&internal_config);
return 0;
}
/* Launch threads, called at application init(). */
int
rte_eal_init(int argc, char **argv)
{

View File

@ -5,16 +5,76 @@
#include <stdarg.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_windows.h>
/* call abort(), it will generate a coredump if enabled */
#include <dbghelp.h>
#define BACKTRACE_SIZE 256
/* dump the stack of the calling core */
void
__rte_panic(const char *funcname, const char *format, ...)
rte_dump_stack(void)
{
va_list ap;
PVOID stack_trace[BACKTRACE_SIZE] = {0};
USHORT frame_num;
BOOL ret;
HANDLE process = GetCurrentProcess();
rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
va_start(ap, format);
rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
va_end(ap);
abort();
ret = SymInitialize(process, NULL, TRUE);
if (!ret) {
RTE_LOG_WIN32_ERR("SymInitialize()");
return;
}
SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
frame_num = RtlCaptureStackBackTrace(0, BACKTRACE_SIZE,
stack_trace, NULL);
while (frame_num > 0) {
DWORD64 address = (DWORD64)(stack_trace[frame_num - 1]);
DWORD64 sym_disp = 0;
DWORD error_code = 0, lin_disp;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO symbol_info = (PSYMBOL_INFO)buffer;
IMAGEHLP_LINE64 line;
symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol_info->MaxNameLen = MAX_SYM_NAME;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
ret = SymFromAddr(process, address, &sym_disp, symbol_info);
if (!ret) {
error_code = GetLastError();
if (error_code == ERROR_INVALID_ADDRESS) {
/* Missing symbols, print message */
rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL,
"%d: [<missing_symbols>]\n", frame_num--);
continue;
} else {
RTE_LOG_WIN32_ERR("SymFromAddr()");
goto end;
}
}
ret = SymGetLineFromAddr64(process, address, &lin_disp, &line);
if (!ret) {
error_code = GetLastError();
/* If ERROR_INVALID_ADDRESS tag unknown and proceed */
if (error_code != ERROR_INVALID_ADDRESS) {
RTE_LOG_WIN32_ERR("SymGetLineFromAddr64()");
goto end;
}
}
rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL,
"%d: [%s (%s+0x%0llx)[0x%0llX]]\n", frame_num,
error_code ? "<unknown>" : line.FileName,
symbol_info->Name, sym_disp, symbol_info->Address);
frame_num--;
}
end:
ret = SymCleanup(process);
if (!ret)
RTE_LOG_WIN32_ERR("SymCleanup()");
}