Wednesday, October 24, 2012

How to remote debug PL/SQL with Oracle SQL Developer

There are quite a few posts (see the References section at the bottom) on how to debug PL/SQL remotely. That is when you want to step through another session that is running some PL/SQL procedure. Still I didn't find it obvious to get it working. Mainly because none of the blog posts have a diagram on how all components are connected and which component tries to connect with the other component(s). Therefore this post, including..... a diagram! :)

Setup
- on a Windows 7 desktop PC running SQL developer with IP xxx.yyy.19.84
- remote database running in VM with IP xxx.yyy.19.104. This one actually is running on the above desktop machine, but that should not change much if it would be on a separate machine, except there might be some firewall(s) in between.

In short this is what we are trying to achieve:


  1. Start up the remote debug listener on port 4000 on the desktop machine
  2. Start up SQl*Plus connecting to the remote database
  3. Connect to the remote debug listener from the database. This might be the tricky part for some: SQL*Plus is connected to the remote database, so the DBMS_DEBUG_JDWP.CONNECT_TCP call is executed from that database! So that machine (.104) needs to be able to get to the machine *.84) with the remote debug listener listening on port 4000
  4. Execute the stored procedure from the package you want to debug and SQL Developer will stop at the set breakpoints

Detailed steps
  1. As mentioned in all the referenced blog posts, right-click on the connection and select Remote Debug....
  2. In that popup enter:

    If done correctly, you should see something like:

    If you get a message saying "The debugger is not able to listen for JPDA using the specified parameters." then there is something wrong with the parameters you entered. Yes that's all I could figure out too... Potentially you entered the wrong Local address or maybe there's already something listening on the specified port.
    Note that the Local address is the IP of the machine SQL Developer is running on. Unless your database is running on that same machine, you can't use 127.0.0.1 (localhost). You have to use the full IP address.
  3. Since the database (which is on xxx.yyy.19.104) needs to connect to the SQL Developer remote debugger listener, it must be able to get to that machine (xxx.yyy.19.84). You can test this by trying to telnet to it and the port the listener is listening on from the .104 machine:
    
    
    $ telnet xxx.yyy.19.84 4000
    Trying xxx.yyy.19.84...
    Connected to MyPC (xxx.yyy.19.84).
    Escape character is '^]'.
    JDWP-Handshake
    ^]quit
    
    

    Look for the JDWP-Handshake string. If you get that, you know it can get to the remote debug listener on the .84 machine. Also note that when you quit the telnet session, the listener is stopped, so make sure to start it again!
  4. Start up an SQL*Plus session from the .84 machine to the remote database. For example:
    
    
    sqlplus user/passwd@xxx.yyy.19.104/oracle
    
    

  5. Connect to the remote lister on the .84 machine:
    
    
    SQL> set serveroutput on;
    SQL> execute DBMS_DEBUG_JDWP.CONNECT_TCP('xxx.yyy.19.84',4000);
    
    

    Note it is the .84 machine and of course port 4000 where the remote debugger is listening on.
  6. In SQL Developer, set a breakpoint in a procedure you want to debug, e.g test_me. Tip: as a first try, set it at the first line of code in the method test_me, then you know for sure that if it gets called, it should stop there definitely.
  7. Now call that procedure from the SQL*Plus commandline, e.g:
    
    
    DECLARE
      P_ANR VARCHAR2(25);
      P_RESULT VARCHAR2(4000);
    BEGIN
      P_ANR := 666;
    
      SOME_PCK.test_me(
        P_ANR => P_ANR,
        P_RESULT => P_RESULT
      );
      DBMS_OUTPUT.PUT_LINE('P_RESULT = ' || P_RESULT);
    END;
    /
    
    

    Note the test_me method has an IN and an OUT parameter.
  8. Your SQL Developer should now stop in the breakpoint you've set, see below SQL Developer screenshot of the Remote Debug session log window:


Remarks
I did not seem to need to run:


GRANT DEBUG CONNECT SESSION TO some_user;
GRANT DEBUG ANY PROCEDURE TO some_user;
/



You might still need to execute these commands if you get the permission errors you see in Step 5 here.

If you have a firewall on the .84 machine or between the two machines, you might need it to allow port 4000 to be accessed from the (other) DB machine...

References
Using SQL Developer to debug your anonymous PL/SQL blocks
Remote debugging with SQL Developer revisited
Application Express Community - Remote debugging
Sue's Blog... again... - Remote debugging with SQL Developer
Barry McGillin - Remote debugging with SQL Developer
Debug ApEx App with SQL Developer
Use Oracle SQL Developer to aid Oracle Application Express development
OTN Discussion Forums - Remote Debugging

1 comment:

Unknown said...

OMG! You saved my life. This is the best remote debugging tutorial in the whole internet.
Very well explained. Thank you very much.