4

While debugging a java application using jdb, is it possible to set a break-point with a pre-defined action. For instance if I am interested in knowing what the value of a certain variable is when the flow passes through a certain point, I can set a break-point with

> stop at MyClass:10

Perform an action :

> print myVal

and let the program continue.

> cont

Basically I want to combine / automate the above three commands into one.

I know I can achieve this using expect, but I want something builtin into jdb. My use case is to be able to debug customer issues on-prem where I cannot attach a regular IDE debugger or have no option to do a quick code change to add logs.

Gautam
  • 1,862
  • 9
  • 16

3 Answers3

2

Adding my own expect solution, in case someone else might be looking for something like this :

#!/usr/bin/expect --
set timeout -1
set DBGPROMPT "\\\[1\\\] "
set OPENBRACE "\\\("
spawn ~/debug/jdk1.8.0_171/bin/jdb -attach 5005

# In case you had terminated on a suspended thread the last time
expect ">"
send -- "resume\r"


# add a breakpoint
expect ">"
send -- "stop in com.example.auth.MyClass.doStuff\r"

expect {
    -regex "Breakpoint hit.*com.example.auth.MyClass.doStuff$OPENBRACE.*$DBGPROMPT"
    {
        send "print myVal\r"
        exp_continue
    }
    -regex ".*tomcat-http.*$DBGPROMPT"
    {
        interact "\033\[19~" return
        send "cont\r"
        exp_continue
    }
}
interact

Explanation The script adds a break-point for the method doStuff of class MyClass. The expect section defines two actions. One for breakpoint we have set : to print the value of myVal and then continue. The second action is the default behavior of any breakpoint you set for which you have not specified any action ( not even continue ). When the debugger stops at such a breakpoint, the control is given to the user to interact with it the way he wants. When he is done, he can press F8 to let the program continue.

If you want to add a new break-point, copy-paste the two lines after the comment "add a breakpoint" and change the path to class / method.

You can add break-points for line numbers in a similar way.

I'm using 'tomcat-http' as reg-ex for my usecase. You may have to change this if needed.

P.S. Change the path to the jdb binary accordingly.

Gautam
  • 1,862
  • 9
  • 16
1

I'm not aware of any way to accomplish this in JDB, however, this feature exists in IntelliJ IDEA. In the breakpoint properties, you can specify an expression and the IDE will evaluate it and log the result, and optionally continue the execution without stopping (if you uncheck the "Suspend" checkbox).

yole
  • 92,896
  • 20
  • 260
  • 197
-1

Sounds like you are trying to use debugger for something that it is not really meant for.

The concept you are describing can be solved if you have the source code. You can just put a LOG4j output to achieve your goal.

I have never used JDB debugger but I have used many different debuggers. However I did some research, from what I can tell I think it does not support such functionality which is also to be expected.

I have yet to see a debugger that does something like this. Essentially you want to have a "Watch feature" but on steroids. Ie, you do not even want to step through the program flow itself. You want a piece of code to be executed whenever a specific line of java opcode is executed.

To achieve something like this on machine level debugging (not JVM) you have to use codecaves/code injection & detouring. So you would intercept the execution. Thereafter you can modify/inspect whatever registries you want change. After you are done you would return to original execution point. This is something you do usually with malicious intent :).

Most closest thing to your current goal would be a conditional breakpoint and using it together with watch functionality that some Java debuggers offer - jdb does not. Both Eclipse and Intellij have support for conditional breakpoints & variable watching.

So you could breakpoint in your code only if something specific to your interests happens.

Miko
  • 135
  • 7
  • 4
    IntelliJ IDEA does have this feature. In the breakpoint properties, you can specify an expression and the IDE will evaluate it and log the result, and optionally continue the execution without stopping. – yole May 11 '18 at 07:57
  • @yole, +1, Does not exactly answers the question but does enhance my productivity toolkit. for "optionally continue.." , is it the "Remove once hit" check box ? Can you point me to the doc which explains this feature. – Gautam May 11 '18 at 08:48
  • 1
    [GDB does this for 'machine level'](https://sourceware.org/gdb/current/onlinedocs/gdb/Break-Commands.html#Break-Commands) and as I recall did this back to the '90s at least, and at least some commercial (non-FSF) debuggers did so well before that. I _think_ Java designers made jdb primitive because they expected better tools using jdwp to supersede it, which has largely happened (including the examples you cite), but I don't have evidence. – dave_thompson_085 May 11 '18 at 09:55
  • "Optionally continue" is the "Suspend" checkbox. The documentation for this feature is here: https://www.jetbrains.com/help/idea/breakpoints.html – yole May 11 '18 at 11:13
  • @yole You are indeed correct. Intellij conditional breakpoint settings dialog exceeds my expectations. It seems that is exactly what OP wants. Perhaps you can post an answer in my stead which OP can accept. – Miko May 11 '18 at 11:30