Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set_trace not working inside django #7

Open
Grokzen opened this issue Apr 28, 2015 · 8 comments
Open

set_trace not working inside django #7

Grokzen opened this issue Apr 28, 2015 · 8 comments

Comments

@Grokzen
Copy link

Grokzen commented Apr 28, 2015

I got this stacktrace when i was testing ptpdb inside django with set_trace()

Environment:

Request Method: POST
Request URL: http://localhost:8080/

Django Version: 1.6.1
Python Version: 2.7.6
Installed Applications:
('suit',
 'django.contrib.auth',
 'django.contrib.admin',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'celery',
 'south',
 'cmdb',
 'debug_toolbar')
Installed Middleware:
('django.middleware.csrf.CsrfViewMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware')


Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in wrapper
  432.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  99.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
  52.         response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner
  198.             return view(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper
  29.             return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  99.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func
  25.                 return func(self, *args2, **kwargs2)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in changelist_view
  1347.                 response = self.response_action(request, queryset=cl.get_queryset(request))
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in response_action
  1084.             response = func(self, request, queryset)
File "/srv/support/utils.py" in wrapper
  52.             return action(modeladmin, request, queryset, **kwargs)
File "/srv/support/unit/admin.py" in action_disable_service_mode
  291.                 unit_names.append(unit.name)
File "/srv/support/unit/admin.py" in action_disable_service_mode
  291.                 unit_names.append(unit.name)
File "/usr/lib/python2.7/bdb.py" in trace_dispatch
  49.             return self.dispatch_line(frame)
File "/usr/lib/python2.7/bdb.py" in dispatch_line
  67.             self.user_line(frame)
File "/usr/lib/python2.7/pdb.py" in user_line
  158.             self.interaction(frame, None)
File "/usr/lib/python2.7/pdb.py" in interaction
  210.         self.cmdloop()
File "/usr/local/lib/python2.7/dist-packages/ptpdb/__init__.py" in cmdloop
  160.                     line = self._get_input()
File "/usr/local/lib/python2.7/dist-packages/ptpdb/__init__.py" in _get_input
  223.             return self.cli.cli.read_input().text
File "/usr/local/lib/python2.7/dist-packages/prompt_toolkit/interface.py" in read_input
  321.                 self.eventloop.run(self.stdin, self.create_eventloop_callbacks())
File "/usr/local/lib/python2.7/dist-packages/prompt_toolkit/eventloop/posix.py" in run
  57.         with call_on_sigwinch(received_winch):
File "/usr/local/lib/python2.7/dist-packages/prompt_toolkit/eventloop/posix.py" in __enter__
  155.         self.previous_callback = signal.signal(signal.SIGWINCH, lambda *a: self.callback())

Exception Type: ValueError at /unit/
Exception Value: signal only works in main thread
@jonathanslenders
Copy link
Owner

Try to run Django in single threaded mode. (i think it's with the -s option.)

@joequery
Copy link

joequery commented May 5, 2015

The single threaded option is --nothreading, but that doesn't resolve the issue for me. I might poke around if I can find some time.

@Grokzen
Copy link
Author

Grokzen commented Jun 11, 2015

Found the same thing happening inside a Flask application

  File "/usr/lib/python2.7/bdb.py", line 49, in trace_dispatch
    return self.dispatch_line(frame)
  File "/usr/lib/python2.7/bdb.py", line 67, in dispatch_line
    self.user_line(frame)
  File "/usr/lib/python2.7/pdb.py", line 158, in user_line
    self.interaction(frame, None)
  File "/usr/lib/python2.7/pdb.py", line 210, in interaction
    self.cmdloop()
  File "/home/grok/.virtualenvs/foo/lib/python2.7/site-packages/ptpdb/__init__.py", line 160, in cmdloop
    line = self._get_input()
  File "/home/grok/.virtualenvs/foo/lib/python2.7/site-packages/ptpdb/__init__.py", line 223, in _get_input
    return self.cli.cli.read_input().text
  File "/home/grok/.virtualenvs/foo/lib/python2.7/site-packages/prompt_toolkit/interface.py", line 321, in read_input
    self.eventloop.run(self.stdin, self.create_eventloop_callbacks())
  File "/home/grok/.virtualenvs/foo/lib/python2.7/site-packages/prompt_toolkit/eventloop/posix.py", line 57, in run
    with call_on_sigwinch(received_winch):
  File "/home/grok/.virtualenvs/foo/lib/python2.7/site-packages/prompt_toolkit/eventloop/posix.py", line 155, in __enter__
    self.previous_callback = signal.signal(signal.SIGWINCH, lambda *a: self.callback())
ValueError: signal only works in main thread

@morenoh149
Copy link

found the same thing a year later. set_trace() causes a No exception message supplied error when placed inside a View's get_queryset function. At least using the django rest framework view filtering

@jonathanslenders
Copy link
Owner

Hi @morenoh149,
Does it work with the --nothreading option? Does it still give the same error message? Does the normal pdb work?

@arshbot
Copy link

arshbot commented Mar 7, 2019

I know this is an old issue, but I can confirm this works in django

@Grokzen
Copy link
Author

Grokzen commented Mar 8, 2019

@arshbot I have not tried this for a long time now, i will give it another shot and see if it is resolved or not.

@x-yuri
Copy link

x-yuri commented Jul 6, 2019

I believe I've run into the issue with pdb and Django. When I set a breakpoint here. It stops a couple of times before Django boots (before it starts a Django process, and performs checks). But when I do a request (http://localhost/admin/something/add/), it fails with the error as in the original post. Django 2.0.2, Python 3.7.3.

The thing about pdb is that if you stop in the main thread before stopping in a non-main thread, in the latter case pdb would fail:

1.py:

#!/usr/bin/env python
import threading

def thread():
    print('-- thread', threading.get_ident(), threading.enumerate(), threading.main_thread())
    import pdb; pdb.set_trace()

print('-- main', threading.get_ident(), threading.enumerate(), threading.main_thread())
# import pdb; pdb.set_trace()   # (1)
# import pdb; pdb.Pdb(nosigint=True).set_trace()   # (2)
t = threading.Thread(target=thread)
t.start()
t.join()
print('-- main', threading.get_ident(), threading.enumerate(), threading.main_thread())
import pdb; pdb.set_trace()
$ ./1.py
-- main 139987190187648 [<_MainThread(MainThread, started 139987190187648)>] <_MainThread(MainThread, started 139987190187648)>
-- thread 139987184482048 [<_MainThread(MainThread, started 139987190187648)>, <Thread(Thread-1, started 139987184482048)>] <_MainThread(MainThread, started 139987190187648)>
--Return--
> /home/yuri/_/2/1.py(6)thread()->None
-> import pdb; pdb.set_trace()
(Pdb) c
-- main 139987190187648 [<_MainThread(MainThread, started 139987190187648)>] <_MainThread(MainThread, started 139987190187648)>
--Return--
> /home/yuri/_/2/1.py(15)<module>()->None
-> import pdb; pdb.set_trace()
(Pdb) c

With line (1) uncommented:

$ ./1.py
-- main 140351081735808 [<_MainThread(MainThread, started 140351081735808)>] <_MainThread(MainThread, started 140351081735808)>
> /home/yuri/_/2/1.py(11)<module>()
-> t = threading.Thread(target=thread)
(Pdb) c
-- thread 140351074244352 [<_MainThread(MainThread, started 140351081735808)>, <Thread(Thread-1, started 140351074244352)>] <_MainThread(MainThread, started 140351081735808)>
--Return--
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "./1.py", line 6, in thread
    import pdb; pdb.set_trace()
  File "/usr/lib/python3.7/bdb.py", line 92, in trace_dispatch
    return self.dispatch_return(frame, arg)
  File "/usr/lib/python3.7/bdb.py", line 151, in dispatch_return
    self.user_return(frame, arg)
  File "/usr/lib/python3.7/pdb.py", line 293, in user_return
    self.interaction(frame, None)
  File "/usr/lib/python3.7/pdb.py", line 344, in interaction
    signal.signal(signal.SIGINT, Pdb._previous_sigint_handler)
  File "/usr/lib/python3.7/signal.py", line 47, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread

-- main 140351081735808 [<_MainThread(MainThread, started 140351081735808)>] <_MainThread(MainThread, started 140351081735808)>
--Return--
> /home/yuri/_/2/1.py(11)<module>()->None
-> t = threading.Thread(target=thread)
(Pdb) c

One solution is to not create threads. There are 2 sources of threads in Django:

  1. autoreload. The outer process (django-admin) starts a Django process in an infinite loop (while true; do fork; done). The Django process starts Django in a non-main thread, the main thread waits for changes and exits. So most of the time pdb works in a non-main thread.
  2. threading (using separate thread to handle requests).

As such, the solution is ./manage.py runserver --nothreading --noreload.

The other solution is to not make it stop in the main thread before a non-main one. The quick and dirty way is:

aaa = False
class ...:
    def ...:
        global aaa
        aaa += 1
        if aaa > 2:   # the exact value depends
            import pdb; pdb.set_trace()

The third option is: import pdb; pdb.Pdb(nosigint=True).set_trace().

Supposedly related bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants