Home > Software design >  uWSGI call randomly injected into Python call stack?
uWSGI call randomly injected into Python call stack?

Time:09-30

I'm trying to get to the bottom of a weird bug (see here) - basically I'm seeing unexpected DB disconnects. To investigate I added a call stack dump to the disconnect code in Django - now I'm more confused than ever...

What I'm seeing in the call stack is a completely unexpected call sequence, e.g.:

...
File "/deployment/v_env/lib/python3.8/site-packages/qrcode/base.py", line 326, in __mod__
  for item, other_item in zip(self, other)]
File "/deployment/v_env/lib/python3.8/site-packages/qrcode/base.py", line 303, in __iter__
  return iter(self.num)
File "/deployment/v_env/lib/python3.8/site-packages/django/http/response.py", line 292, in close
  signals.request_finished.send(sender=self._handler_class)
File "/deployment/v_env/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 180, in send
  return [
...

Here the QR code library I'm using suddenly jumps to HttpResponse.close(). Another:

...
File "/deployment/v_env/lib/python3.8/site-packages/django/db/models/query.py", line 1268, in _insert
  query = sql.InsertQuery(self.model, ignore_conflicts=ignore_conflicts)
File "/deployment/v_env/lib/python3.8/site-packages/django/db/models/sql/subqueries.py", line 141, in __init__
  super().__init__(*args, **kwargs)
File "/deployment/v_env/lib/python3.8/site-packages/django/http/response.py", line 292, in close
  signals.request_finished.send(sender=self._handler_class)
File "/deployment/v_env/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 180, in send
  return [
...

Here some Django DB query code suddenly jumps to HttpResponse.close().

There's no way that this call stack is right - the code immediately above close() simply does not call that code, nor does it call a close() method that may somehow be bound to the wrong object.

Now HttpResponse.close() can be called by uWSGI from the C runtime - the only thing I can figure is that this is happening during the handling of a request, and somehow this is showing up in the call stack.

So my question is, can this is really the case? Does a C call into python really just jump into the call stack like this, or is uWSGI failing to protect the call to Python correctly? I understand the GIL must be acquired before any call to python - maybe that isn't happening. Or maybe traceback.print_stack() doesn't handle calls from C properly?

Any insight apeciated.

CodePudding user response:

Thinking some more, I think this injection into the call stack is correct. How else could it work? The GIL could be obtained at any time, and Python isn’t going to start a new interpreter per call, so it’s got to just run in the current context.

  • Related