RFA: Problem with Exceptions

Hi all,

I'm compiling this trivial program on Darwin:

int main(int argc, char **argv) {
  try {
    throw argc;
  } catch(int i) {
    return i;
  }

  return 0;
}

However, it segfaults when I run it. I've attached the .s files
generated by LLVM and GCC, but it looks as if LLVM isn't generating a
gxx_personality_v0 section (like it does for Unwind_Resume, et al). Is
this what's causing the failure? Does anyone know how to get it to
generate this section?

Thanks!
-bw

t.gcc.s (4.16 KB)

t.llvm.s (4.06 KB)

Hi all,

I'm compiling this trivial program on Darwin:

int main(int argc, char **argv) {
  try {
    throw argc;
  } catch(int i) {
    return i;
  }

  return 0;
}

However, it segfaults when I run it. I've attached the .s files
generated by LLVM and GCC, but it looks as if LLVM isn't generating a
gxx_personality_v0 section (like it does for Unwind_Resume, et al). Is
this what's causing the failure? Does anyone know how to get it to
generate this section?

The most obvious thing different is that gcc expects the return value of the
throw (EDX) to be 1, while llvm expects it to be 2. Try changing the cmp to 2
at line 46 to cmp against 1 instead and see if that works.

t.gcc.s (4.16 KB)

t.llvm.s (4.06 KB)

It still fails. :frowning:

-bw

Hi Bill, is this a 64 bit machine? If so, did you make
any adjustments based on
http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-August/010489.html ?

Thanks,

Duncan.

Duncan,

Hi Bill, is this a 64 bit machine? If so, did you make
any adjustments based on
http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-August/010489.html ?

This is 32 bit machine. 64 bit will definitely won't work due to bunch
of stuff unimplemented: dwarf builtins, stack layout description, etc.

Hi Duncan,

This is on a 64-bit machine, but running as 32-bit. I tried using the
changes you mentioned in that email but it still segfaulted.

-bw

Hi Dale,

The most obvious thing different is that gcc expects the return value
of the
throw (EDX) to be 1, while llvm expects it to be 2. Try changing the
cmp to 2
at line 46 to cmp against 1 instead and see if that works.

that's because in order to have correct invoke semantics (always branch
to the unwind label whatever exception is unwound) we synthesize a
catch-all after the catch-an-int. This displaces the index of the
catch-an-int from 1 to 2, i.e. the code is correct.

Ciao,

Duncan.

Hi Bill,

I'm compiling this trivial program on Darwin:

int main(int argc, char **argv) {
  try {
    throw argc;
  } catch(int i) {
    return i;
  }

  return 0;
}

However, it segfaults when I run it. I've attached the .s files
generated by LLVM and GCC, but it looks as if LLVM isn't generating a
gxx_personality_v0 section (like it does for Unwind_Resume, et al). Is
this what's causing the failure? Does anyone know how to get it to
generate this section?

does it segfault if you link using mainline g++? Where does the segfault
occur - in the unwinder, or in the program itself (and if so, where)?

Thanks,

Duncan.

Hi Duncan,

> I'm compiling this trivial program on Darwin:
>
> int main(int argc, char **argv) {
> try {
> throw argc;
> } catch(int i) {
> return i;
> }
>
> return 0;
> }
>
> However, it segfaults when I run it. I've attached the .s files
> generated by LLVM and GCC, but it looks as if LLVM isn't generating a
> gxx_personality_v0 section (like it does for Unwind_Resume, et al). Is
> this what's causing the failure? Does anyone know how to get it to
> generate this section?

does it segfault if you link using mainline g++? Where does the segfault
occur - in the unwinder, or in the program itself (and if so, where)?

It segfaults if I compile the .s file with g++. The segfault's
occurring in the _Unwind_RaiseException function. It loops through
calling the personality function for each frame. The first time
through is fine, but the second time through it gets a bad address for
the personality function and barfs. Evan noticed that there was a bad
value in the Leh_frame_common_begin1 section:

.byte 0x1b # Personality (pcrel sdata4)

where gcc has:

.byte 0x9b # Personality (pcrel sdata4 indirect)

Changing this changed the segfault to:

terminate called after throwing an instance of 'int'
Abort trap

So we're getting closer at least. :slight_smile: Now I just need to figure out
why it's calling terminate and not catching the throw...

-bw

Hi Bill,

int main(int argc, char **argv) {
  try {
    throw argc;
  } catch(int i) {
    return i;
  }

  return 0;
}

I see a call to terminate in the llvm assembler. Where did that
come from? I compiled with llvm-gcc-4.0 and llvm-gcc-4.2 and
didn't see such a call.

Thanks,

Duncan.

Duncan,

I see a call to terminate in the llvm assembler. Where did that
come from? I compiled with llvm-gcc-4.0 and llvm-gcc-4.2 and
didn't see such a call.

std::terminate() is called by __cxa_throw, if unwinding fails. I think
the source of problem was my frame_to_args_offs patch. So, let's wait
for retest :slight_smile: