jdb

http://herongyang.com/jtool/jdb.html

http://www.rhcedan.com/2010/06/22/killing-a-java-thread/

用处:上去杀死一个线程,!

"jdb" Command

"jdb": A command line tool that allows you to debug a Java application interactively with in a command line mode. "javac" is distributed as part of the Sun JDK package. It has the following syntax:

jdb [options] main_class_name
jdb [options] -attach <address>

where "options" is a list of options, "main_class_name" is a the name of the main class of a Java application, and "address" is the debugging connection address of a running Java application.

As you can see from the syntax, there are two ways of running "jdb":

1. Running "jdb" to launch a Java application and start a debug session on that application.

2. Running "jdb" to connect to a separately launched Java application and start a debug session on that application.

Commonly used options are:

  • "-help" - Displays a short help text.
  • "-verbose" - Generates verbose output to standard output.
  • "-classpath classpath" - Specifies a list of path names where the launcher will search for compiled type definitions.
  • "-Dproperty=value" - Defines a new system property, which can be accessed by the application.
  • "-launch" - Launches the debugged application immediately upon startup of jdb. This option removes the need for using the run command. The target application is launched and then stopped just before the initial application class is loaded. At that point you can set any necessary breakpoints and use the cont to continue execution.

Note that in order to use all debugging commands, the target application must be compiled with "-g" option, which will generate all debugging information, including source file, line number, and local variables, into the class file.

Launching and Debugging Java Applications

To test the debugger, I wrote the following simple Java application, Hello.java:

class Hello {
   public static void main(String[] a) {
      System.out.println("Hello world!");
   }
}

Here is what I did in a command window to run "jdb" to launch and debug Hello.java:

>javac Hello.java

>jdb Hello
Initializing jdb ...

> stop in Hello.main
Deferring breakpoint Hello.main.
It will be set after the class is loaded.

> run
run Hello
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
>
VM Started: Set deferred breakpoint Hello.main

Breakpoint hit: "thread=main", Hello.main(), line=3 bci=0
3          System.out.println("Hello world!");

main[1] next
Hello world!
>
Step completed: "thread=main", Hello.main(), line=4 bci=8
4       }

main[1] cont
>
The application exited

Notice that:

  • Once started, "jdb" offers you command prompt to allow you to run debugging commands interactively.
  • Without the "-launch" option, "jdb" will not start the main() method of the specified class.
  • "stop in" command sets a breakpoint at the beginning of the specified method. See the next section for other commonly used debugging commands.
  • "run" command starts a new JVM process with run your application in debug mode.
  • "jdb" and the JVM of your application are different processes. If you use Windows Task Manager, you should see two processes named as "jdb" and "java".
  • "next" command executes only the current statement of the debugged application.
  • "cont" command resumes the execution to the end or the next breakpoint.

If you want to launch the target application immediately, you can use the "-launch" option:

>jdb -launch Hello
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
>
VM Started: No frames on the current call stack

main[1] cont
> Hello world!

The application has been disconnected

As we expected, "jdb -launch" command launches the target application immediately, and stops at the beginning of the main() method.

Attaching "jdb" to Running Applications

If you ask "Can I launch the debugger (‘jdb‘) and the target application separately?", the answer is "Yes, you can.". In JDK 1.5, both "jdb" and "java" have been enhanced to use the latest JPDA (Java Platform Debugger Architecture) technology to give you the following options:

                     Debugger                 Target
Option                    jdb                   java

     1   Shared memory client   Shared memory server
     2   Shared memory server   Shared memory client
     3          Socket client          Socket server
     4          Socket server          Socket client

The shared memory options requires that the debugger and the target application to be on the same machine. Of course, the socket options allow you to run them remotely.

Let‘s try option #1 first. Open a command window on a windows system and run:

>java -agentlib:jdwp=transport=dt_shmem,address=MyHello,server=y,
   suspend=y Hello

Listening for transport dt_shmem at address: MyHello

The target application is launched in "shared memory server" mode. Its execution is suspended. Now open another command window and run:

>jdb -attach MyHello
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
>
VM Started: No frames on the current call stack

main[1] stop in Hello.main
Deferring breakpoint Hello.main.
It will be set after the class is loaded.

