41

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.

10 Answers 10

30

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Though it seems to be a cleaner way, it does not work in pdb if there is no breakpoint set.
Hmm, you're right - it must be an optimisation the debugger uses. That said, most of the time when you're running in the debugger you'll have a breakpoint set.
@babbageclunk, not if you're just trying to look at the environment when a program crashes (my most common way of doing things: python -m pdb <program>).
You may want to check for alternate trace users like pytest-cov... if it is truly a debugger, it should be of a type with pydevd in the name.
17

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

try:
    import pydevd
    DEBUGGING = True
except ImportError:
    DEBUGGING = False

1 Comment

Except after pip install pydevd ...
15

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:

1 Comment

One liner: any(True for frame in inspect.stack() if frame[1].endswith('pydevd.py'))
10

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'

2 Comments

This is not truly an answer to the question - you get __debug__ even when not running under a debugger (but have not used the -O "optimise" flag).
Indeed, hence the “requires an external discipline” caveat.
7

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

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

2 Comments

Similarly, if 'pdb' in sys.modules: ... if using pdb.
I discovered this technique isn't viable in some circumstances, such as when tests are run with pytest.
2

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)

5 Comments

Unfortunately, this only works if you are using "step". If you use "continue" then gettrace() returns None
I'm familiar with the VSCode python debugger - can you elaborate on how you're launching the debugger with step or continue options?
python -m pdb Program.py - I'd like to know if the user did the "-m pdb". I wound up checking if "pdb" in sys.modules.
Would you like to share that in your own answer? I'll add my assumptions to my own post.
This worked for me even when running the cProfile profiler for my PyQt app, unlike other answers. Python 3.12.
2

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

1 Comment

This didn't work for me when running my PyQt app via cProfile for profiling. This other answer using from sys import gettrace as sys_gettrace; sys_gettrace() is not None worked.
1

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

Comments

1

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.

Comments

-1

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.

1 Comment

No. That just depends on whether you ran python with the -o flag.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.