SOLVED: Wrestling with exceptions on win32 gcj 4.1

tHE DPR dpr@aha.lt
Thu Feb 9 09:20:00 GMT 2006


hi,

>> the stack traces are pretty much unusable though.
>> looking into that now.
>
> Does it help if you put the folder containing
> "addr2line" and "c++filt" (from binutils) in your
> PATH before you run your applications? I'm not
> in touch with GCJ/Win32 at all, but once upon a
> time, these were necessary to get line numbers
> and demangled names (respectively) in stack traces.
>
made some tests with this program:

import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class TestCallback
{
    public static void main (String [] args)
    {
        final Display display = new Display();

        Shell shell = new Shell(display);
        shell.setText("Exception in Windows callback");
        shell.setLayout(new FillLayout());

        shell.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent e) {
                e.gc.drawRectangle(10, 10, 200, 100);
                throw new IllegalStateException("ouch!");
            }
        });

        try {
            shell.open();

            while (!shell.isDisposed()) {
                if (!display.readAndDispatch())
                    display.sleep();
            }
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        display.dispose();
    }
}

i get this stacktrace:

java.lang.IllegalStateException: ouch!
   at 0x6387c8 (Unknown Source)
   at 0x4e191e (Unknown Source)
   at 0x4e6392 (Unknown Source)
   at 0x4e6c84 (Unknown Source)
   at 0x4e6ca4 (Unknown Source)
   at 0x4e6da4 (Unknown Source)
   at 0x401611 (Unknown Source)
   at 0x464784 (Unknown Source)
   at 0x4617d5 (Unknown Source)
   at 0x46a94a (Unknown Source)
   at 0x46c433 (Unknown Source)
   at 0x46a8bb (Unknown Source)
   at 0x46fb3d (Unknown Source)
   at 0x4436ec (Unknown Source)
   at 0x465afd (Unknown Source)
   at 0x402579 (Unknown Source)
   at 0x792543 (Unknown Source)
   at 0x64f0f9 (Unknown Source)
   at 0x64f840 (Unknown Source)
   at 0x511fa9 (Unknown Source)
   at 0x51206c (Unknown Source)
   at 0x10029501 (Unknown Source)
   at 0x1001d92c (Unknown Source)
   at 0x77d48812 (Unknown Source)
   at 0x77d4b4bc (Unknown Source)
   at 0x77d4b508 (Unknown Source)
   at 0x7c90eadf (Unknown Source)
   at 0x1000c22f (Unknown Source)
   at 0x46669f (Unknown Source)
   at 0x40d454 (Unknown Source)
   at 0x40e4bc (Unknown Source)
   at 0x4014da (Unknown Source)
   at 0x6bf92c (Unknown Source)
   at 0x59d287 (Unknown Source)
   at 0x50b470 (Unknown Source)
   at 0x4e0400 (Unknown Source)
   at 0x4e0562 (Unknown Source)
   at 0x4e0597 (Unknown Source)
   at 0x401308 (Unknown Source)
   at 0x401233 (Unknown Source)
   at 0x401284 (Unknown Source)
   at 0x7c816d4b (Unknown Source)

there are two problems with this stacktrace.

1) after filtering through
egrep -o '(0x\w*) ' stacktrace.txt | i686-pc-mingw32-addr2line -e snip.exe

i get this:
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/gcc-4.1/libffi/src/x86/win32.S:57
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
??:0
??:0
??:0
??:0
??:0
??:0
??:0
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:30
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/home/dpr/gcc/test/swt/TestCallback.java:12
/tmp/ccgHeB0g.i:11
prims.cc:0
prims.cc:0
??:0

i suspect it's a problem with debug info, or binutils (i'm using
binutils-2.16.1)

2) the ip addresses are skewed. they do not point
to the return location of a call nor to the location
of a call instruction. instead, they point to the
middle of a call instruction or some preceding
instruction. that depends on a length of a call
instruction. the formula for seems to be
ret_location - 4. that can't be correct in any case.


>
>>> Is another patch needed to remove the -fomit-frame-pointer you
>>> mentioned here? Maybe this is due to a new addition because manual
>>> configure.host hacking wasn't previously necessary.
>>>
>> i just didn't find any other way how to do it, so i replaced
>> all -fomit-frame-pointer to -fno-omit-frame-pointer in configure.host.
>
> Without DWARF-2 unwinding information (which is generated when
> you do not use SJLJ exceptions), the frame pointer (register
> EBP) is the only link that can be used to unwind through
> call frames. So I guess you should not use -fomit-frame-pointer
> if you want to be able to get stack traces when using SJLJ
> exceptions. If you're using DW2 exceptions though, you should
> use it on x86-32 at least to free up a valuable register.
>
but gcj is built with -fomit-frame-pointer even
when --enable-sjlj-exceptions
option is used, so i would suspect a configuration bug.

>
>>> There is an old patch that unfortunately hit a dead end, but helped with
>>> exceptions/stack traces by enabling basic Dwarf2 unwinding on win32
>>> (but not across .dll boundaries AFAIK)
>>>
>> not completely sure what it means. i remember somewhere in another post
>> it was told that just callbacks don't work.
>
> When using callbacks in Win32 GUI applications and using DW2
> exceptions, the unwinder is not able to unwind from the
> callback function all the way back to a suitable exception
> handler because the Win32 OS functions do not have any DW2
> unwind information associated with them. It is perhaps possible
> to work around this by defining a suitable
> MD_FALLBACK_FRAME_STATE_FOR, but there seems to be no one with
> the requisite knowledge, time and enthusiasm to do this. :-/
>
thanks for this info. now i get why my test program can throw
exceptions from win32 callback.

> DW2 unwind information based exception handling is far superior
> (IMHO) to SJLJ-based EH and it would hurt a platform to not
> move over to DW2 EH especially for languages like Java where
> the general trend is to throw exceptions wily-nily. :-/
>
anyone investigated SEH (structured exception handling)?

-- dpr



More information about the Java mailing list