main[1] cont
> Set deferred breakpoint Hello.main

Breakpoint hit: "thread=main", Hello.main(), line=3 bci=0
3          System.out.println("Hello world!");

main[1] list
1    public class Hello {
2       public static void main(String[] a) {
3 =>       System.out.println("Hello world!");
4       }
5    }

main[1] cont
>
The application exited

As you can see, the debugger successfully connected to the target application. I used "next" command to let the target application to execute the current statement.

Let‘s try option #3 first. Open a command window on a windows system and run:

>java -agentlib:jdwp=transport=dt_socket,address=localhost:8888,server=y,
   suspend=y Hello

Listening for transport dt_socket at address: 8888

The target application is launched in "socket server" mode. Its execution is suspended. Now open another command window and run:

>jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8888
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
>
VM Started: No frames on the current call stack

main[1] stop in Hello.main
Deferring breakpoint Hello.main.
It will be set after the class is loaded.

main[1] cont
> Set deferred breakpoint Hello.main

Breakpoint hit: "thread=main", Hello.main(), line=3 bci=0
3          System.out.println("Hello world!");

main[1] quite

Cool. I know how to run "jdb" to debug an application running on a remote machine now!

However, the command suggested in the JPDA documentation did not work:

>jdb -attach localhost:8888
java.io.IOException: shmemBase_attach failed: The system cannot find
   the file specified
        at com.sun.tools.jdi.SharedMemoryTransportService.attach0(...
        ...

My guess is that the Windows version of "jdb" assumes "shared memory" as the default transport mode.

Debugging Commands

Ok, I think we did enough about launching the debugger and connecting to the target application. Let‘s now move on to look at some debugging commands.

Here is list of commonly used debugging commands. I got this list by using "help" at debugging prompt.

run [class [args]]        -- start execution of an application

threads [threadgroup]     -- list threads
thread <thread id>        -- set default thread
suspend [thread id(s)]    -- suspend threads (default: all)
resume [thread id(s)]     -- resume threads (default: all)
where [<thread id> | all] -- dump a thread‘s stack
up [n frames]             -- move up a thread‘s stack
down [n frames]           -- move down a thread‘s stack
kill <thread id> <expr>   -- kill a thread with the given exception
interrupt <thread id>     -- interrupt a thread

print <expr>              -- print value of expression
dump <expr>               -- print all object information
eval <expr>               -- evaluate expression (same as print)
set <lvalue> = <expr>     -- assign new value to a variable
locals                    -- print all local variables

classes                   -- list currently known classes
class <class id>          -- show details of named class
methods <class id>        -- list a class‘s methods
fields <class id>         -- list a class‘s fields

threadgroups              -- list threadgroups
threadgroup <name>        -- set current threadgroup

stop in <class id>.<method>[(argument_type,...)]
                          -- set a breakpoint in a method
stop at <class id>:<line> -- set a breakpoint at a line
clear <class id>.<method>[(argument_type,...)]
                          -- clear a breakpoint in a method
clear <class id>:<line>   -- clear a breakpoint at a line
clear                     -- list breakpoints
catch [uncaught|caught|all] <class id>|<class pattern>
                          -- break when specified exception occurs
ignore [uncaught|caught|all] <class id>|<class pattern>
                          -- cancel ‘catch‘

watch [access|all] <class id>.<field name>
                          -- watch access/modifications to a field
unwatch [access|all] <class id>.<field name>
                          -- discontinue watching
trace methods [thread]    -- trace method entry and exit
untrace methods [thread]  -- stop tracing method entry and exit
step                      -- execute current line
step up                   -- execute until the current method returns
stepi                     -- execute current instruction
next                      -- step one line (step OVER calls)
cont                      -- continue execution from breakpoint

list [line number|method] -- print source code
use (or sourcepath) [source file path]
                          -- display or change the source path
classpath                 -- print classpath info from target VM

monitor <command>         -- execute command each time the program stops
monitor                   -- list monitors
unmonitor <monitor#>      -- delete a monitor
read <filename>           -- read and execute a command file

lock <expr>               -- print lock info for an object
threadlocks [thread id]   -- print lock info for a thread

disablegc <expr>          -- prevent garbage collection of an object
enablegc <expr>           -- permit garbage collection of an object

!!                        -- repeat last command
<n> <command>             -- repeat command n times
help (or ?)               -- list commands
version                   -- print version information
exit (or quit)            -- exit debugger

Multi-Thread Debugging Exercise

To help me practice debugging commands, I wrote the following simple application, PrimeNumberSeeker.java:

 1 /**
 2  * PrimeNumberSeeker.java
 3  * Copyright (c) 2003 by Dr. Herong Yang, http://www.herongyang.com/
 4  */
 5 public class PrimeNumberSeeker extends Thread {
 6    private static final int ceiling = 100;
 7    private static final int interval = 1000;
 8    private static final int delay = 100;
 9    public int count = 0;
10    public int current = 2;
11    public int[] primes = null;
12    public static void main(String[] a) {
13       System.out.println("Period, Current int, # primes");
14       PrimeNumberSeeker t = new PrimeNumberSeeker();
15       t.start();
16       int i = 0;
17       while (true) {
18          i++;
19          System.out.println( i+", "+t.current+", "+t.count);
20          try {
21             sleep(interval);
22          } catch (InterruptedException e) {
23             System.out.println("Monitor interrupted.");
24          }
25       }
26    }
27    public void run() {
28       primes = new int[ceiling];
29       while (count < ceiling) {
30          current++;
31          int j = 2;
32          boolean isPrime = true;
33          while (j<current/2 && isPrime) {
34             isPrime = current % j > 0;
35             j++;
36          }
37          if (isPrime) {
38             count++;
39             primes[count-1] = current;
40          }
41          try {
42             sleep(delay);
43          } catch (InterruptedException e) {
44             System.out.println("Runner interrupted.");
45          }
46       }
47    }
48 }

Note that:

  • This application tries to use a sub-thread to calculate prime numbers.
  • The main thread is monitoring how the sub-thread is doing.
  • A delay mechanism is used to slow the calculation.
  • The application has an infinite loop. So you have to terminate it by "Ctrl-C".

Here is how I compiled the application and executed without debugging:

>javac -g PrimeNumberSeeker.java

>java PrimeNumberSeeker
Period, Current int, # primes
1, 2, 0
2, 12, 5
3, 22, 8
4, 32, 11
5, 42, 13
6, 52, 15
7, 62, 18
8, 72, 20
9, 82, 22
10, 92, 24
11, 102, 26
12, 112, 29
13, 122, 30
...
53, 521, 98
54, 531, 99
55, 541, 100
56, 541, 100
57, 541, 100
...

The output seems to be fine. But I want to use "jdb" to exam the calculation and to practice the debugging commands. Below I will show my debugging session in multiple parts with my comments.

1. Setting up breakpoints and getting the debugging session going:

>jdb PrimeNumberSeeker
Initializing jdb ...
> stop in PrimeNumberSeeker.main
Deferring breakpoint PrimeNumberSeeker.main.
It will be set after the class is loaded.

> run
run PrimeNumberSeeker
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
>
VM Started: Set deferred breakpoint PrimeNumberSeeker.main

Breakpoint hit: "thread=main", PrimeNumberSeeker.main(), line=13
13          System.out.println("Period, Current int, # primes");
main[1] stop in PrimeNumberSeeker.run
Set breakpoint PrimeNumberSeeker.run

main[1] cont
Period, Current int, # primes
1, 2, 0
>
Breakpoint hit: "thread=Thread-0", PrimeNumberSeeker.run(), line=28
28          primes = new int[ceiling];

Thread-0[1] threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0xe2 Reference Handler
  (java.lang.ref.Finalizer$FinalizerThread)0xe1  Finalizer
  (java.lang.Thread)0xe0                         Signal Dispatcher
Group main:
  (java.lang.Thread)0x1         main          running
  (PrimeNumberSeeker)0x118      Thread-0      running (at breakpoint)

Ok. What I have done so far:

  • Started the debugging session with the first breakpoint at the beginning of the main() method, which cause the execution to stop at line 13.
  • Then I created the second breakpoint at the beginning of the run() method in order to catch the sub thread.
  • Then I issued the "cont" command. My application continued with the sub thread created stopped at the breakpoint at line 28. The main thread also stopped.
  • Noticed that the debugger prompt is changed from "main[1]" to "Thread-0[1]". This is to inform you that you are currently in the sub thread, no longer in the main thread.
  • The I used the "threads" command to list all threads. I saw two thread groups: "system" and "main". Of course, I am not interested in the "system" group at this point. The "main" shows two threads: "main" (my monitoring thread) and "Thread-0" (my sub thread working on the calculation).
  • Thread "Thread-0" status shows "running (at breakpoint)". But the word "running" is referring to the thread execution mode, not the current execution status.
  • Notice that tread "main" is also stopped at this moment. As a general rule, if one thread is stopped, all other threads are stopped also.

2. Stepping through the sub thread:

Thread-0[1] where all
Signal Dispatcher:
Finalizer:
  [1] java.lang.Object.wait (native method)
  [2] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:111)
  [3] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:127)
  [4] java.lang.ref.Finalizer$FinalizerThread.run (Finalizer.java:...
Reference Handler:
  [1] java.lang.Object.wait (native method)
  [2] java.lang.Object.wait (Object.java:429)
  [3] java.lang.ref.Reference$ReferenceHandler.run (Reference.java...
main:
  [1] java.lang.Thread.sleep (native method)
  [2] PrimeNumberSeeker.main (PrimeNumberSeeker.java:21)
Thread-0:
  [1] PrimeNumberSeeker.run (PrimeNumberSeeker.java:28)

Thread-0[1] next
2, 2, 0
>
Step completed: "thread=Thread-0", PrimeNumberSeeker.run(), line=29
29          while (count < ceiling) {

Thread-0[1] where all
...
main:
  [1] java.lang.Thread.sleep (native method)
  [2] PrimeNumberSeeker.main (PrimeNumberSeeker.java:21)
Thread-0:
  [1] PrimeNumberSeeker.run (PrimeNumberSeeker.java:29)

Thread-0[1] next
3, 2, 0
>
30             current++;

Thread-0[1] next
4, 3, 0
>
31             int j = 2;
Thread-0[1] next
> 5, 3, 0
32             boolean isPrime = true;

Thread-0[1] next
6, 3, 0
>
33             while (j<current/2 && isPrime) {

Thread-0[1] list
29          while (count < ceiling) {
30             current++;
31             int j = 2;
32             boolean isPrime = true;
33 =>          while (j<current/2 && isPrime) {
34                isPrime = current % j > 0;
35                j++;
36             }
37             if (isPrime) {
38                count++;
Thread-0[1] print current
 current = 3

What I have done here:

  • I used "where all" to display the current location of all threads.
  • Then I used "next" to execute one statement in the current thread, the sub thread, going from line 28 to line 29.
  • The next "where all" command showed me that the main thread went through an entire iteration of the "while" loop. The main thread stopped again at line 21.
  • Then I used a couple of "next" command in the sub thread to bring the execution to line 33. At the same time, the main thread went through a couple of iterations, printed some output messages.
  • Then I used "print" to check the current value of variable "current". Value 3 is correct.

3. Checking local variables:

Thread-0[1] next
7, 3, 0
>
37             if (isPrime) {

Thread-0[1] print isPrime
 isPrime = true

Thread-0[1] next
8, 3, 0
>
38                count++;

Thread-0[1] next
9, 3, 0
>
39                primes[count-1] = current;

Thread-0[1] print count
 count = 1

Thread-0[1] next
> 10, 3, 1
42                sleep(delay);

Thread-0[1] list
38                count++;
39                primes[count-1] = current;
40             }
41             try {
42 =>             sleep(delay);
43             } catch (InterruptedException e) {
44                System.out.println("Runner interrupted.");
45             }
46          }
47       }

Thread-0[1] print primes[0]
 primes[0] = 3

What I have done here:

  • I used "next" again. The sub thread jumped over the calculation loop between line 33 and 36. This is correct, since "current" has "3", a prime number, no need to do any calculation.
  • Then I used "next" and "print" several times. I saw prime number 3 was correctly recorded in the "primes" array.

4. Going back to the main thread:

Thread-0[1] stop at PrimeNumberSeeker:19
Set breakpoint PrimeNumberSeeker:19
Thread-0[1] cont
>
Breakpoint hit: "thread=main", PrimeNumberSeeker.main(), line=19 bci=25
19             System.out.println( i+", "+t.current+", "+t.count);

main[1] where all
main:
  [1] PrimeNumberSeeker.main (PrimeNumberSeeker.java:19)
Thread-0:
  [1] java.lang.Thread.sleep (native method)
  [2] PrimeNumberSeeker.run (PrimeNumberSeeker.java:42)

main[1] print i
 i = 11

main[1] print t.current
 t.current = 3

main[1] print t.count
 t.count = 1

What I have done here:

  • I created another breakpoint in the main thread at line 19.
  • Then I allowed both threads to run naturally to the next breakpoint, line 19. The command prompt is changed back to "main[1]".
  • Then I used "where all" to check where the execution are stopped in all threads. It is interesting to see that the sub thread stopped inside the sleep() method.
  • Then I checked some local variables, "i", "t.current", and "t.count". Their values were all correct.

5. Switching threads:

main[1] cont
>
Breakpoint hit: "thread=main", PrimeNumberSeeker.main(), line=19 bci=25
19             System.out.println( i+", "+t.current+", "+t.count);

main[1] print t.current
 t.current = 14

main[1] print t.count
 t.count = 6

main[1] where all
...
main:
  [1] PrimeNumberSeeker.main (PrimeNumberSeeker.java:19)
Thread-0:
  [1] java.lang.Thread.sleep (native method)
  [2] PrimeNumberSeeker.run (PrimeNumberSeeker.java:42)

main[1] threads
...
Group main:
  (java.lang.Thread)0x1         main          running
  (PrimeNumberSeeker)0x118      Thread-0      running (at breakpoint)

main[1] thread 280

Thread-0[1] list
Current method is native

Thread-0[1] step out
11, 22, 8
>
Step completed: "thread=Thread-0", PrimeNumberSeeker.run(), line=45
45             }

Thread-0[1] list
41             try {
42                sleep(delay);
43             } catch (InterruptedException e) {
44                System.out.println("Runner interrupted.");
45 =>          }
46          }
47       }
48    }

