mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 11:26:16 +01:00
W32: Don't use g_getenv() in crash handler or during initialization
The first is to avoid any non-trivial code in the crash handler. The second is to avoid the use of quarks and hash tables (brought in by g_getenv()) during GLib initialization.
This commit is contained in:
parent
ff8b43a154
commit
1955ede43b
@ -1068,20 +1068,29 @@ static void *WinVEH_handle = NULL;
|
||||
* or for control flow.
|
||||
*
|
||||
* This function deliberately avoids calling any GLib code.
|
||||
* This is done on purpose. This function can be called when the program
|
||||
* is in a bad state (crashing). It can also be called very early, as soon
|
||||
* as the handler is installed. Therefore, it's imperative that
|
||||
* it does as little as possible. Preferably, all the work that can be
|
||||
* done in advance (when the program is not crashing yet) should be done
|
||||
* in advance. And this function certainly does not need to use Unicode.
|
||||
*/
|
||||
static LONG __stdcall
|
||||
g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
||||
{
|
||||
EXCEPTION_RECORD *er;
|
||||
char debugger[MAX_PATH + 1];
|
||||
WCHAR *debugger_utf16;
|
||||
const char *debugger_env = NULL;
|
||||
const char *catch_list;
|
||||
const gsize debugger_buffer_size = MAX_PATH + 1;
|
||||
char debugger[debugger_buffer_size];
|
||||
char debugger_env[debugger_buffer_size];
|
||||
const gsize catch_buffer_size = 1024;
|
||||
char catch_buffer[catch_buffer_size];
|
||||
char *catch_list;
|
||||
gboolean catch = FALSE;
|
||||
STARTUPINFOW si;
|
||||
STARTUPINFOA si;
|
||||
PROCESS_INFORMATION pi;
|
||||
HANDLE event;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
DWORD flags;
|
||||
|
||||
if (ExceptionInfo == NULL ||
|
||||
ExceptionInfo->ExceptionRecord == NULL ||
|
||||
@ -1097,7 +1106,11 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
break;
|
||||
default:
|
||||
catch_list = g_getenv ("G_VEH_CATCH");
|
||||
catch_buffer[0] = 0;
|
||||
if (!GetEnvironmentVariableA ("G_VEH_CATCH", catch_buffer, catch_buffer_size))
|
||||
break;
|
||||
|
||||
catch_list = catch_buffer;
|
||||
|
||||
while (!catch &&
|
||||
catch_list != NULL &&
|
||||
@ -1156,9 +1169,8 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
||||
|
||||
fflush (stderr);
|
||||
|
||||
debugger_env = g_getenv ("G_DEBUGGER");
|
||||
|
||||
if (debugger_env == NULL)
|
||||
debugger_env[0] = 0;
|
||||
if (!GetEnvironmentVariableA ("G_DEBUGGER", debugger_env, debugger_buffer_size))
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
/* Create an inheritable event */
|
||||
@ -1180,19 +1192,13 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
||||
}
|
||||
debugger[MAX_PATH] = '\0';
|
||||
|
||||
debugger_utf16 = g_utf8_to_utf16 (debugger, -1, NULL, NULL, NULL);
|
||||
if (GetEnvironmentVariableA ("G_DEBUGGER_OLD_CONSOLE", (char *) &flags, 1))
|
||||
flags = 0;
|
||||
else
|
||||
flags = CREATE_NEW_CONSOLE;
|
||||
|
||||
/* Run the debugger */
|
||||
if (0 != CreateProcessW (NULL,
|
||||
debugger_utf16,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
g_getenv ("G_DEBUGGER_OLD_CONSOLE") != NULL ? 0 : CREATE_NEW_CONSOLE,
|
||||
NULL,
|
||||
NULL,
|
||||
&si,
|
||||
&pi))
|
||||
if (0 != CreateProcessA (NULL, debugger, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi))
|
||||
{
|
||||
CloseHandle (pi.hProcess);
|
||||
CloseHandle (pi.hThread);
|
||||
@ -1205,8 +1211,6 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
||||
WaitForSingleObject (event, 60000);
|
||||
}
|
||||
|
||||
g_free (debugger_utf16);
|
||||
|
||||
CloseHandle (event);
|
||||
|
||||
/* Now the debugger is present, and we can try
|
||||
@ -1222,6 +1226,8 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
||||
void
|
||||
g_crash_handler_win32_init (void)
|
||||
{
|
||||
char tmp;
|
||||
|
||||
if (WinVEH_handle != NULL)
|
||||
return;
|
||||
|
||||
@ -1230,7 +1236,7 @@ g_crash_handler_win32_init (void)
|
||||
* break advanced exception handling such as in CLRs like C# or other managed
|
||||
* code. See: https://blogs.msdn.microsoft.com/jmstall/2006/05/24/beware-of-the-vectored-exception-handler-and-managed-code/
|
||||
*/
|
||||
if (g_getenv ("G_DEBUGGER") == NULL && g_getenv("G_VEH_CATCH") == NULL)
|
||||
if (!GetEnvironmentVariableA ("G_DEBUGGER", (char *) &tmp, 1))
|
||||
return;
|
||||
|
||||
WinVEH_handle = AddVectoredExceptionHandler (0, &g_win32_veh_handler);
|
||||
|
Loading…
Reference in New Issue
Block a user