javadebuggingjdb

jdb : Perform a pre-defined action at a breakpoint


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.


Solution

  • 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.