Thread-0[1] print count
 count = 8

What I have done here:

  • I let the main thread executed a full period stopping at line 19 again. Of course, the sub thread execute some number of statements and stopped inside the sleep() native method.
  • Then I listed all threads and want to find a way to switch the command prompt to the sub thread to check local variable there. The manual says to use "thread n", where n is the thread index to change the current thread. But where can I to get the thread index? I tried to search the Web and did not get any clear answer.
  • However I got the answer from the output of the threads output. The thread index was listed as a hex number next to the class name. For example, "(PrimeNumberSeeker)0x118" means thread 0x118 = 280.
  • So I used "thread 280" to switch to the sub thread as the current thread. Notice that the command prompt changed.
  • The first "list" command did not work, because the sub thread was stopped inside the "sleep()" method. The "step out" command continued the execution just enough to finish "sleep()" and back to the caller, run().

6. Running one thread only:

Thread-0[1] stop at PrimeNumberSeeker:39
Set breakpoint PrimeNumberSeeker:39

Thread-0[1] cont
>
Breakpoint hit: "thread=Thread-0", PrimeNumberSeeker.run(), line=39
39                primes[count-1] = current;

Thread-0[1] cont
>
Breakpoint hit: "thread=main", PrimeNumberSeeker.main(), line=19
19             System.out.println( i+", "+t.current+", "+t.count);

