google / pyringe

Debugger capable of attaching to and injecting code into python processes.
Other
1.63k stars 78 forks source link

Pyringe falls over if something (GdbProxy?) reports a non-numeric version #17

Closed marcintustin closed 10 years ago

marcintustin commented 10 years ago
$ python -m pyringe
Pyringe (Python 2.7.3) on linux2
For a list of debugger commands, try "help()". (python's help is available as pyhelp.)
==> pid:[None] #threads:[0] current thread:[None]
>>> attach(17014)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/repl.py", line 157, in Attach
    self.inferior.Reinit(pid)
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/inferior.py", line 464, in Reinit
    self.__init__(pid, auto_symfile_loading)
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/inferior.py", line 436, in __init__
    self.StartGdb()
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/inferior.py", line 482, in StartGdb
    self._gdb = GdbProxy()
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/inferior.py", line 133, in __init__
    gdb_version = GdbProxy.Version()
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/inferior.py", line 244, in Version
    major = int(version[0])
ValueError: invalid literal for int() with base 10: 'Red'
Traceback (most recent call last):
  File "/opt/python/current/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/opt/python/current/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/__main__.py", line 19, in <module>
    pyringe.interact()
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/__init__.py", line 25, in interact
    DebuggingConsole().interact()
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/repl.py", line 208, in interact
    prompt = self.StatusLine() + '\n' + sys.ps1
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/repl.py", line 133, in StatusLine
    self.inferior.StartGdb()
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/inferior.py", line 482, in StartGdb
    self._gdb = GdbProxy()
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/inferior.py", line 133, in __init__
    gdb_version = GdbProxy.Version()
  File "/home/dtdev/dtenv/lib/python2.7/site-packages/pyringe/inferior.py", line 244, in Version
    major = int(version[0])
ValueError: invalid literal for int() with base 10: 'Red'
(dtenv)[ dtdev@dtdev-centos ~ ]
$ 
TehMillhouse commented 10 years ago

That's frustrating. The reason why this is happening is because pyringe is attempting a version check on gdb itself before deciding which command line flags are safe to use, but there's no real way to ask gdb for its version. [1]

It'd be great to know what it tried to parse there. I'm guessing the 'Red' is part of Red Hat (Is this RHEL? Nvm, didn't see the centos hostname)...

Could you post the output of gdb --version on the machine where this failed? In the meantime, I'll make sure that exceptions raised when trying this check will be properly handled.


[1] - You'd think gdb --version does the right thing, but that prints out the complete welcome text, which includes copying info and whatever braindead version format the package maintainer of your distro thought was a useful at gdb compile time; This could be GNU gdb (GDB) 7.4.1 or it could be GNU gdb (GDB) 7.6.2 (Debian 7.6.2-1) or GNU gdb (GDB) 7.6.2-Screw-Numeric-versions!. There simply is no way to simply find out which version of gdb is installed, so we're stuck with trying to make the heuristics of what version numbers may look like as good as possible.

TehMillhouse commented 10 years ago

I've made the version check more flexible in f4e0ba6a867e4e659826fb63e6e1f29e3f10b470. I'd appreciate if you could try it out and see if this fixes the specific issue you're seeing. (I'd also still like to see what gdb's version text looks like on centos, just to make sure the new approach won't break anytime soon)

marcintustin commented 10 years ago

Output. I'll test the new version in a moment.

$ gdb --version
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
marcintustin commented 10 years ago

That's running on centos 2.6.32-279.2.1.el6.x86_64

marcintustin commented 10 years ago

Here's the output using the commit posted. It works! (In the sense that it doesn't fall over, and would almost certainly work if I had a recent gdb):

$ python -m pyringe
Pyringe (Python 2.7.3) on linux2
For a list of debugger commands, try "help()". (python's help is available as pyhelp.)
==> pid:[None] #threads:[0] current thread:[None]
>>> attach(10795)
WARNING:root:Your version of gdb may be unsupported (< 7.4), proceed with caution.
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "pyringe/repl.py", line 157, in Attach
    self.inferior.Reinit(pid)
  File "pyringe/inferior.py", line 478, in Reinit
    self.__init__(pid, auto_symfile_loading)
  File "pyringe/inferior.py", line 450, in __init__
    self.StartGdb()
  File "pyringe/inferior.py", line 497, in StartGdb
    self._gdb.Attach(self.position)
  File "pyringe/inferior.py", line 197, in <lambda>
    return lambda *args, **kwargs: self._Execute(name, *args, **kwargs)
  File "pyringe/inferior.py", line 337, in _Execute
    result_string = self._Recv(timeout)
  File "pyringe/inferior.py", line 424, in _Recv
    raise TimeoutError()
TimeoutError
==> pid:[10795] #threads:[0] current thread:[None]