Monday, February 27, 2012

Remote Debugging CLI over SSH Tunnel in Zend Studio

I had trouble getting the path mapping to work on this.  I originally posted the blog entry last night stating I could not get it working.  This morning, I got it working, but the problem is I can't get it to stop working now, so I don't know exactly what fixed it.

The changes I made were: 1) I added an "original_url=http//test-server" to the QUERY_STRING environment variable.  I then created a new server under Studio Admin | Preferences | PHP DEBUG | PHP Servers | New.  I put "http://test-server" as the URL of that points to the document root of this server (which it actually is).  I then created a path mapping all the way down to the public directory.  Previously, my path mapping looked like this:

/home/server_name/site/current/releases/bootstrap => ProjectRoot

I left that in place, but I added another one with:
/home/server_name/site/current/releases/bootstrap/public => ProjectRoot/public

Once I did this, my path mapping suddenly started working.  However, I also closed out Zend Studio last night and reopened it this morning, and I didn't try to run this.  So maybe resetting studio captured some setting that wasn't sticking.  I just don't know.  And since I can't break it now, I can't figure out what the critical parameter is.  So best bet is to just follow all of the above.

ORIGINAL BLOG CONTENT FOLLOWS:

For remote debugging in general, the SSH tunnel works very well.  I prefer it to the so-called "tunneling" option native to Zend Studio, which I discussed in a another blog recently here.

This discussion assumes that you already have a working SSH connection to the remote server you want to debug on.

ESTABLISH A TUNNEL
Execute: SSH -R 10137:127.0.0.1:10137 user@remote-server

This will log you into the remote server.  Verify that this is working by running:
netstat -tln | grep 10137

on the remote server.  It should come back with something very similar to the following:


tcp        0      0 127.0.0.1:10137         0.0.0.0:*               LISTEN    
tcp6       0      0 ::1:10137               :::*                    LISTEN


If you don't get this, then maybe the user account you are using doesn't have adequate access to set this up.  It doesn't need all root privileges, but it does need some.  It's very possible that the account on which your application is setup does not have adequate access, and you need to tunnel in as "ubuntu" or the equivalent for your OS.

You need to keep this terminal session open as long as you are communicating with the remote machine.  I created a very simple bash file named "tunnel" with one argument "user@remote-server" to do this so I can easily shell into various machines.


#!/bin/bash
# Opens tunnel for use by Zend Studio

SSHCOMMAND="SSH -R 10137:127.0.0.1:10137"

echo "$SSHCOMMAND $1"
$SSHCOMMAND $1

I am also assuming you already have Zend Debugger setup on the remote machine.  I have some decent instructions for doing this in this blog: http://www.klugedeforce.com/2012/02/remote-debugging-over-tunnel-in-zend.html.  So I won't repeat them in detail here.  You need to put the "ZendDebugger.so" on the server, put "dummy.php" in the base directory, and configure the "php.ini" file or a "conf.d/*.ini" with the needed settings.  Make sure 127.0.0.1 is in the allowed hosts list.  You don't need the tunnel entry in the .ini at all, but having it won't hurt.


Go to Zend Studio | Preferences | PHP | Debug | Debug Servers.  Select the Zend Debugger entry and click "Configure".  Set "Debug Port: 10137" and set "Client Host/IP: 127.0.0.1"

Create a remote server with the address of the remote server as "http://test-server" or something along those lines.  If the remote server has a real address, use it.   Just be sure you set the identical address in the "original_url=http://test-server" in the QUERY_STRING environment variable (discussed later).  Set this new server to default.

To test you settings, you can go to Run | Debug Configurations and setup a debug session using the server you configured above (or just use any one you already have setup).  Click "test debugger".  It should give you a success message.  This uses dummy.php so it must be in the root html directory (probably */public) for this to work.  At this point, you can debug the remote server if you choose in a normal way.  As long as that terminal with the SSH session is open, all your Zend communication will route through it, and you can remote debug with no issues.  Disable the tunnel (i.e. exit from it), and change the server to a local one, and you can debug the local copy as well with the same settings.

I tried the following CLI debugging with the built in "tunnel" option, but it didn't even think about working, which is why I decided to try the SSH tunnel option.

DEBUGGING REMOTE CLI CALLS
You need to configure an Environment Variable named "QUERY_STRING" in order to debug command line PHP calls.  Zend debugger will pick up that QUERY_STRING and stop the session accordingly.  You can either set it when you call the script or export it from a BASH file (my preferred method).  I generally use a bash file to kick off the CLI processes and events and pass in any variables from the command line.

So I might end up calling something like:
X-Devent newPurchaseOrder 3048272 DEBUG, which will cause a PHP call to a cli.php file.  And before I do that, I can easily have:

export QUERY_STRING="start_debug=1&debug_fastfile=1&debug_host=127.0.0.1&use_remote=1&debug_port=10137&debug_stop=1&original_url=http://test-server&debug_session_id=1002"

at the top of the bash file that sets the QUERY_STRING environment variable a-priori.

Thanks to the "debug_stop=1", the code execution will stop in the debugger at the first line in the first PHP files it hits.  "use_remote=1" is taken from the server's perspective.  It actually means use the local copies of the files from Zend Studio (so you can set breakpoints).

I struggled to find the right permutations to get this to work, but now that it does, it's a great capability to have.  I can now debug queue events by intercepting the handler calls.

No comments:

Post a Comment