views:

273

answers:

4

I'm trying to debug a problem in my Java application that throws no errors, no exceptions and doesn't even crash the app (it seems the failure happens in a separate thread).

The problem seems to be inside a call to a library function (it's JAXBContext.newInstance(String) if that matters). The program will reach the line just before the call, but not the one just after it. My catch blocks are not entered and the program just continues to run.

The problem happens while trying to render an XML response to a web request that came in via Struts. The request has been handled and the code should marshal the response object. The client gets a response right away (so the code doesn't seem to hang in a loop), but it's just empty.

I have set a breakpoint just before the problematic line but the debugger just runs over it, I haven't a clue why.

I'm using eclipse and the application runs inside an OSGi container (Apache Felix) that was started with -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y. From within Eclipse I then use the Debug settings for "Remote Java application" to connect the debugger.

What are techniques to get at such a problem?

A: 

perhaps inside the call there is an infitite loop happening and this is why you get no further - but this might not cause a crash (unless memory is being used in each loop).

Grouchal
No, I don't think so. The error happens upon handling a web request coming in via Struts and the client gets a result (which is empty) right away. So the app doesn't hang, it jumps out of the processing.
Hanno Fietz
+1  A: 

If you're sure the problem is somewhere within that method, you could try looking at the JAXB source code.

EDIT:

Well, if it gets really bad you can build your own private copy with debugging instrumentation. I hope you won't have to resort to that.

Matthew Flaschen
Well, I'll give that a try, but without getting the debugger to step in there, I might be having a hard time.
Hanno Fietz
+1  A: 

You could try getting a Thread Dump - that will tell you if any methods are blocking (e.g. waiting for input). [Edit: re-reading your original question, getting a thread dump probably won't help as it looks like nothing is actually blocking. But I'm leaving it here as I find it useful in many other situations!]

If you think the error is happening in another thread you could also set an UncaughtExceptionHandler to try and catch it.

Phill Sacre
Blocking: no, not this time. UncaughtExceptionHandler was a nice idea, unfortunately, it didn't catch anything either.
Hanno Fietz
+3  A: 

Probably an obvious question, but are you sure you are catching Throwable? An unchecked exception could easily cause the thread in question to die (assuming no one above you in the call stack is catching it either.)

Since you are suspending the VM on startup with your debug arguments, I assume you have confirmed that the debugger is attaching correctly. The fact that you say the debugger skips right past the call is very suspect. Are you able to hit any breakpoints in this application? What about in this Class? What about in this thread?

How did you narrow down the line in question without the debugger? println/debugging to a file?

Can you paste a code snippet of the method in question?

You could confirm the theory that the thread is dying by creating a second thread before the problem occurs and joining it to the thread you think is dying. Then the second thread's run() method would be invoked when the thread in question exits, and you'd know it died (but would still not know why.)

In answer to your general question, when I have a bug in a Java app that I can't reproduce in the debugger (which happens from time to time for various reasons), I incrementally modify my code with sysout printlns or output to files. If necessary, I may also modify the code my code is invoking. If you don't have the source code to the code you are invoking, you can try one of the many BCI frameworks to inject your byte code into the methods in question. It's a tedious process, but only happens occasionally.

jptsetme
+1 Not all Throwables are Exceptions, and we usually catch Exceptions; it's easy for this to slip past us.
Carl Manaster