• Stars
    star
    700
  • Rank 62,010 (Top 2 %)
  • Language
    Python
  • License
    GNU General Publi...
  • Created over 7 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Trace any Python program, anywhere!

lptrace

lptrace is strace for Python programs. It lets you see in real-time what functions a Python program is running. It's particularly useful to debug weird issues on production.

For example, let's debug a non-trivial program, the Python SimpleHTTPServer. First, let's run the server:

vagrant@precise32:/vagrant$ python -m SimpleHTTPServer 8080 &
[1] 1818
vagrant@precise32:/vagrant$ Serving HTTP on 0.0.0.0 port 8080 ...

Now let's connect lptrace to it:

vagrant@precise32:/vagrant$ sudo python lptrace -p 1818
...
fileno (/usr/lib/python2.7/SocketServer.py:438)
meth (/usr/lib/python2.7/socket.py:223)

fileno (/usr/lib/python2.7/SocketServer.py:438)
meth (/usr/lib/python2.7/socket.py:223)

_handle_request_noblock (/usr/lib/python2.7/SocketServer.py:271)
get_request (/usr/lib/python2.7/SocketServer.py:446)
accept (/usr/lib/python2.7/socket.py:201)
__init__ (/usr/lib/python2.7/socket.py:185)
verify_request (/usr/lib/python2.7/SocketServer.py:296)
process_request (/usr/lib/python2.7/SocketServer.py:304)
finish_request (/usr/lib/python2.7/SocketServer.py:321)
__init__ (/usr/lib/python2.7/SocketServer.py:632)
setup (/usr/lib/python2.7/SocketServer.py:681)
makefile (/usr/lib/python2.7/socket.py:212)
__init__ (/usr/lib/python2.7/socket.py:246)
makefile (/usr/lib/python2.7/socket.py:212)
__init__ (/usr/lib/python2.7/socket.py:246)
handle (/usr/lib/python2.7/BaseHTTPServer.py:336)
handle_one_request (/usr/lib/python2.7/BaseHTTPServer.py:301)
^CReceived Ctrl-C, quitting
vagrant@precise32:/vagrant$

You can see that the server is handling the request in real time! After pressing Ctrl-C, the trace is removed and the program execution resumes normally.

How it works

gdb is an awesome debugger. It lets you attach to any running program, as long as you're root. It also lets you call any C function this program exposes.

What's interesting is that among the C functions the Python interpreter exposes, one function PyRun\_SimpleString, lets you run a single expression of Python code.

We use this function to ask the Python process to read a temporary file lptrace created. This file contains a hook to the sys.settrace function, which allows us to get notified whenever a function is called.

Finally, we need to output the tracing data somewhere. We could do this in the program we're tracing but that wouldn't be very useful. Instead, we write it to a FIFO so that lptrace can display it in its own window.

That's about it. I encourage you to read the source --- it's short and pretty simple!

Running lptrace

lptrace was written to be run on production servers. Because of this, you only need lptrace to run the whole program. You can get lptrace by installing the lptrace PyPI package or simply by downloading the main source file.

Usage

Tracing a Python program

sudo python lptrace -p <process_id>

Getting a pdb prompt inside a Python program

Sometimes it's useful to get a pdb prompt inside a Python program. Note that this requires that the Python program you're attaching to has access to stdin.

sudo python lptrace -p <process_id> -d

Requirements

lptrace requires Python 2.7.x and GDB 7.x. It has been tested on Linux successfully, and it should run on most recent Unices.

Issues

Please open a ticket here

Security

lptrace is a debugging tool. It uses temporary files, so it may be vulnerable to some race conditions. Caveat emptor!

Special Thanks

I'd like to thank the Pyrasite project for coming up with the idea to inject code into a running Python process.

More Repositories

1

kite

(Obsolete, use https://github.com/inboxapp/inbox instead) A modern webmail.
Python
1,075
star
2

mojo

A pure object programming language, inspired by io and smalltalk
C
9
star
3

te

A minimalistic text editor
C
8
star
4

electron-breakpad-sentry

Forward Electron crash reports to Sentry
Ruby
8
star
5

minilibc

a small implementation of the libc, for teaching purposes
6
star
6

cagibi

A personal dropbox service
Python
4
star
7

vagrant-rails

Some scripts to set up a vagrant box for rails development.
Shell
3
star
8

croma

A simple (and dumb) macro processor
C
3
star
9

minival

An online code sandbox built with seccomp and Python
C
3
star
10

cabinet

A python interface to berkeleyDB
Python
3
star
11

config-files

My various config files
Emacs Lisp
2
star
12

fretboard-old

The older, deprecated, ugly, faster version of fretboard
C++
2
star
13

fh

fh is to rss feeds what mh is to mails
Ruby
2
star
14

miniforth

A minimal implementation of forth
C
2
star
15

grabber

An autocompletion for X11 environments
1
star
16

tunnel

A personal proxy
1
star
17

tt

A no-frills task/time tracker
C++
1
star
18

minus

A really, really small wsgi framework
Python
1
star
19

liszt

A web-backed (todo) list manager
Python
1
star
20

needles

Stats about SF
Python
1
star
21

infinity-pools

Browser extensions to hide the Twitter feed after 30 mins a day.
JavaScript
1
star
22

inbox.net

C# bindings to the Inbox api -- Experimental
C#
1
star
23

st

A programming (or whatever) session time manager
C++
1
star
24

Bug_Attack

Classic Tower Defense game (C++ / Qt)
C++
1
star
25

tablature

A tiny elisp script for drawing tablatures
1
star
26

miniwsgi

A tiny tiny wsgi framework
Python
1
star
27

scaletool

A small python/Tk script that displays the notes in a given scale and mode
Python
1
star
28

rfcspot

RFCs for the rest of us
Python
1
star
29

Presentation

"Webapp" for writing keynotes in textile/html
JavaScript
1
star
30

snippets

a repository of code I reuse from project to project
JavaScript
1
star
31

fuzzr

A webapp inspired by the Diceman book
Python
1
star
32

generative-music

Projet de musique gรฉnerative pour l'UV IC07
Python
1
star
33

mgmt

A time-tracking application
1
star