Is it possible to set breakpoints at a specific bytecode instruction? - java

I'm using jdb to remotely debug a Java application of which I don't have the source code. Furthermore, the application jars are obfuscated.
I can set method breakpoints but, is it possible to set breakpoints at a specific bytecode instruction within a method? The idea I have is to use some disassembler like javap to identify the interesting instructions.
Can jdb or other Java debugger do this?

You need line numbers to breakpoint on (something I assume has been removed). You can artificially add line numbers to the file using instrumentation and you will be able to breakpoint at every instruction if you wish.

Related

Modify JVM flags at Runtime

I would like to modify/set JVM flags as soon as my program starts. I cannot do it on the command line, because I work with people who don't even know that exists. So it has to be automatically done in the program.
I am particularly interested by these three flags: -Xms4G -Xmx8G -noverify
I found in this discussion (or that one) that it is possible to modify some flags using the Interface HotSpotDiagnosticMXBean. And this code shows how to modify the flags. Unfortunately, the flags Xms or just ms are not recognized and then an exception is thrown.
I've also found that capsule may do the work, but it seems pretty heavy to use.
Is there any easy way to do it?
You need to write two programs: one that is just a launcher to provide the correct parameters to run your other program. This is how Eclipse works, and Jitsi, and the now-end-of-life InstallShield Multiplatform launchers. It may be that you can write a trivial (eg one line or close to it) shell, .bat, or VBS script to do the job.

Eclipse: Is it Possbile to Set Breakpoint on a Whole Module

I have the following 2 questions regarding Eclipse debugger:
The application that I work on consists of a large number of Maven modules. Is it possible to set a break point on a whole module?
I often have to work on applications that I have no prior knowledge of, and thus don't know where to put a breakpoint. Is there a good place to set a break point in such apps to stop the debugger? Then I can just use the step debugger to trace and see what the code is doing.
Thanks
No, breakpoints are a point, namely a line, in the code where you would like execution to stop. The JVM has no notion of separate Maven modules, so cannot break on that basis.
What information do you start with? Presumably you're not literally looking at a .zip of code you know nothing about. You can place a breakpoint in the main() method to break (almost) as soon as the application starts, or identify other core classes and place breakpoints in them. Other than the actual application entry point (main() and so on), there is no standard "good" place to put a breakpoint in order to see what the code is doing.

Making my own debugger

I project to build my own bytecodes debugger to view:
the currents "objects" in the operands stack;
to have a visual representation of frames;
to have a list of declared objects in the Java heap (of the running program);
to have a list of constant pools, etc
The problem is I want to set up in place a breakpoint options to my program and to see the application in real.
I looked on the internet the way to do a debugger, and I found JDPA wich could probably help me doing my project.
But, I am not sure its the good thing, cause I don't want a Java debugger, I really need a Bytecode debugger.
How can I insert bytecodes break points in a project ? I see on the internet that "0xca is reserved as a breakpoint instruction for debuggers and is not used by the language". Is it the good way ?
Option#1 :
Using JPDA you can use com.sun.jdi.request.EventRequestManager.createBreakpointRequest() method you can add a breakpoint to any Location. Per the Java documentation on the Location class it is
A point within the executing code of the target VM.
It may be a bytecode location or the source line location.
Option#2: If you can find the method in which the bytecode lies you can place an artificial breakpoint in your JPDA-based debugger because you can tell the offset of the bytecode from the start of the function.

Debugging a Java program running from Tomcat (JSP)