main[1] cont
> 12, 23, 9

Breakpoint hit: "thread=Thread-0", PrimeNumberSeeker.run(), line=39
39                primes[count-1] = current;

Thread-0[1] cont
>
Breakpoint hit: "thread=main", PrimeNumberSeeker.main(), line=19
19             System.out.println( i+", "+t.current+", "+t.count);

main[1] suspend 1

main[1] cont
>
Breakpoint hit: "thread=Thread-0", PrimeNumberSeeker.run(), line=39
39                primes[count-1] = current;

Thread-0[1] cont
>
Breakpoint hit: "thread=Thread-0", PrimeNumberSeeker.run(), line=39
39                primes[count-1] = current;

Thread-0[1] cont
>
Breakpoint hit: "thread=Thread-0", PrimeNumberSeeker.run(), line=39
39                primes[count-1] = current;

Thread-0[1] print current
 current = 41

Thread-0[1] print count
 count = 13

What I have done here:

  • After check different areas of the code, I wanted to only the break the execution when a new prime number is found. So I created a breakpoint at line 39.
  • Then I used "cont" to let the execution to continue. But two threads always executed at the same time, and stopped at the same time whenever one thread reached a breakpoint.
  • So I used "suspend 1" to suspend the main thread. This is a cool command, allowing me to concentrate on a single thread. Of course, you can use "resume 1" to release the suspension.

