Skip to content
This repository has been archived by the owner on Dec 9, 2021. It is now read-only.

ValueError: signal only works in main thread #10

Closed
jayvdb opened this issue Jun 8, 2020 · 3 comments
Closed

ValueError: signal only works in main thread #10

jayvdb opened this issue Jun 8, 2020 · 3 comments

Comments

@jayvdb
Copy link

jayvdb commented Jun 8, 2020

Running Django 3.0 on Python 3.8, using python ./manage.py runserver

  File "/usr/lib/python3.8/site-packages/debug_toolbar/panels/__init__.py", line 181, in process_request
    return self.get_response(request)
  File "/usr/lib/python3.8/site-packages/djdt_flamegraph/djdt_flamegraph.py", line 63, in process_request
    self.sampler.start()
  File "/usr/lib/python3.8/site-packages/djdt_flamegraph/djdt_flamegraph.py", line 90, in start
    signal.signal(signal.SIGALRM, self._sample)
  File "/usr/lib64/python3.8/signal.py", line 47, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread
@blopker
Copy link
Owner

blopker commented Jun 8, 2020

Hello, this issue is discussed in the README.

@blopker blopker closed this as completed Jun 8, 2020
@jayvdb
Copy link
Author

jayvdb commented Jun 9, 2020

Thanks. python ./manage.py runserver --nothreading --noreload worked. Would be nice if it detected this and de-activated itself. It might even be able to be detected in settings.py to avoid listing it in INSTALLED_APPS.

Now I run into #9

@jayvdb
Copy link
Author

jayvdb commented Jun 9, 2020

I am able to get it to be a bit less problematic with the following; is that worth submitting as-is, maybe with a warning emitted on the console?

 class Sampler(object):
     def __init__(self, interval=0.001):
         self.stack_counts = collections.defaultdict(int)
         self.interval = interval
+        self.disabled = False
 
     def _sample(self, signum, frame):
         stack = []
@@ -87,8 +87,13 @@
         return '\n'.join('%s %d' % (key, value) for key, value in sorted(self.stack_counts.items()))
 
     def start(self):
-        signal.signal(signal.SIGALRM, self._sample)
-        signal.setitimer(signal.ITIMER_REAL, self.interval, self.interval)
+        try:
+            signal.signal(signal.SIGALRM, self._sample)
+            signal.setitimer(signal.ITIMER_REAL, self.interval, self.interval)
+        except ValueError:
+            self.disabled = True
 
     def stop(self):
+        if self.disabled:
+            return
         signal.setitimer(signal.ITIMER_REAL, 0, 0)

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

No branches or pull requests

2 participants