Reproduced in: http://blog.csdn.net/jarfield/article/details/5250915
Recently, I have been studying Tomcat's work details. The main method is to refer to how Tomcat works and tomcat 5.5.26 source code.
The Tomcat code structure is clear and the comments are complete. However, the Code is static after all, and it is difficult to thoroughly understand the collaboration between classes and runtime objects.
If you can debug the process of starting, processing, and stopping tomcat, and check the whereabouts of tomcat in each step, you can solve the problem above.
So another question came out: How to Use eclipse to remotely debug tomcat?
I checked some documents online and found a lot of related articles. I briefly reviewed the solution and principles, and familiarized myself with the Tomcat STARTUP script.
How to remotely debug JVM?
Remote debugging of Tomcat is essentially remote debugging of JVM. Rather than understanding the running details of the JVM itself, you need to understand the running details of the applications on the JVM.
In any case, we need to obtain the internal information during JVM Runtime (such as viewing debugging information) and control the JVM running process (such as one-step execution ), in order to achieve the purpose of debugging.
This cannot be done by the debugger itself. Otherwise, the JVM security will be greatly compromised. Unless JVM provides a "backdoor" for the debugger to query some runtime information and allows the debugger to send some control commands.
I have to feel that the JVM is powerful. The javatm platform debugger architecture has been proposed and implemented since j2se 1.4.2.
JPDA for short.
JPDA Overview
As the name suggests, JPDA defines a standard architecture for the debugger on the Java platform. The architecture consists of three main components: JVM Ti, jdi, and jdwp.
The full name of JVM Ti is Java Virtual Machine Tool interface, which defines the functions and corresponding access interfaces that JVM must provide to support debugging. These access interfaces are provided in local languages and are implemented by JVM (such as Sun's hotspot VM.
However, JVM Ti is only a series of functions provided by JVM. How can I call a debugger (especially a remote debugger? Actually, the direct client of JVM Ti is not a debugger, but a stuff called "JPDA back-end. This stuff should be part of the JVM. in the bin directory of Sun JRE, you can find the library file of jdwp. dll (jdwp. So), which is the implementation of JPDA back-end. In my understanding, JPDA back-end provides various access methods (shared memory, socket) to receive debugger requests and then call the JVM
Ti interface.
The full name of jdi is Java debug interface, which defines high-level APIs for accessing the JVM Ti interface. It is provided in pure Java language and implemented by JDK (available in tools. jar of Sun JDK ). The debugger directly uses jdi for debugging. In contrast to the back-end of JPDA, the role implemented by jdi is JPDA front-end.
The full name of jdwp is Java debug wire protocol, which defines the binary format of communication information between JPDA front-end and JPDA back-end. The communication information includes the request information sent by the debugger to the JVM and the debugging information sent by the JVM to the debugger.
To sum up, the debugger calls the jdi implementation (JPDA front-end) provided by JDK, through the jdwp protocol, and the JPDA
Back-end (jdwp. dll, jdwp. So,...) for communication. JPDA back-end calls the JVM Ti interface to obtain debugging information or send control commands. Then, JPDA back-end uses the debugging information or command execution results through the jdwp protocol.
To the debugger.
How to enable JPDA
By default, JPDA back-end is not enabled in JVM. You need to load the following parameters on the command line that starts JVM:
-Xdebug-xrunjdwp: Transport = dt_socket, address = 8000, Server = Y, suspend = y
-Xdebug
Enable debugging features
-Xrunjdwp
Enable the jdwp implementation. It contains several sub-options:
Transport = dt_socket
The transmission method between JPDA front-end and back-end. Dt_socket indicates that socket transmission is used.
IP address = 8000
JVM listens for requests on port 8000.
Server = y
Y indicates that the started JVM is debugged. If it is N, the JVM started is the debugger.
Suspend = y
Y indicates that the started JVM will pause and wait until the debugger is connected.
Suspend = y is very important. If you want to debug from the beginning of Tomcat startup, you must set suspend = y.
Tomcat Startup Script
If JPDA is enabled when Tomcat is started, it can be debugged. By default, JPDA is not enabled for Tomcat, which must be manually enabled.
The method for enabling JPDA is also very simple. You can modify the Tomcat STARTUP script and add the command line parameters for starting JPDA.
However, the Tomcat STARTUP script is a bit complicated, and it is not a simple "Java...". Let's take a brief look.
There are n more scripts under the bin directory of Tomcat 5.5.26 release version. The scripts related to Tomcat Start and Stop are (take windows as an example ):
Startup. Bat // start Tomcat
Shutdown. Bat // stop Tomcat
Catalina. Bat // contains the core logic for starting/stopping Tomcat
Startup. BAT and shutdown. Bat both enable and stop by calling Catalina. bat, so they have very few code. The main logic is in Catalina. bat.
Catalina. bat is a powerful script. Through parameters, You can execute various actions, including debug run start stop version.
If we directly execute Catalina. bat, we can see its usage instructions:
Startup. bat, in fact, is to execute Catalina. bat start; shutdown. bat, in fact, is to execute Catalina. Bat stop.
It is not hard to guess, we can write a jdpa. bat, directly call Catalina. Bat JPDA start, you should be able to enable JPDA. Copy a copy of startup. BAT and set the following line.
Call "% executable %" start % cmd_line_args %
Modify
Call "% executable %" JPDA start % cmd_line_args %
However,-xdebug-xrunjdwp: Transport = dt_socket, address = 8000, Server = Y, suspend = Y. How can these option parameters be passed to Catalina. bat?
Take a look at the comments in front of Catalina. bat. The default value of server is Y. The value of transport is the variable jpda_transport, the value of address is the variable jpda_address, and the value of suspend is the variable jpda_suspend. If no explicit replication is performed, the default value of these variables is dt_shmem jdbconn (default value indicates that shared memory is used as the transmission mode ). These default values are not required. Currently, the remote debugging of eclisep only supports socket transmission. Call Catalina. Bat JPDA
Before start, we set the appropriate values for these variables:
Set jpda_transport = dt_socket
Set jpda_address = 8000
Set jpda_suspend = y
Call "% executable %" JPDA start % cmd_line_args %
Then, run JPDA. Bat directly, and tomcat runs in JPDA adjustable mode:
It can be seen that the JPDA of Tomcat uses Socket transmission and the listening port is port 8000. Tomcat startup has been paused. It will continue to be started only when the debugger is connected.
I listed the complete content of JPDA. bat in the following section. The simhei part is added based on startup. BAT:
@ Echo off
If "% OS %" = "windows_nt" setlocal
Rem ---------------------------------------------------------------------------
Rem JPDA script for the Catalina Server
Rem
Rem $ ID: JPDA. Bat 302918 18: 25: 11z yoavs $
Rem ---------------------------------------------------------------------------
Rem guess catalina_home if not defined
Set current_dir = % Cd %
If not "% catalina_home %" = "" Goto gothome
Set catalina_home = % current_dir %
If exist "% catalina_home %/bin/Catalina. Bat" Goto okhome
CD ..
Set catalina_home = % Cd %
Cd % current_dir %
: Gothome
If exist "% catalina_home %/bin/Catalina. Bat" Goto okhome
Echo the catalina_home environment variable is not defined correctly
Echo this environment variable is needed to run this program
Goto end
: Okhome
Set executable = % catalina_home %/bin/Catalina. bat
Rem check that target executable exists
If exist "% executable %" Goto okexec
Echo cannot find % executable %
Echo this file is needed to run this program
Goto end
: Okexec
Rem get remaining unshifted command line arguments and save them in
Set pai_line_args =
: Setargs
If "% 1" "=" Goto donesetargs
Set cmd_line_args = % cmd_line_args % 1
Shift
Goto setargs
: Donesetargs
Set jpda_transport = dt_socket
Set jpda_address = 8000
Set jpda_suspend = y
Call "% executable %"JPDAStart % cmd_line_args %
: End
Remotely debug tomcat in eclipse
First, the source code of Tomcat 5.5.26 is divided into five projects: Container connectors Jasper servletapi build and imported to eclipse. Start the relevant code mainly in the container. Take it as the current project and open the "Debug configurations" dialog box.
Create a remote Java application, select "Standard (socket attach)" for connection type, set "host" to "localhost", and "Port" to "8000. Click "Apply" to save.
Make sure that JPDA. bat has been executed, and Tomcat is waiting for the debugger to connect. then execute the preceding debug configuration, and eclipse can connect to Tomcat.
Tomcat starts from the main method of Bootstrap. When I set a breakpoint in the first line of code, Tomcat is started on this line:
Next, let Tomcat continue execution. We can see that the console outputs the startup information.