[2/2] eal/windows: support debug calls
Checks
Commit Message
From: Tal Shnaiderman <talshn@mellanox.com>
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>
---
config/meson.build | 1 +
lib/librte_eal/common/meson.build | 1 +
lib/librte_eal/windows/eal.c | 7 ++++
lib/librte_eal/windows/eal_debug.c | 77 +++++++++++++++++++++++++++++++++-----
4 files changed, 77 insertions(+), 9 deletions(-)
Comments
On Sun, 7 Jun 2020 12:35:29 +0300
talshn@mellanox.com wrote:
> From: Tal Shnaiderman <talshn@mellanox.com>
>
> 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>
> ---
> config/meson.build | 1 +
> lib/librte_eal/common/meson.build | 1 +
> lib/librte_eal/windows/eal.c | 7 ++++
> lib/librte_eal/windows/eal_debug.c | 77 +++++++++++++++++++++++++++++++++-----
> 4 files changed, 77 insertions(+), 9 deletions(-)
>
> diff --git a/config/meson.build b/config/meson.build
> index 43ab113106..51a953c7d3 100644
> --- a/config/meson.build
> +++ b/config/meson.build
> @@ -268,6 +268,7 @@ if is_windows
> if cc.get_id() == 'gcc'
> add_project_arguments('-D__USE_MINGW_ANSI_STDIO', language: 'c')
> endif
> + add_project_link_arguments('-lDbgHelp', language: 'c')
When cross-compiling with MinGW-w64 from Linux, the library is "dbghelp"
(lowercase), and filesystem is case-sensitive, so this doesn't work. Suggest
using lowercase everywhere.
[snip]
> /* Launch threads, called at application init(). */
> int
> rte_eal_init(int argc, char **argv)
> diff --git a/lib/librte_eal/windows/eal_debug.c b/lib/librte_eal/windows/eal_debug.c
> index 669be6ff97..fda217bee4 100644
> --- a/lib/librte_eal/windows/eal_debug.c
> +++ b/lib/librte_eal/windows/eal_debug.c
> @@ -5,16 +5,75 @@
> #include <stdarg.h>
> #include <rte_log.h>
> #include <rte_debug.h>
> +#include <rte_windows.h>
>
> - /* call abort(), it will generate a coredump if enabled */
> -void
> -__rte_panic(const char *funcname, const char *format, ...)
> +#include <DbgHelp.h>
Same problem with filename, same solution.
> +
> +#define BACKTRACE_SIZE 256
> +
> +/* dump the stack of the calling core */
> +void rte_dump_stack(void)
Result type should be on its own line. Please re-check the series for this
particular violation, there are a few more instances.
[rest snipped]
@@ -268,6 +268,7 @@ if is_windows
if cc.get_id() == 'gcc'
add_project_arguments('-D__USE_MINGW_ANSI_STDIO', language: 'c')
endif
+ add_project_link_arguments('-lDbgHelp', language: 'c')
endif
if get_option('b_lto')
@@ -8,6 +8,7 @@ if is_windows
'eal_common_bus.c',
'eal_common_class.c',
'eal_common_devargs.c',
+ 'eal_common_debug.c',
'eal_common_errno.c',
'eal_common_launch.c',
'eal_common_lcore.c',
@@ -221,6 +221,13 @@ rte_eal_init_alert(const char *msg)
RTE_LOG(ERR, EAL, "%s\n", msg);
}
+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)
@@ -5,16 +5,75 @@
#include <stdarg.h>
#include <rte_log.h>
#include <rte_debug.h>
+#include <rte_windows.h>
- /* call abort(), it will generate a coredump if enabled */
-void
-__rte_panic(const char *funcname, const char *format, ...)
+#include <DbgHelp.h>
+
+#define BACKTRACE_SIZE 256
+
+/* dump the stack of the calling core */
+void 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()");
}