How to detect that Python code is being executed through the debugger?

Question:

Is there a simple way to detect, within Python code, that this code is being executed through the Python debugger?

I have a small Python application that uses Java code (thanks to JPype). When I’m debugging the Python part, I’d like the embedded JVM to be passed debug options too.

Asked By: Stéphane Bonniez

||

Answers:

From taking a quick look at the pdb docs and source code, it doesn’t look like there is a built in way to do this. I suggest that you set an environment variable that indicates debugging is in progress and have your application respond to that.

$ USING_PDB=1 pdb yourprog.py

Then in yourprog.py:

import os
if os.environ.get('USING_PDB'):
    # debugging actions
    pass
Answered By: dowski

Python debuggers (as well as profilers and coverage tools) use the sys.settrace function (in the sys module) to register a callback that gets called when interesting events happen.

If you’re using Python 2.6, you can call sys.gettrace() to get the current trace callback function. If it’s not None then you can assume you should be passing debug parameters to the JVM.

It’s not clear how you could do this pre 2.6.

Answered By: babbageclunk

You can try to peek into your stacktrace.

https://docs.python.org/library/inspect.html#the-interpreter-stack

when you try this in a debugger session:

import inspect
inspect.getouterframes(inspect.currentframe()

you will get a list of framerecords and can peek for any frames that refer to the pdb file.

Answered By: do3cc

A solution working with Python 2.4 (it should work with any version superior to 2.1) and Pydev:

import inspect

def isdebugging():
  for frame in inspect.stack():
    if frame[1].endswith("pydevd.py"):
      return True
  return False

The same should work with pdb by simply replacing pydevd.py with pdb.py. As do3cc suggested, it tries to find the debugger within the stack of the caller.

Useful links:

Answered By: Stéphane Bonniez

If you’re using Pydev, you can detect it in such way:

import sys
if 'pydevd' in sys.modules: 
    print "Debugger"
else:
    print "commandline"
Answered By: Mvoicem

Another way to do it hinges on how your python interpreter is started. It requires you start Python using -O for production and with no -O for debugging. So it does require an external discipline that might be hard to maintain .. but then again it might fit your processes perfectly.

From the python docs (see “Built-in Constants” here or here):

__debug__
This constant is true if Python was not started with an -O option.

Usage would be something like:

if __debug__:
    print 'Python started without optimization'
Answered By: Travelling Man

I found a cleaner way to do it,

Just add the following line in your manage.py

#!/usr/bin/env python
import os
import sys

if __debug__:
    sys.path.append('/path/to/views.py')


if __name__ == "__main__":
    ....

Then it would automatically add it when you are debugging.

Answered By: user491135

Other alternative if you’re using Pydev that also works in a multithreading is:

try:
    import pydevd
    DEBUGGING = True
except ImportError:
    DEBUGGING = False
Answered By: jordeu

Since the original question doesn’t specifically call out Python2 – This is to confirm @babbageclunk’s suggested usage of sys also works in python3:

from sys import gettrace as sys_gettrace

DEBUG = sys_gettrace() is not None
print("debugger? %s" % DEBUG)
Answered By: Adam Smooch

In my perllib, I use this check:

if 'pdb' in sys.modules:
    # We are being debugged

It assumes the user doesn’t otherwise import pdb

Answered By: snoopyjc
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.