I think I have done enough debugging practice and want to stop here now. However, my program does have a calculation error. I want to leave it to you to find out.

Conclusions

  • "jdb" is a nice debugging tool. But it only offers a command line interface, not so easy to use. It is much more efficient to use graphical interface debugger.
  • JPDA is well designed, allowing us to debug Java applications remotely.
  • Debugging multi-thread application is tricky. The following "jdb" notes may help you.
  • Whenever one thread reaches a break point, all other threads are stopped also.
  • The command prompt tells what is the current thread.
  • "where all" tells where the execution are currently in all threads.
  • "threads" lists all the threads with thread indexes as Hex numbers.

Killing a Java Thread

Programming Add comments

Jun 222010

This was amazingly impossible to find the answer to when I was looking for it.

The setup — running JVM, some thread doing something stupid like taking 100% CPU usage. For the purposes of my example, I will explain that I was using Jetty to serve a homegrown web application. With an Apache front-end, requests were being passed to Jetty over the AJP13 protocol using mod_jk.

Basically, the result of months of research turned out to be that a misconfigured client browser was passing a “Content-Length” value in the header of the request that was greater than the amount of data that was actually being supplied by the request. That’s stupid, right? What’s stupider is that in this situation, mod_jk winds up passing this crap along to Jetty, and with AJP13, Jetty sits there waiting for more data to come from the connector. But, there is no more data. So, away it would spin… until the service could be completely restarted, causing a service interruption for end-users. This was not acceptable, so before I was able to find what was actually causing the problem, I spent a long time finding a suitable work-around to the bug. The logical answer seemed to be “killing a java thread” — and I honestly thought that somebody else out there in the world had somehow found a way to kill a java thread. Apparently nobody in the mass of all google search results has ever found a way to kill a java thread that is attached to a running JVM, without destroying the entire JVM… at least not that I found.

