mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-13 04:46:15 +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.
|
* or for control flow.
|
||||||
*
|
*
|
||||||
* This function deliberately avoids calling any GLib code.
|
* 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
|
static LONG __stdcall
|
||||||
g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
||||||
{
|
{
|
||||||
EXCEPTION_RECORD *er;
|
EXCEPTION_RECORD *er;
|
||||||
char debugger[MAX_PATH + 1];
|
const gsize debugger_buffer_size = MAX_PATH + 1;
|
||||||
WCHAR *debugger_utf16;
|
char debugger[debugger_buffer_size];
|
||||||
const char *debugger_env = NULL;
|
char debugger_env[debugger_buffer_size];
|
||||||
const char *catch_list;
|
const gsize catch_buffer_size = 1024;
|
||||||
|
char catch_buffer[catch_buffer_size];
|
||||||
|
char *catch_list;
|
||||||
gboolean catch = FALSE;
|
gboolean catch = FALSE;
|
||||||
STARTUPINFOW si;
|
STARTUPINFOA si;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
DWORD flags;
|
||||||
|
|
||||||
if (ExceptionInfo == NULL ||
|
if (ExceptionInfo == NULL ||
|
||||||
ExceptionInfo->ExceptionRecord == NULL ||
|
ExceptionInfo->ExceptionRecord == NULL ||
|
||||||
@ -1097,7 +1106,11 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
|||||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||||
break;
|
break;
|
||||||
default:
|
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 &&
|
while (!catch &&
|
||||||
catch_list != NULL &&
|
catch_list != NULL &&
|
||||||
@ -1156,9 +1169,8 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
|||||||
|
|
||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
|
|
||||||
debugger_env = g_getenv ("G_DEBUGGER");
|
debugger_env[0] = 0;
|
||||||
|
if (!GetEnvironmentVariableA ("G_DEBUGGER", debugger_env, debugger_buffer_size))
|
||||||
if (debugger_env == NULL)
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
|
||||||
/* Create an inheritable event */
|
/* Create an inheritable event */
|
||||||
@ -1180,19 +1192,13 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
|||||||
}
|
}
|
||||||
debugger[MAX_PATH] = '\0';
|
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 */
|
/* Run the debugger */
|
||||||
if (0 != CreateProcessW (NULL,
|
if (0 != CreateProcessA (NULL, debugger, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi))
|
||||||
debugger_utf16,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
TRUE,
|
|
||||||
g_getenv ("G_DEBUGGER_OLD_CONSOLE") != NULL ? 0 : CREATE_NEW_CONSOLE,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&si,
|
|
||||||
&pi))
|
|
||||||
{
|
{
|
||||||
CloseHandle (pi.hProcess);
|
CloseHandle (pi.hProcess);
|
||||||
CloseHandle (pi.hThread);
|
CloseHandle (pi.hThread);
|
||||||
@ -1205,8 +1211,6 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
|||||||
WaitForSingleObject (event, 60000);
|
WaitForSingleObject (event, 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (debugger_utf16);
|
|
||||||
|
|
||||||
CloseHandle (event);
|
CloseHandle (event);
|
||||||
|
|
||||||
/* Now the debugger is present, and we can try
|
/* Now the debugger is present, and we can try
|
||||||
@ -1222,6 +1226,8 @@ g_win32_veh_handler (PEXCEPTION_POINTERS ExceptionInfo)
|
|||||||
void
|
void
|
||||||
g_crash_handler_win32_init (void)
|
g_crash_handler_win32_init (void)
|
||||||
{
|
{
|
||||||
|
char tmp;
|
||||||
|
|
||||||
if (WinVEH_handle != NULL)
|
if (WinVEH_handle != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1230,7 +1236,7 @@ g_crash_handler_win32_init (void)
|
|||||||
* break advanced exception handling such as in CLRs like C# or other managed
|
* 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/
|
* 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;
|
return;
|
||||||
|
|
||||||
WinVEH_handle = AddVectoredExceptionHandler (0, &g_win32_veh_handler);
|
WinVEH_handle = AddVectoredExceptionHandler (0, &g_win32_veh_handler);
|
||||||
|
Loading…
Reference in New Issue
Block a user