Looking for ideas to fix X server crash running GCJ-compiled program
Boehm, Hans
hans_boehm@hp.com
Fri Mar 7 00:42:00 GMT 2003
I don't know enough about X to help much. Some minor suggestions:
1) You should be able to set GC_free_space_divisor to a large number instead of fixing the heap size. If you are running in a workstation environment, this is likely to be more robust.
2) Setting GC_max_retries to essentially infinite will essentially force the collector into an infinite GC loop when it runs out of memory. That's usually not desirable.
I'm not sure how the X server could possibly get efficient access to the client heap, since it's neither in a shared memory segment nor mmapped against a file. Presumably a finalizer could still deallocate something in shared memory. Does the behavior change if the server isn't local? Xscope doesn't shed any light?
Finalizers are run from GC_invoke_finalizers(). Breakpoints there might help. Setting GC_PRINT_STATS might let you know whether a GC occurred just before the crash.
Hans
> -----Original Message-----
> From: Scott Gilbertson [mailto:scottg@mantatest.com]
> Sent: Thursday, March 06, 2003 10:16 AM
> To: java@gcc.gnu.org
> Subject: Looking for ideas to fix X server crash running GCJ-compiled
> program
>
>
> Recent tests of my application cause the X server to crash.
> I don't know if
> it's a problem with the server, the peers, awt, the garbage
> collector or the
> optimizer (or something else). I'm hoping this problem sounds really
> familiar to somebody, because I'm running out of ideas.
>
> It all started when I tried to get my app running without any
> "System.gc"
> calls, because they cause disgusting pauses. That meant I
> had to get the
> garbage collector to stop using up all the RAM in my system,
> so I made a
> native function that does:
> _Jv_GCSetMaximumHeapSize ((size_t)bytes);
> _Jv_GCSetInitialHeapSize ((size_t)bytes);
> GC_max_retries = 999999999L;
> where 'bytes' is typically 20,000,000. Now when I do a "load
> test", which
> involves simulating about 200 user input events per second
> with a function
> generator hooked up to a rotary knob input, the program
> doesn't run out of
> memory, so it runs much longer than an earlier attempt
> (several minutes!).
> The heap use periodically gets near the 20 meg limit then
> backs off to 13-15
> megs and climbs again. It climbs quickly, because there's
> garbage generated
> every time I put text on the screen -- I'll be looking at
> ways to reduce
> garbage generation (mainly implementing unimplemented methods
> in the xlib
> peers) once I get it to stop crashing. I mention all this
> because I wonder
> if the collection or finalization of some object is somehow
> involved in the
> X server crash. I didn't seem to have the crash before I took out the
> System.gc calls.
>
> I'm running linux kernel 2.4.19 on i386. My gcc is a 3.3
> snapshot from a
> couple of weeks ago, with all my awt/xlib patches (even the
> one Tom doesn't
> like, to permit lightweight Containers). I'm using the xlib peers.
>
> Now the X server crashes (taking my application with it, of
> course) after a
> few minutes of high load. According to a gdb backtrace, the
> problem is a
> SEGV in CopyGC. I'm using Xfbdev (tiny-X with frame-buffer
> driver). I
> built and tested the new version 4.3 XFree86 (previous tests
> were on 4.2.0),
> with the same result. I tried gdb'ing each of the 8 processes in my
> application, but I don't get any consistent point of failure.
> The program
> gets a SIGHUP, which I've figured out means the crash is in
> the X server.
> I'm not sure how to debug the problem, and I'm hoping it's obvious to
> somebody.
>
> I looked in the peer code and the only place XCopyGC (the client-side
> function which triggers CopyGC) is called is in gnu/gcj/xlib/natGC.cc.
>
> Here are my theories:
> 1. CopyGC isn't checking its arguments enough, and we're
> generating a bad
> argument.
> 2. We are prematurely collecting an object from which CopyGC
> is trying to
> get data.
> 3. We are calling XFreeGC and subsequently using that GC
> (i.e., cloning a GC
> that's been disposed), and the server doesn't catch the error.
> 4. The optimizer is re-arranging code, causing #2 or #3.
> 5. We are using too many X server resources before freeing some
>
> I guess #1 would be an XFree86 bug, and doesn't seem all that
> likely given
> the maturity level of XFree86. On the other hand, I'm using
> a tiny-X build,
> and maybe that eliminates some of the error checking.
>
> I don't know enough to decide whether #2 is a real possibility. For
> example, it's not clear to me whether the X server digs
> directly into the
> client's memory when both are running on the same machine,
> and hence would
> get upset if you'd reclaimed the object right after calling
> XCopyGC, but
> before the server has processed the request. That's what's implied at
> http://tronche.com/gui/x/xlib/my-own/gcontext.html : "GCs however, are
> references to opaque structures stored on the client side for
> efficiency
> reasons."
>
> For #3, I inspected the code, and couldn't spot any place
> where we use a GC
> after disposing it.
>
> For #4, I'm thinking of the cases where we have something like:
> SomeClass lThing = thing;
> thing = null;
> if (lThing != null)
> lThing.dispose ();
> You'd obviously want the nullification to happen before the
> dispose. An
> over-enthusiastic optimizer could theoretically reverse that.
> It doesn't
> seem very likely, though.
>
> For #5, I inspected the code. The only thing I noticed is that
> java.awt.Container.visitChild() creates (i.e. clones) a
> Graphics and doesn't
> dispose it. I added gfx2.dispose() in a finally block, but
> it didn't help.
> Here's the modified code:
> private void visitChild(Graphics gfx, GfxVisitor
> visitor,Component comp)
> {
> Rectangle bounds = comp.getBounds();
> Rectangle clip = gfx.getClipBounds().intersection(bounds);
>
> if (clip.isEmpty()) return;
>
> Graphics gfx2 = gfx.create();
> try
> {
> gfx2.setClip(clip.x, clip.y, clip.width, clip.height);
> gfx2.translate(bounds.x, bounds.y);
>
> visitor.visit(comp, gfx2);
> }
> finally
> {
> gfx2.dispose (); // This is the thing I added
> }
> }
>
>
> Any suggestions how I should proceed on debugging this thing,
> or theories
> that I've missed?
> Thanks.
>
>
>
More information about the Java
mailing list