So, for all of you guys out there that want/need to do the same thing — here’s your solution:

1) Ensure that your java program is started with the following parameters:

-Dcom.sun.management.jmxremote.port=50199 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xrunjdwp:transport=dt_socket,address=50100,server=y,suspend=n

This will allow us to attach the java debugger to the running process, after we identify which Thread is causing the problem. Also, make sure that you have your iptables setup appropriately so as to only allow connections on 50100 and 50199 from the hosts/workstations that you manage.

2) Identify the offending thread:
In order to identify the offending thread, I used the Java VisualVM
utility that is shipped with the JDK distribution. You can also use
JConsole, but VisualVM allows you to add in JConsole plugins, and the
look/feel is so much better than JConsole, so I use VisualVM. We’ll need
the JTop JConsole plugin, which you can find in /demo/management/JTop.jar. I trust you’ll be able to figure out how to get the plugin working…
The thread that is eating your CPU will be at the top of the list. For
the purposes of this example, the image below is an infant thread, so
the CPU(sec) column reflects only a few seconds worth of actual usage —
yours may/probably will be much higher.

3) Kill the thread.
In this example, the ThreadName is “btpool0-0″. Fire up the java
debugger (also shipped with the JDK distribution), and attach to the
running JVM…

[[email protected] ~]# jdb -attach 50100

Get a list of the running threads — this will also give us the thread id as the JVM sees it:

Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
< threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0x25c1             Reference Handler                                         cond. waiting
  (java.lang.ref.Finalizer$FinalizerThread)0x25c2              Finalizer                                                 cond. waiting
  (java.lang.Thread)0x25c3                                     Signal Dispatcher                                         running
  (java.lang.Thread)0x25c4                                     RMI TCP Accept-0                                          running
  (java.lang.Thread)0x25c5                                     RMI TCP Accept-50199                                      running
  (java.lang.Thread)0x25c6                                     RMI TCP Accept-0                                          running
  (java.lang.Thread)0x25c7                                     RMI Scheduler(0)                                          cond. waiting
