Discussion:
[Mingw-w64-public] How to catch access violations on x86 and x64
Niklas Baumstark
2011-08-02 16:06:49 UTC
Permalink
Hi guys,

I wonder whether there is a cross-architecture way to replace MSVC code like

__try {
// code that can create access violations
} __except(EXCEPTION_EXECUTE_HANDLER) {
// handler code
}

with an equivalent construct in GCC? I know about a viable solution for x86
(http://www.programmingunlimited.net/siteexec/content.cgi?page=mingw-seh),
but I can't figure out how to do it on x64.

Greetings,
Niklas
Kai Tietz
2011-08-02 16:30:06 UTC
Permalink
Post by Niklas Baumstark
Hi guys,
I wonder whether there is a cross-architecture way to replace MSVC code like
__try {
 // code that can create access violations
} __except(EXCEPTION_EXECUTE_HANDLER) {
 // handler code
}
with an equivalent construct in GCC? I know about a viable solution for x86
(http://www.programmingunlimited.net/siteexec/content.cgi?page=mingw-seh),
but I can't figure out how to do it on x64.
Greetings,
Niklas
Hello Niklas,

this is possible for gcc-based code, but to achieve this is a bit
tricky. You need inline-assembler and some labels. Additionally you
need for this a recent binutils and gcc 4.6 version with 64-bit
SEH-unwinding information support.

Then you can use the following pattern for this

function
{
....
#ifdef __SEH__
asm ("\t.l_startw:\n"
"\t.seh_handler __C_specific_handler, @except\n"
"\t.seh_handlerdata\n"
"\t.long 1\n"
"\t.rva .l_startw, .l_endw, _gnu_exception_handler ,.l_endw\n"
"\t.text"
);
#endif
....
#ifdef __SEH__
asm ("\tnop\n"
"\t.l_endw: nop\n");
#endif
...
}

The interesting part here is the line "\t.rva .l_startw, .l_endw,
_gnu_exception_handler ,.l_endw\n". The first rva is the
start-address of the first instruction within try-block,
the next is the end-address of the try-block (be aware that it needs
to +1 after end of last instruction in try-block). The third rva is
the handler to be called, and the fourth is the address of the
finally-block.

I hope this helps you a bit.

Regards,
Kai
Niklas Baumstark
2011-08-02 16:55:26 UTC
Permalink
Hi Kai,

first off, thanks for your swift response! Your code is an
excellent start for me to look into. I am actually using the latest
GCC and binutils already, so this is no problem for me.
However, are there any special configure options needed for either
of the two to enable the SEH-unwinding information support you
mentioned?
I further understand that __C_specific_handler and _gnu_exception_handler
are symbols defined in some GCC library. Right now, for reasons of code
size, I specifically disable any linkage (static or dynamic) to GCC libraries.
I guess this would be a show-stopper then?

Greetings,
Niklas
Kai Tietz
2011-08-02 19:07:46 UTC
Permalink
Post by Niklas Baumstark
Hi Kai,
first off, thanks for your swift response! Your code is an
excellent start for me to look into. I am actually using the latest
GCC and binutils already, so this is no problem for me.
However, are there any special configure options needed for either
of the two to enable the SEH-unwinding information support you
mentioned?
I further understand that __C_specific_handler and _gnu_exception_handler
are symbols defined in some GCC library. Right now, for reasons of code
size, I specifically disable any linkage (static or dynamic) to GCC libraries.
I guess this would be a show-stopper then?
Greetings,
Niklas
For x64 the SEH support is present OOTB then. Just use here the
__SEH__ guard to check, if compiler supports it.
The __C_specific_handler is a symbol from msvcrt (one of the many not
pretty good documented). The __gnu_exception_handler is an internal
symbol of mingw-w64. See here crt-code for more information.
Nevertheless you can use here instead of __C_specific_handler also
value one, if you don't want a catcher-routine to select, if you want
to handle exception, or not.

You can find in binutils source (gas/object/coff-obj-seh.[c|h] some
more information. Also you can find some documentation about this
handler on msdn.

Regards,
Kai
Niklas Baumstark
2011-08-02 19:29:46 UTC
Permalink
Okay Kai,

thank you very much for your help. I think I can figure the rest out by myself.

Greetings,
Niklas

Loading...