Can a single java thread be killed from jdb?
Asked Answered
X

3

4

In theory, the JDB (java debugger) allows for a single thread to be killed. In practice, is it possible? Here I attach jdb to my JVM, which has an agentlib at port 8000:

$ jdb -attach 8000
> 

I list the threads:

> threads
Group system:
  (java.lang ...
  [...]

I find the thread in question and try to kill it:

> kill 0x21bb new java.lang.Exception("die!")
killing thead: pool-766-thread-1
> com.sun.tools.example.debug.expr.ParseException: Unable to create java.lang.Exception instance
Expression must evaluate to an object

So threads cannot be killed?

How can one create a new Exception in the jdb, to give it to the thread to die?

Xylidine answered 18/11, 2011 at 21:40 Comment(1)
The semicolor does not make a difference (tested it), and the poster in the "here" link that you added also says that he cannot kill the thread either.Xylidine
J
1

The following answer on SO does seems only to enforce your question.

But the following answer probably does answer your question...

Jacks answered 19/11, 2013 at 12:38 Comment(1)
Or not. The difference between those is that the 1st answer linked doesn't show the status of the threads before trying to kill them. In the 2nd link the thread was being stepped at breakpoint, and killing it in that case works, but in the 1st link the thread was probably sleeping, and neither directly killing nor suspending it appears to work in that case. See my answer for details.Youngling
L
0

It is possible you have jconsole/jvisualvm also running. I had the same issue, but then I closed jconsole, the jdb kill command worked.

Lott answered 18/1, 2014 at 20:20 Comment(0)
S
0

I think I know what your problem was. You cannot kill threads with jdb unless they are first suspended. But one of the strange things in JVM is that you cannot suspend a sleeping thread. If it's "running (at breakpoint)", which really also means suspended, then it can be killed:

main[1] threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0x162 Reference Handler cond. waiting
  (java.lang.ref.Finalizer$FinalizerThread)0x161  Finalizer         cond. waiting
  (java.lang.Thread)0x160                         Signal Dispatcher running
Group main:
  (java.lang.Thread)0x1                           main              running (at breakpoint)
main[1] kill 0x1 new java.lang.Exception("die!")
killing thread: main
main[1] instance of java.lang.Thread(name='main', id=1) killed

OTOH, if you're trying to kill a thread that's sleeping, that seems impossible...

> threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0x162 Reference Handler cond. waiting
  (java.lang.ref.Finalizer$FinalizerThread)0x161  Finalizer         cond. waiting
  (java.lang.Thread)0x160                         Signal Dispatcher running
Group main:
  (java.lang.Thread)0x1bf                         Thread-0          sleeping
  (java.lang.Thread)0x1c1                         DestroyJavaVM     running
> kill 0x1bf new java.lang.Exception("die!")
killing thread: Thread-0
> com.sun.tools.example.debug.expr.ParseException: Unable to create java.lang.Exception instance
Expression must evaluate to an object
> suspend
All threads suspended.
> kill 0x1bf new java.lang.Exception("die!")
killing thread: Thread-0
> com.sun.tools.example.debug.expr.ParseException: Unable to create java.lang.Exception instance
Expression must evaluate to an object
> threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0x162 Reference Handler cond. waiting
  (java.lang.ref.Finalizer$FinalizerThread)0x161  Finalizer         cond. waiting
  (java.lang.Thread)0x160                         Signal Dispatcher running
Group main:
  (java.lang.Thread)0x1bf                         Thread-0          sleeping
  (java.lang.Thread)0x1c1                         DestroyJavaVM     running
> 

Even switching to that (sleeping) thread's own stack frame doesn't exactly help

> thread 0x1bf
Thread-0[1] kill 0x1bf new java.lang.Exception("die!")
killing thread: Thread-0
Thread-0[1] Thread not suspended
Expression must evaluate to an object

Also note that JDWP specific threads cannot be killed that way at all (via JDI, which jdb is also using underneath), as libjdwp will err on the request. Given the thread name pool-766-thread-1 involved in your example, I don't think it was one of those (JDWP) threads though.

Stepdaughter answered 2/7 at 11:37 Comment(1)
One might also infer/joke that the Java designers thought it's not polite to kill threads in their sleep. :PYoungling

© 2022 - 2024 — McMap. All rights reserved.