Group main:
  (java.util.TimerThread)0x25ca                                Timer-0                                                   cond. waiting
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25cb      btpool0-0                                                 running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25cc      btpool0-1 - Acceptor0 [email protected]:8080 running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25cd      btpool0-2 - Acceptor1 [email protected]:8080 running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25ce      btpool0-3 - Acceptor0 [email protected]:8009   running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25cf      btpool0-4                                                 running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25d0      btpool0-5                                                 running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25d1      btpool0-6                                                 running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25d2      btpool0-7                                                 running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25d3      btpool0-8                                                 running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25d4      btpool0-9                                                 running
  (java.util.TimerThread)0x25d5                                Timer-1                                                   cond. waiting
  (java.lang.Thread)0x25d6                                     PoolScavenger0                                            cond. waiting
  (oracle.jdbc.pool.OracleImplicitConnectionCacheThread)0x25d8 Thread-15                                                 sleeping
  (java.util.TimerThread)0x25d9                                Timer-2                                                   cond. waiting
  (java.lang.Thread)0x25db                                     Thread-18                                                 cond. waiting
  (java.util.TimerThread)0x25dc                                Timer-3                                                   cond. waiting
  (java.util.TimerThread)0x25dd                                Timer-4                                                   cond. waiting
  (java.lang.Thread)0x25de                                     Northgate Server                                          running
  (java.util.TimerThread)0x25df                                Timer-5                                                   cond. waiting
  (java.util.TimerThread)0x25e0                                Timer-6                                                   cond. waiting
  (java.util.TimerThread)0x25e1                                Timer-7                                                   cond. waiting
  (java.util.TimerThread)0x25e2                                Timer-8                                                   cond. waiting
  (java.util.TimerThread)0x25e3                                Timer-9                                                   cond. waiting
  (java.lang.Thread)0x25e4                                     pool-1-thread-1                                           cond. waiting
  (java.util.TimerThread)0x25e5                                Timer-10                                                  cond. waiting
  (java.lang.Thread)0x25e6                                     DestroyJavaVM                                             running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25e7      btpool0-10                                                running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25e8      btpool0-11                                                running
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25e9      btpool0-12                                                running
  (oracle.jdbc.pool.OracleImplicitConnectionCacheThread)0x25ea Thread-756                                                sleeping
  (org.mortbay.thread.BoundedThreadPool$PoolThread)0x25eb      btpool0-13                                                cond. waiting
Group RMI Runtime:
  (java.lang.Thread)0x25ed                                     JMX server connection timeout 51                          cond. waiting
  (java.lang.Thread)0x25ee                                     RMI TCP Connection(2687)-127.0.0.1                        running
>

The thread id that we’re going to kill is “0x25cb”. The first step of killing the thread is to jump into it, and suspend it…

> thread 0x25cb
btpool0-0[1] suspend 0x25cb

Now, here’s the real trick, and the primary component of killing the thread that I was unable to find in all of the search that I had done… Step to the next frame.

btpool0-0[1] step
>
Step completed: <... snip ...>

This puts you in a position to inject a general exception into the running code (should probably be something that is uncaught), thereby exiting the running thread, and cleaning up objects gracefully within the JVM.

btpool0-0[1] kill 0x25cb new java.lang.Exception()
killing thread: btpool0-0
btpool0-0[1] instance of com.site.package.name(name=‘btpool0-0‘, id=9675) killed
btpool0-0[1]

Exit the java debugger, and you’re done!

-dan

时间: 2024-10-21 23:33:56

jdb的相关文章

Java自带的性能监测工具用法简介——jstack、jconsole、jinfo、jmap、jdb、jsta、jvisualvm

