SublimeXdebug
SublimeXdebug copied to clipboard
xdebug on a remote ip?
i dont see documentation how to configure a new IP because i want to debug an application thats on a dedicated server. It seems to connect to 127.0.0.1 only?
Currently, it only works when Sublime is on the same machine as the webserver/Xdebug install. Kindari is working on rewriting the plugin to allow for remote debugging. You can find more info on it on #36
how does the IP affect it? I'm missing something or what? this is a network level, what does xdebug/st care if it's on the localhost or not?
It's not so much about IP as it is about filesystem paths. When you're working with a remote server, the filesystem path that Sublime/SublimeXdebug sees is different than the one that Xdebug sees, even if you're mounting the remote files directly (such as through sshfs or other remote mounting system), because the path is still technically different. The only way it would work is if you RDPed into the server and ran Sublime directly on it, so that the paths matched correctly.
Issue #26 goes into more detail about why remote debugging doesn't work with this version, and how the rewrite will likely fix it.
I'd figure that it would be possible to just create the symlinks on the host (that runs ST) to represent the guest's FS (that runs php/xdebug) but that doesn't seem to be enough for some reason. And this issue is still awaiting attention I see.
I was curious on the file paths issue so I started looking into it:
- To mimic the paths I created symlinks to represent on both systems the correct path. Figured this should be an easy work-around but it didn't work since there's an open bug for a known issue that Xdebug can't handle symlinks and always expands to the full path so no win here.
- Enabling Xdebug remote logs I see the conversation between ST and Xdebug and the xml shows the file:/// with the path of my host system that runs ST for the breakpoints - which is probably the issue - so I hacked Xdebug.py and changed the pathname to reflect the actual file system on the guest where Xdebug and the php code lives - yet this doesn't work.
If it's just path mapping it doesn't look like that much of an effort but at this point I'm not sure that this is the only problem.
Let's stir this discussion towards something productive so we can find the solution here.
I changed Xdebug.py@222 as follows:
def uri(self):
local_path = os.path.realpath(self.view.file_name())
remote_path = local_path.replace( "/mnt/server/", "/" )
return 'file://' + remote_path
Now, breakpoints work. But I still don't see anything in those 2 Xdebug-frames below.
Interesting. So it could be that the breakpoints worked for me too I guess (I didn't catch anything visual in those 2 xdebug frames either). Have you got any lead why those boxes aren't populated if it's actually working?
@lirantal You should see a message in the status bar: "Xdebug: breakpoint" when the bp is working. Pressing F8 you can then Step Into, Step Over, etc.. I did not yet investigate from where the boxes get filled. I don't know when I'll find time to look into it.
@mbirth: I had the same issue. You need to include your remote_path setup near line 469 where you see this:
xdebug_current = show_file(self.view.window(), child.getAttribute('filename'))
the chile.getAttribute... needs to be replaced to account for your remote_path
I've put a console debug line there but I don't see the code even reaching that part. I'm also doing remote debugging and even though I've put breakpoints, then clicked 'Start debugging' in Sublime and then loaded a URL with a GET parameter of XDEBUG_SESSION_START I see nothing in xdebug nor execution does not stop in the browser... Sublime just shows in the console: "Page finished executing, reload to continue..."
I finally found some time to experiment further and got it to work for me (thanks to @nathanjovin), here's what I did:
diff --git a/Xdebug.py b/Xdebug.py
index 5bf9fe8..158c429 100644
--- a/Xdebug.py
+++ b/Xdebug.py
@@ -219,7 +219,12 @@ class XdebugView(object):
self.del_breakpoint(row)
def uri(self):
- return 'file://' + os.path.realpath(self.view.file_name())
+ # XXX: Translate local path to remote path
+ translations = get_project_setting('path_translations') or get_setting('path_translations') or None
+ local_path = os.path.realpath(self.view.file_name())
+ remote_path = local_path.replace(translations['local2remote'][0], translations['local2remote'][1])
+ sublime.status_message('Xdebug: Path was: ' + local_path + ' and now is: ' + remote_path)
+ return 'file://' + remote_path
def lines(self, data=None):
lines = []
@@ -460,8 +465,13 @@ class XdebugContinueCommand(sublime_plugin.TextCommand):
for child in res.childNodes:
if child.nodeName == 'xdebug:message':
#print '>>>break ' + child.getAttribute('filename') + ':' + child.getAttribute('lineno')
- sublime.status_message('Xdebug: breakpoint')
- xdebug_current = show_file(self.view.window(), child.getAttribute('filename'))
+ sublime.status_message('Xdebug: breakpoint at ' + child.getAttribute('filename') + ':' + child.getAttribute('lineno'))
+ # XXX: Translate remote path to local path
+ translations = get_project_setting('path_translations') or get_setting('path_translations') or None
+ remote_path = child.getAttribute('filename')[7:] # omit "file://"
+ local_path = "file://" + remote_path.replace(translations['remote2local'][0], translations['remote2local'][1])
+ sublime.status_message('Xdebug: breakpoint at local file ' + local_path + ':' + child.getAttribute('lineno'))
+ xdebug_current = show_file(self.view.window(), local_path)
xdebug_current.current(int(child.getAttribute('lineno')))
if (res.getAttribute('status') == 'break'):
And in my project settings, I added this:
{
// ...
"settings":
{
"xdebug":
{
"url": "http://myserver/mypath/myscript",
"path_translations":
{
"local2remote": [ "/mnt/server/", "/" ],
"remote2local": [ "/var/www/", "/mnt/server/var/www/" ]
}
}
}
}
Note: Since it's a simple String.replace()
, never use [ "/", "/mnt/server/" ]
for remote2local
as it will replace ALL slashes by the local path. And for remote2local
you have to use the local path you opened the file from in ST2. local2remote
needs the original path on disk as it does a os.path.realpath()
...
@mbirth Thanks for the patch. It got me close.
If you're in Windows and your remote server is Mac or linux this is how I got it working:
diff --git a/Xdebug.py b/Xdebug.py
index 5bf9fe8..158c429 100644
--- a/Xdebug.py
+++ b/Xdebug.py
@@ -219,7 +219,17 @@ class XdebugView(object):
self.del_breakpoint(row)
def uri(self):
- return 'file://' + os.path.realpath(self.view.file_name())
+ # XXX: Translate local path to remote path
+ translations = get_project_setting('path_translations') or get_setting('path_translations') or None
+ path_replace = get_project_setting('path_replace') or get_setting('path_replace') or None
+ local_path = os.path.realpath(self.view.file_name())
+ remote_path = local_path.replace(translations['local2remote'][0], translations['local2remote'][1])
+
+ if not path_replace is None:
+ remote_path = remote_path.replace(path_replace['local2remote'][0], path_replace['local2remote'][1])
+
+ sublime.status_message('Xdebug: Path was: ' + local_path + ' and now is: ' + remote_path)
+ return 'file://' + remote_path
def lines(self, data=None):
lines = []
@@ -460,8 +465,13 @@ class XdebugContinueCommand(sublime_plugin.TextCommand):
for child in res.childNodes:
if child.nodeName == 'xdebug:message':
#print '>>>break ' + child.getAttribute('filename') + ':' + child.getAttribute('lineno')
- sublime.status_message('Xdebug: breakpoint')
- xdebug_current = show_file(self.view.window(), child.getAttribute('filename'))
+ sublime.status_message('Xdebug: breakpoint at ' + child.getAttribute('filename') + ':' + child.getAttribute('lineno'))
+ # XXX: Translate remote path to local path
+ translations = get_project_setting('path_translations') or get_setting('path_translations') or None
+ remote_path = child.getAttribute('filename')[7:] # omit "file://"
+ local_path = "file://" + remote_path.replace(translations['remote2local'][0], translations['remote2local'][1])
+ sublime.status_message('Xdebug: breakpoint at local file ' + local_path + ':' + child.getAttribute('lineno'))
+ xdebug_current = show_file(self.view.window(), local_path)
xdebug_current.current(int(child.getAttribute('lineno')))
if (res.getAttribute('status') == 'break'):
And in my project settings, I added this:
{
// ...
"settings":
{
"xdebug":
{
"url": "http://192.168.0.1",
"path_translations":
{
"local2remote": [ "X:\\sites\\example.com\\", "/home/user/share/sites/example.com/" ],
"remote2local": [ "/home/user/share/sites/example.com/", "/X:/sites/example.com/" ]
},
"path_replace":
{
"local2remote": [ "\\", "/" ]
}
}
}
}
Here's a pull request: https://github.com/Kindari/SublimeXdebug/pull/70