W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
/* gwin32-private.c - private glib functions for gwin32.c
|
|
|
|
|
*
|
|
|
|
|
* Copyright 2019 Руслан Ижбулатов
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
|
* along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Copy @cmdline into @debugger, and substitute @pid for `%p`
|
|
|
|
|
* and @event for `%e`.
|
2021-04-24 20:50:10 +00:00
|
|
|
|
* If @debugger_size (in wchar_ts) is overflowed, return %FALSE.
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
* Also returns %FALSE when `%` is followed by anything other
|
|
|
|
|
* than `e` or `p`.
|
|
|
|
|
*/
|
|
|
|
|
static gboolean
|
2021-04-24 20:50:10 +00:00
|
|
|
|
_g_win32_subst_pid_and_event_w (wchar_t *debugger,
|
|
|
|
|
gsize debugger_size,
|
|
|
|
|
const wchar_t *cmdline,
|
|
|
|
|
DWORD pid,
|
|
|
|
|
guintptr event)
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
{
|
|
|
|
|
gsize i = 0, dbg_i = 0;
|
|
|
|
|
/* These are integers, and they can't be longer than 20 characters
|
|
|
|
|
* even when they are 64-bit and in decimal notation.
|
|
|
|
|
* Use 30 just to be sure.
|
|
|
|
|
*/
|
|
|
|
|
#define STR_BUFFER_SIZE 30
|
2021-04-24 20:50:10 +00:00
|
|
|
|
wchar_t pid_str[STR_BUFFER_SIZE] = {0};
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
gsize pid_str_len;
|
2021-04-24 20:50:10 +00:00
|
|
|
|
wchar_t event_str[STR_BUFFER_SIZE] = {0};
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
gsize event_str_len;
|
2019-08-10 19:55:53 +02:00
|
|
|
|
|
2021-04-24 20:50:10 +00:00
|
|
|
|
_snwprintf_s (pid_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%lu", pid);
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
pid_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
2021-04-24 20:50:10 +00:00
|
|
|
|
pid_str_len = wcslen (pid_str);
|
|
|
|
|
_snwprintf_s (event_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%Iu", event);
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
event_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
2021-04-24 20:50:10 +00:00
|
|
|
|
event_str_len = wcslen (event_str);
|
2019-08-10 19:55:53 +02:00
|
|
|
|
#undef STR_BUFFER_SIZE
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
|
|
|
|
|
while (cmdline[i] != 0 && dbg_i < debugger_size)
|
|
|
|
|
{
|
2021-04-24 20:50:10 +00:00
|
|
|
|
if (cmdline[i] != L'%')
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
debugger[dbg_i++] = cmdline[i++];
|
2021-04-24 20:50:10 +00:00
|
|
|
|
else if (cmdline[i + 1] == L'p')
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
{
|
|
|
|
|
gsize j = 0;
|
|
|
|
|
while (j < pid_str_len && dbg_i < debugger_size)
|
|
|
|
|
debugger[dbg_i++] = pid_str[j++];
|
|
|
|
|
i += 2;
|
|
|
|
|
}
|
2021-04-24 20:50:10 +00:00
|
|
|
|
else if (cmdline[i + 1] == L'e')
|
W32: Add a simple exception handler
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
2019-01-13 11:21:04 +00:00
|
|
|
|
{
|
|
|
|
|
gsize j = 0;
|
|
|
|
|
while (j < event_str_len && dbg_i < debugger_size)
|
|
|
|
|
debugger[dbg_i++] = event_str[j++];
|
|
|
|
|
i += 2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
if (dbg_i < debugger_size)
|
|
|
|
|
debugger[dbg_i] = 0;
|
|
|
|
|
else
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|