JDK内置工具使用 一.javah命令(C Header and Stub File Generator) 二.jps命令(Java Virtual Machine Process Status Tool) 三.jstack命令(Java Stack Trace) 四.jstat命令(Java Virtual Machine Statistics Monitoring Tool) 五.jmap命令(Java Memory Map) 六.jinfo命令(Java Configuration Inf

java调试工具jdb

Finds and fixes bugs in Java platform programs. Synopsis jdb [options] [classname] [arguments] options Command-line options. See Options. classname Name of the main class to debug. arguments Arguments passed to the main() method of the class. Descrip

Debug with jdb

原文地址: http://www.javaworld.com/article/2077445/testing-debugging/debug-with-jdb.html Q: How do you use jdb (included in the JDK 1.2 package) effectively to debug Java programs? I've tried many times, but I am successful only in loading a class file t

jdb - The Java Debugger

jdb 是一个简单的命令行调试器,可以调试本地或远程 Java Virtual Machine. jdb [ options ] [ class ] [ arguments ] options 命令行参数 class 调试的类名称 arguments main函数的参数 1. 开始调试 有两种方式启动调试,一个是新启动一个 JVM 加载指定的类,然后在开始执行指令时停止:另一个是连接到一个正在运行的 JVM.具体方法如下. (1) C:\> jdb MyClass (2) C:\> java

jdb调试scala代码的简单介绍

在linux调试C/C++的代码需要通过gdb,调试java代码呢?那就需要用到jdb工具了.关于jdb的用法在网上大家都可以找到相应的文章,但是对scala进行调试的就比较少了.其实调试的大致流程都是一样的,只是需要注意一些细节的地方就可以了.下面就来简单说明一下.在这里关于scala和jdk的配置问题就不再详述了,下面进入正题吧. 首先放上调试用的scala代码hello.scala object hello { def main(args: Array[String]): Unit = {

使用 JDB 调试 Android 应用程序

By Huang Tao of TinyLab.org 2015/04/13 前言 自从有了各种 IDE 工具,程序猿调试工作轻松了不少,只要在 IDE 上面点击两下按钮,各种程序运行时的信息全部都显示在屏幕上面,很美好的一件事情,我们都要感谢开发这些 IDE 工具的前辈,是他们让我们的工作变得这么"轻松简单",但是对于我个人来说,不是很喜欢这些 IDE 工具: 第一是因为这类 IDE 工具实在是变化太快,我们要花费很大的时间成本来学习这一类工具,然而当你好不容易熟悉了一种工具之后,别

java jdb命令详解

jdb - Java debugger 功能描述: 通过简单的命令行程序,对本地或远程jvm进程进行调试. 开启jdb会话: 有多种方式可以开启jdb会话. (1)常见的方式是采用Jdb命令打开一个新的jvm进程进行调试. 通过将jvm进程启动命令的java替换成jdb就可以了. 通过此方式启动jdb会话,将开启一个jvm进程,加载指定的class, 并停在第一条执行的指令前. 如: 当前目录有Java源文件 Test.java,  经过 javac -g Test.java 编译生成包含调试信

百度加固后检测反jdb调试apk的小记录

百度加固后的apk检测反jdb调试apk的简单分析,就一个很简单的记录而已,方便以后查阅. 按照正常IDA调试,在开始用jdb来连接,出错了 毕竟是加壳的东西,所以反编译看一下,竟然找到了一点内容,如下: static { if(!Debug.isDebuggerConnected()) { String v0 = Build.CPU_ABI; if(v0 != null && (v0.startsWith("x86"))) { StubApplication.load

Ext3文件系统及JDB介绍

Ext3介绍 对于ext3文件系统,磁盘空间划分一系列block groups,每个group有位图来跟踪inode和data块的分配和范围.其物理布局如下: Superblock:位于group内第0个block,为了保证兼容,前1024B字节为0,SB从1024B偏移处存储,大小1024B.存储的是文件系统相关信息,在多个group中有备份(0,1,3,5,7,9,25,37,49,81等).大部分信息在格式化时确定,并只读.可以用dumpe2fs命令查看: Group Descriptor

使用jdb调试apk

jdb是一个支持java代码级调试的工具,它是由java jdk提供的,存在于xxx\Java\jdk1.6.0_21\bin之下 使用ddms调试时,主机会打开另外一个网络端口,在DDMS里查看,一般是8700. 启动DDMS,这时程序前面应该有个红色小虫,点上面的开始调试按钮.这步不是必须的,这步的工作其实相当于手动敲: $ adb -d forward tcp:8700 jdwp:$PID 其中$PID为要调程序的进程号. 通过attach方式进行调试步骤: 显示所有可供调试的用户进程: