eal/windows: support exit and panic
authorTal Shnaiderman <talshn@mellanox.com>
Tue, 23 Jun 2020 20:57:21 +0000 (23:57 +0300)
committerThomas Monjalon <thomas@monjalon.net>
Wed, 24 Jun 2020 09:02:51 +0000 (11:02 +0200)
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>
config/meson.build
lib/librte_eal/common/meson.build
lib/librte_eal/windows/eal.c
lib/librte_eal/windows/eal_debug.c

index bb64c3b..351e268 100644 (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')
index 02e5d28..036ff62 100644 (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',
index b6bffd3..97c8427 100644 (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)
 {
index 669be6f..56ed70d 100644 (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();
+
+       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_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();
+               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()");
 }