I don't know why I never found myself having to use a debugger to step through my program and see what was going on, probably because I'm used to using interpreted languages such as PHP where it becomes very easy to add debugging code (print_r) and see changes live.
However with this new Java project I feel like I must learn the correct ways of debugging.
So this program, that I didn't write, runs on Tomcat and uses basic JSPs. The issue is that when I try to access a specific JSP page it throws an exception and gives me the stacktrace of what happened:
org.apache.jasper.JasperException: java.lang.NullPointerException
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:503)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:433)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:363)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:306)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.sgrp.singer.filters.SingerLoginFilter.doFilter(SingerLoginFilter.java:128)
How would I step through my program using a tool such as JDB? I can't really step through a specific class because I need to mimic what my JSP is doing... I would like to do this through the command-line, without using an IDE.
First, java has to be started with certain parameters to plugin a debugger:
-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
are the parameters used for our purpose. Afterwards, you use your IDE and connect the debugger remotely. You set a breakpoint to a piece of code (please make sure that the local files and the remote program are exactly the same revision) and generate the error. You can set breakpoints to uncaught exceptions as well.
As a hint: You can alter your referenced error-catching-JSP (error.jsp for us) to display not only the stacktrace of the caught exception (ex.getStracktrace), but also the causing stacktrace (ex.getCause().getStacktrace()). This might help identify higher level exception causes.
Edit: I'm sorry, without an IDE this is an information overflow that might not be possible for a human to do. Tomcat applications are complex on an architectural level, switching between a number of different classes for the easiest requests.
An alternative solution that may be easier to use than hooking a debugger to Tomcat:
First, take a look at the call stack. At the bottom, you'll see your class named org.sgrp.singer.filters.SingerLoginFilter. The problem lies here, at line 128 of method doFilter.
The first line says org.apache.jasper.JasperException: java.lang.NullPointerException. That means you've used an object whose value is null at line 128 of mentioned class.
Check out that code to find out what could be wrong. Also, add some print/logging statements to your code.
Debugging should be your last resort. You can gather a lot of information just by looking at your stack trace.
JDB could be used, it wouldn't be my first choice though.
Here is a good explanation how to use it:
http://www.javaworld.com/javaworld/javaqa/2000-06/04-qa-0623-jdb.html
You need to remember to include debug information when you compile your files and set up the Tomcat so you are able to connect to it, this is the string, as mentioned by other post:
-Xdebug -Xnoagent -Djava.compiler=NONE-Xrunjdwp:server=y, transport=dt_socket,address=8000,suspend=y
8000 can be replaced by any other numerical value. It basicaly tells jvm to listen on that port for a debugger.
What will happen now, is tomcat will start but suspend itself and wait for a debugger to attach before proceeding.
Start JDB and attach:
jdb -attach localhost:8000
in here, localhost can be replaced by where tomcat is running if it's running on a different machine and 8000 can be replaced with whatever port you set jvm in tomcat.
Now you can debug, you can see the debug instructions if you type help in jdb.
I have always used eclipse debugger, either running tomcat within eclipse or connecting eclipse to a separate, but local to eclipse, jboss server.
Works like a dream, no need to change jvm settings or anything.

Reconstruction of java command line arguments

Is there a way to reconstruct the command line arguments passed to Java within a Java program, including the JVM options and classpath option?
I have a Java program that needs to restart the JVM and manipulate its bootclasspath (i.e. trying to override some system classes). I use the libc system method to invoke the new JVM.
I'm open for better approaches, but Java agents isn't an option.
Why not use a file that has these properties just like the Eclipse ini file and NetBeans conf files. That way you just read these properties and spawn the new Java process with these properties.
Back to your question, this previous answer should do
I agree that futzing with the bootclasspath is generally a poor idea. But...
Grab the code for "java.c" - the C program that compiles down to java.exe. You'll find that it just uses the JNI Invocation API to construct a JVM and call the main method. You could modify and re-compile this to look for particular exit codes, etc. and loop around and re-launch the JVM if required.
Alternatively, Eclipse does this (or at least used to), but having one Java program construct the command line (from a props file, etc.) and launch a sub-process. Again, it hooked the sub-process exit code and used that to decide whether or not to re-launch a new sub-process.
Err... modifying a whole core java class at runtime is a very very bad idea.
Whats wrong with subclassing here? Are you trying to modify an external library, add functionality, or be lazy?

Categories