mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-17 04:45:47 +00:00
info: Load DbgHelp.dll using g_module_open()
... and update meson file so that enable it only using required headers. "dependency(...)" is unlikely successful for Windows SDK libraries since it doesn't ship pkg-config file. So it needs to be changed to "find_library()" to link corresponding .lib file. That would result to most MSVC build system will link dbghelp.dll. However, one drawback of the change is that gstreamer-1.0.dll will mandate dbghelp.dll although it should be optional. So g_module_open() way can be the most safe way in this case. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/626>
This commit is contained in:
parent
19fb999e09
commit
220ce9c3fd
2 changed files with 98 additions and 18 deletions
109
gst/gstinfo.c
109
gst/gstinfo.c
|
@ -156,9 +156,10 @@ static char *gst_info_printf_pointer_extension_func (const char *format,
|
||||||
#endif /* HAVE_BACKTRACE */
|
#endif /* HAVE_BACKTRACE */
|
||||||
|
|
||||||
#ifdef HAVE_DBGHELP
|
#ifdef HAVE_DBGHELP
|
||||||
#include <Windows.h>
|
#include <windows.h>
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
#include <tlhelp32.h>
|
#include <tlhelp32.h>
|
||||||
|
#include <gmodule.h>
|
||||||
#endif /* HAVE_DBGHELP */
|
#endif /* HAVE_DBGHELP */
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
|
@ -2958,19 +2959,91 @@ generate_backtrace_trace (void)
|
||||||
#endif /* HAVE_BACKTRACE */
|
#endif /* HAVE_BACKTRACE */
|
||||||
|
|
||||||
#ifdef HAVE_DBGHELP
|
#ifdef HAVE_DBGHELP
|
||||||
static void
|
/* *INDENT-OFF* */
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
DWORD (WINAPI * pSymSetOptions) (DWORD SymOptions);
|
||||||
|
BOOL (WINAPI * pSymInitialize) (HANDLE hProcess,
|
||||||
|
PCSTR UserSearchPath,
|
||||||
|
BOOL fInvadeProcess);
|
||||||
|
BOOL (WINAPI * pStackWalk64) (DWORD MachineType,
|
||||||
|
HANDLE hProcess,
|
||||||
|
HANDLE hThread,
|
||||||
|
LPSTACKFRAME64 StackFrame,
|
||||||
|
PVOID ContextRecord,
|
||||||
|
PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
|
||||||
|
PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
|
||||||
|
PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
|
||||||
|
PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
|
||||||
|
PVOID (WINAPI * pSymFunctionTableAccess64) (HANDLE hProcess,
|
||||||
|
DWORD64 AddrBase);
|
||||||
|
DWORD64 (WINAPI * pSymGetModuleBase64) (HANDLE hProcess,
|
||||||
|
DWORD64 qwAddr);
|
||||||
|
BOOL (WINAPI * pSymFromAddr) (HANDLE hProcess,
|
||||||
|
DWORD64 Address,
|
||||||
|
PDWORD64 Displacement,
|
||||||
|
PSYMBOL_INFO Symbol);
|
||||||
|
BOOL (WINAPI * pSymGetModuleInfo64) (HANDLE hProcess,
|
||||||
|
DWORD64 qwAddr,
|
||||||
|
PIMAGEHLP_MODULE64 ModuleInfo);
|
||||||
|
BOOL (WINAPI * pSymGetLineFromAddr64) (HANDLE hProcess,
|
||||||
|
DWORD64 qwAddr,
|
||||||
|
PDWORD pdwDisplacement,
|
||||||
|
PIMAGEHLP_LINE64 Line64);
|
||||||
|
} dbg_help_vtable = { NULL,};
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
static GModule *dbg_help_module = NULL;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dbghelp_load_symbol (const gchar * symbol_name, gpointer * symbol)
|
||||||
|
{
|
||||||
|
if (dbg_help_module &&
|
||||||
|
!g_module_symbol (dbg_help_module, symbol_name, symbol)) {
|
||||||
|
GST_WARNING ("Cannot load %s symbol", symbol_name);
|
||||||
|
g_module_close (dbg_help_module);
|
||||||
|
dbg_help_module = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ! !dbg_help_module;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
dbghelp_initialize_symbols (HANDLE process)
|
dbghelp_initialize_symbols (HANDLE process)
|
||||||
{
|
{
|
||||||
static gsize initialization_value = 0;
|
static gsize initialization_value = 0;
|
||||||
|
|
||||||
if (g_once_init_enter (&initialization_value)) {
|
if (g_once_init_enter (&initialization_value)) {
|
||||||
GST_INFO ("Initializing Windows symbol handler");
|
GST_INFO ("Initializing Windows symbol handler");
|
||||||
SymSetOptions (SYMOPT_LOAD_LINES);
|
|
||||||
SymInitialize (process, NULL, TRUE);
|
dbg_help_module = g_module_open ("dbghelp.dll", G_MODULE_BIND_LAZY);
|
||||||
GST_INFO ("Initialized Windows symbol handler");
|
dbghelp_load_symbol ("SymSetOptions",
|
||||||
|
(gpointer *) & dbg_help_vtable.pSymSetOptions);
|
||||||
|
dbghelp_load_symbol ("SymInitialize",
|
||||||
|
(gpointer *) & dbg_help_vtable.pSymInitialize);
|
||||||
|
dbghelp_load_symbol ("StackWalk64",
|
||||||
|
(gpointer *) & dbg_help_vtable.pStackWalk64);
|
||||||
|
dbghelp_load_symbol ("SymFunctionTableAccess64",
|
||||||
|
(gpointer *) & dbg_help_vtable.pSymFunctionTableAccess64);
|
||||||
|
dbghelp_load_symbol ("SymGetModuleBase64",
|
||||||
|
(gpointer *) & dbg_help_vtable.pSymGetModuleBase64);
|
||||||
|
dbghelp_load_symbol ("SymFromAddr",
|
||||||
|
(gpointer *) & dbg_help_vtable.pSymFromAddr);
|
||||||
|
dbghelp_load_symbol ("SymGetModuleInfo64",
|
||||||
|
(gpointer *) & dbg_help_vtable.pSymGetModuleInfo64);
|
||||||
|
dbghelp_load_symbol ("SymGetLineFromAddr64",
|
||||||
|
(gpointer *) & dbg_help_vtable.pSymGetLineFromAddr64);
|
||||||
|
|
||||||
|
if (dbg_help_module) {
|
||||||
|
dbg_help_vtable.pSymSetOptions (SYMOPT_LOAD_LINES);
|
||||||
|
dbg_help_vtable.pSymInitialize (process, NULL, TRUE);
|
||||||
|
GST_INFO ("Initialized Windows symbol handler");
|
||||||
|
}
|
||||||
|
|
||||||
g_once_init_leave (&initialization_value, 1);
|
g_once_init_leave (&initialization_value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ! !dbg_help_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
|
@ -2983,9 +3056,12 @@ generate_dbghelp_trace (void)
|
||||||
CONTEXT context;
|
CONTEXT context;
|
||||||
STACKFRAME64 frame = { 0 };
|
STACKFRAME64 frame = { 0 };
|
||||||
PVOID save_context;
|
PVOID save_context;
|
||||||
GString *trace = g_string_new (NULL);
|
GString *trace = NULL;
|
||||||
|
|
||||||
dbghelp_initialize_symbols (process);
|
if (!dbghelp_initialize_symbols (process))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
trace = g_string_new (NULL);
|
||||||
|
|
||||||
memset (&context, 0, sizeof (CONTEXT));
|
memset (&context, 0, sizeof (CONTEXT));
|
||||||
context.ContextFlags = CONTEXT_FULL;
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
@ -3024,19 +3100,23 @@ generate_dbghelp_trace (void)
|
||||||
|
|
||||||
line.SizeOfStruct = sizeof (line);
|
line.SizeOfStruct = sizeof (line);
|
||||||
|
|
||||||
if (!StackWalk64 (machine, process, thread, &frame, save_context, 0,
|
if (!dbg_help_vtable.pStackWalk64 (machine, process, thread, &frame,
|
||||||
SymFunctionTableAccess64, SymGetModuleBase64, 0))
|
save_context, 0, dbg_help_vtable.pSymFunctionTableAccess64,
|
||||||
|
dbg_help_vtable.pSymGetModuleBase64, 0)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (SymFromAddr (process, frame.AddrPC.Offset, 0, symbol))
|
if (dbg_help_vtable.pSymFromAddr (process, frame.AddrPC.Offset, 0, symbol))
|
||||||
g_string_append_printf (trace, "%s ", symbol->Name);
|
g_string_append_printf (trace, "%s ", symbol->Name);
|
||||||
else
|
else
|
||||||
g_string_append (trace, "?? ");
|
g_string_append (trace, "?? ");
|
||||||
|
|
||||||
if (SymGetLineFromAddr64 (process, frame.AddrPC.Offset, &displacement,
|
if (dbg_help_vtable.pSymGetLineFromAddr64 (process, frame.AddrPC.Offset,
|
||||||
&line))
|
&displacement, &line))
|
||||||
g_string_append_printf (trace, "(%s:%u)", line.FileName, line.LineNumber);
|
g_string_append_printf (trace, "(%s:%lu)", line.FileName,
|
||||||
else if (SymGetModuleInfo64 (process, frame.AddrPC.Offset, &module_info))
|
line.LineNumber);
|
||||||
|
else if (dbg_help_vtable.pSymGetModuleInfo64 (process, frame.AddrPC.Offset,
|
||||||
|
&module_info))
|
||||||
g_string_append_printf (trace, "(%s)", module_info.ImageName);
|
g_string_append_printf (trace, "(%s)", module_info.ImageName);
|
||||||
else
|
else
|
||||||
g_string_append_printf (trace, "(%s)", "??");
|
g_string_append_printf (trace, "(%s)", "??");
|
||||||
|
@ -3044,7 +3124,6 @@ generate_dbghelp_trace (void)
|
||||||
g_string_append (trace, "\n");
|
g_string_append (trace, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
return g_string_free (trace, FALSE);
|
return g_string_free (trace, FALSE);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_DBGHELP */
|
#endif /* HAVE_DBGHELP */
|
||||||
|
|
|
@ -370,12 +370,13 @@ endif
|
||||||
backtrace_deps = []
|
backtrace_deps = []
|
||||||
unwind_dep = dependency('libunwind', required : get_option('libunwind'))
|
unwind_dep = dependency('libunwind', required : get_option('libunwind'))
|
||||||
dw_dep = dependency('libdw', required: get_option('libdw'))
|
dw_dep = dependency('libdw', required: get_option('libdw'))
|
||||||
dbghelp_dep = dependency('DbgHelp', required : get_option('dbghelp'))
|
dbghelp_option = get_option('dbghelp')
|
||||||
backtrace_deps = [unwind_dep, dw_dep, dbghelp_dep]
|
have_dbghelp = cc.has_header('dbghelp.h', required: dbghelp_option) and cc.has_header('tlhelp32.h', required: dbghelp_option)
|
||||||
|
backtrace_deps = [unwind_dep, dw_dep]
|
||||||
backtrace_source_info = false
|
backtrace_source_info = false
|
||||||
backtrace_minimal = false
|
backtrace_minimal = false
|
||||||
# MSVC debug stack trace support
|
# MSVC debug stack trace support
|
||||||
if host_system == 'windows' and dbghelp_dep.found()
|
if host_system == 'windows' and have_dbghelp
|
||||||
cdata.set('HAVE_DBGHELP', 1)
|
cdata.set('HAVE_DBGHELP', 1)
|
||||||
backtrace_source_info = true
|
backtrace_source_info = true
|
||||||
# DWARF stack trace support with libunwind and elf-utils
|
# DWARF stack trace support with libunwind and elf-utils
|
||||||
|
|
Loading…
Reference in a new issue