Terminating an embedded interpreter

Discussion in 'Python' started by Ulrich Eckhardt, Sep 12, 2011.

  1. Hi!

    I'm trying to provide some scripting capabilities to a program. For that,
    I'm embedding a Python interpreter, running a script in a separate thread to
    decouple it from the UI.

    Now, how should I handle rogue scripts? For example, when a script hangs in
    an endless loop, how do I signal the Python interpreter to shut down? In
    other words, I want to trigger something like what Control-C does in a
    "normal" environment.

    In case it matters, the OS here is MS Windows.

    Thanks!

    Uli

    --
    Domino Laser GmbH
    Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
    Ulrich Eckhardt, Sep 12, 2011
    #1
    1. Advertising

  2. On Mon, Sep 12, 2011 at 8:00 PM, Ulrich Eckhardt
    <> wrote:
    > Now, how should I handle rogue scripts? For example, when a script hangs in
    > an endless loop, how do I signal the Python interpreter to shut down? In
    > other words, I want to trigger something like what Control-C does in a
    > "normal" environment.
    >


    You can use PyErr_SetInterrupt to raise KeyboardInterrupt, but it can
    be caught by the script. There's no guaranteed way, short of killing
    the process.

    ChrisA
    Chris Angelico, Sep 12, 2011
    #2
    1. Advertising

  3. Ulrich Eckhardt wrote:

    > Hi!
    >
    > I'm trying to provide some scripting capabilities to a program. For that,
    > I'm embedding a Python interpreter, running a script in a separate thread
    > to decouple it from the UI.
    >
    > Now, how should I handle rogue scripts? For example, when a script hangs
    > in an endless loop, how do I signal the Python interpreter to shut down?


    If you are using threads, they all run within the same Python process. You
    can ask a thread to shut down, but you can't force it to from the outside.
    If the thread runs a script that goes rogue, the script may never return
    control to the thread long enough for it to respond to your request.

    The main UI loop can still kill itself, and take all the threads with it, by
    calling sys.exit. Or if you really need to, os.abort or os._exit can be
    used for immediate "terminate yourself NOW!!!" commands. (But read the docs
    for them first.)

    A better way may be to run the script in a separate process. You can kill
    the process the same way you would any other rogue process: by sending it a
    signal. See the os and subprocess modules.

    But Python's sandboxing abilities are not great. If you really fear rogue,
    or malicious, scripts, perhaps Python is not the right language for this
    task. Otherwise, just trust the script to be sane.



    --
    Steven
    Steven D'Aprano, Sep 12, 2011
    #3
  4. Steven D'Aprano wrote:
    > Ulrich Eckhardt wrote:
    >> I'm trying to provide some scripting capabilities to a program. For that,
    >> I'm embedding a Python interpreter, running a script in a separate thread
    >> to decouple it from the UI.
    >>
    >> Now, how should I handle rogue scripts? For example, when a script hangs
    >> in an endless loop, how do I signal the Python interpreter to shut down?

    >
    > If you are using threads, they all run within the same Python process. You
    > can ask a thread to shut down, but you can't force it to from the outside.
    > If the thread runs a script that goes rogue, the script may never return
    > control to the thread long enough for it to respond to your request.


    Sorry, I described badly what I was doing. The program itself is written in
    C++ and I'm running the Python interpreter in a thread separate to the UI,
    just in order to not hang the UI if anything in the interpreter blocks for
    extended amounts of time. I know that a Python thread is not a "system"
    thread but handled and scheduled internally by Python.


    > The main UI loop can still kill itself, and take all the threads with it,
    > by calling sys.exit. Or if you really need to, os.abort or os._exit can be
    > used for immediate "terminate yourself NOW!!!" commands. (But read the
    > docs for them first.)


    > A better way may be to run the script in a separate process. You can kill
    > the process the same way you would any other rogue process: by sending it
    > a signal. See the os and subprocess modules.


    Yes, a separate process would be much cleaner, but it would complicate
    communication back to the parent process. The Python code is supposed to
    call a few functions I exported. I'd have to tunnel these calls through
    stdin/stdout/stderr and that is more than what I'm willing to do at the
    moment. It does sound intriguing though, since that would allow me to embed
    any scripting language, not just Python.


    > But Python's sandboxing abilities are not great. If you really fear rogue,
    > or malicious, scripts, perhaps Python is not the right language for this
    > task. Otherwise, just trust the script to be sane.


    I'm not fearing malicious scripts. I'm also not concerned about rare hangs
    since this in an internal tool. In this case, I'd take a simple 99% solution
    over a complex 100% solution.


    Thank you for your thoughts, Steven!

    Uli

    --
    Domino Laser GmbH
    Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
    Ulrich Eckhardt, Sep 12, 2011
    #4
  5. Chris Angelico wrote:
    > You can use PyErr_SetInterrupt to raise KeyboardInterrupt


    This sounds useful. Just to make sure, this would be called from a different
    thread than the one running the Python script, is that still OK?

    > , but it can be caught by the script. There's no guaranteed way,
    > short of killing the process.


    This will do for my plans, I'm not trying to defend against anything
    malicious.


    Thanks you!

    Uli


    --
    Domino Laser GmbH
    Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
    Ulrich Eckhardt, Sep 12, 2011
    #5
  6. On Mon, Sep 12, 2011 at 10:05 PM, Ulrich Eckhardt
    <> wrote:
    > Chris Angelico wrote:
    >> You can use PyErr_SetInterrupt to raise KeyboardInterrupt

    >
    > This sounds useful. Just to make sure, this would be called from a different
    > thread than the one running the Python script, is that still OK?
    >
    >> , but it can be caught by the script. There's no guaranteed way,
    >> short of killing the process.

    >
    > This will do for my plans, I'm not trying to defend against anything
    > malicious.


    Yes, that would be what you want then. The main thing to take care of
    is a blanket 'except' that doesn't specify what it's accepting - it'll
    snarf the KeyboardInterrupt and carry on its merry way.

    ChrisA
    Chris Angelico, Sep 12, 2011
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tim Stanka
    Replies:
    0
    Views:
    308
    Tim Stanka
    Jul 19, 2004
  2. Replies:
    3
    Views:
    379
    Jeff Shannon
    Oct 21, 2004
  3. Charlie DeTar

    embedded python and interpreter threads

    Charlie DeTar, Dec 7, 2004, in forum: Python
    Replies:
    2
    Views:
    647
    Charlie DeTar
    Dec 7, 2004
  4. Peter Newman
    Replies:
    1
    Views:
    432
  5. Replies:
    3
    Views:
    748
    Ziga Seilnacht
    Jan 3, 2007
Loading...

Share This Page