Ticket #212 (closed defect: fixed)

Opened 10 months ago

Last modified 10 months ago

Ctrl-C with threaded shell can cause rare crash

Reported by: marc Assigned to: fperez
Priority: normal Milestone:
Component: ipython Version:
Severity: normal Keywords:
Cc:

Description

Well since you asked about testing ctrl-c, I noticed a small problem with the current implentation which can cause a crash. However you need to have a considerable amount of bad luck to hit it so I didnt report it yesterday (I hit it only once when trying, but maybe for slower systems it is a larger problem).

The problem is in runcode of MtInteractiveShell?, where the CODE_RUN variable is set at the beginning of the function to True. However exception catching is only done properly within the runcode function of InteractiveShell?. A keyboardinterrupt within runcode of MtInteractiveShell? causes a deadlock (lock is not released).

So 100 times a second when this function executes, and just before and after code executes, there is slight chance of hitting this interval.

A possible solution is to move the CODE_RUN lines around the runcode call.

  CODE_RUN=True
  InteractiveShell.runcode(self,code_to_run)
  CODE_RUN=False

However people with really bad luck could still hit the bug during the start and end of the function call, so to prevent that an extra try: except has to be used:

            try:
               CODE_RUN=True
               InteractiveShell.runcode(self,code_to_run)
            except KeyboardInterrupt:
               print "Keyboard interrupted in mainloop"
               while not self.code_queue.empty():
                  self.code_queue.get_nowait()
               break
            finally:
               if(got_lock is True):
                  CODE_RUN = False

When interrupted it also removes the rest of the code queue as a bonus (ctrl-c during the actual executing of the user code does not do this, so this is a bit inconsistent). The 'if(got_lock is True):' condition is there to handle a possible reentrant call of runcode (although I have no idea why anyone would do that).

There is still one possiblility for a crash that I can see (those async exceptions really make it a mess), when someone hits ctrl-c when executing the finally clause. Most of that can be repaired by adding an extra

               if(got_lock is True):
                  CODE_RUN = False

just after InteractiveShell?.runcode(self,code_to_run).

Of course then you still have those people left which manage to hit ctrl-c twice just before both CODE_RUN=False lines ... :)

Change History

02/01/08 01:09:09 changed by fperez

  • status changed from new to closed.
  • resolution set to fixed.

Thanks! These problems had been nagging me for a long time, your contribution is very much appreciated. Closed by r3001.

Note that I added a got_lock assignment which was missing in your suggestions above.

I'd appreciate it if you could test current SVN and let me know how it all behaves for you.

Again, many thanks for helping with this rather thorny code which for a very long time has been quite brittle.