object file/linking is missing my exception handlers

I have some exception handling which works fine using the JIT. Now I am
producing object files and linking them, but the exception handling
tables seem to be missing. I call _Unwind_RaiseException and get
_URC_END_OF_STACK as a result.

I produce my object file using TargetMachine::addPassesToEmitFile and
then I link my resulting files with:

gcc -o prog input.o -fexceptions

I'm sure I'm just missing some option to generate the Dwarf tables, but
I can't figure out what it is. For the JIT version I set
JITExceptionHandling and JITEmitDebugInfo on TargetOptions.

Hi,

I have some exception handling which works fine using the JIT. Now I am
producing object files and linking them, but the exception handling
tables seem to be missing. I call _Unwind_RaiseException and get
_URC_END_OF_STACK as a result.

you will get this if no catch clauses match (eg because there are no catch
clauses, perhaps because you only have cleanups). Maybe the JIT wraps the
program in a big catch-all clause? That would cause cleanups to run, and
would explain things if you don't have any catch clauses and instead do all
the work in cleanups.

I produce my object file using TargetMachine::addPassesToEmitFile and
then I link my resulting files with:

Are you using standard dwarf tables, or something of your own invention
(as discussed in a previous email)?

gcc -o prog input.o -fexceptions

This just calls the linker, the -fexceptions option will be ignored. In any
case, the big question is whether the exception table is in input.o already or
not. You can disassemble it and take a look.

I'm sure I'm just missing some option to generate the Dwarf tables, but
I can't figure out what it is. For the JIT version I set
JITExceptionHandling and JITEmitDebugInfo on TargetOptions.

You don't have to do anything AFAIK: by default the code generators will
produce an exception table.

Probably you should send in your IR and the .o file.

Ciao, Duncan.

you will get this if no catch clauses match (eg because there are no catch
clauses, perhaps because you only have cleanups). Maybe the JIT wraps the
program in a big catch-all clause? That would cause cleanups to run, and

I wrap the whole program in a catch-clause within the LLVM-IR itself.

I'm using the standard dwarf tables.

case, the big question is whether the exception table is in input.o
already or

I'm not sure what to look for. If I do a a 'readelf' on the file there
are a few 'GCC_except_table_' blocks.

Probably you should send in your IR and the .o file.

I've attached them (they are quite small, so hopefully okay for the
list). I'm note sure about my support functions though, so my code for
the test_throw() function is below. It doesn't get to the personality
function so I won't post that.

extern "C" void test_throw()
{
  _Unwind_Exception * ue =
static_cast<_Unwind_Exception*>(malloc(sizeof(_Unwind_Exception)));
  ue->exception_cleanup = leaf_cleanup_exception;
  ue->exception_class = leaf_exception_class;
  ue->private_1 = 123;
  ue->private_2 = 456;
  
  auto code = _Unwind_RaiseException( ue );
  //code == URC_END_OF_STACK
  //trace result/abort
}

basic.o (3.16 KB)

basic.o.ll (3.24 KB)

I can confirm now that my personality handler is invoked (I call
setHasUWTable on the functions now, but I'm not sure if that was the
difference). In any case it appears the behaviour of the
tables/handling is slightly different between the JIT and GCC linked.
I'm trying to figure out what this is now.

In appears, as additional error I had, that the JIT is totally okay with
calling _Unwind_Resume on an exception which has already been handled.
When this is done it behaves as rethrowing the same exception (it
seems). In the GCC/ELF executable this results in a segmentation fault.

So it just appears in all the JIT handling of exceptions is rather
different, perhaps more lenient than exec code. This is very strange of
course since my program calling the JIT is linked using the same GCC,
thus one would assume the _Unwind_ functions are exactly the same.
Perhaps just the EH table information is just layed out differently.