[lldb-dev] Saving and restoring STDIN in the ScriptInterpreter

Pavel Labath via lldb-dev lldb-dev at lists.llvm.org
Tue Apr 7 00:15:37 PDT 2020


Hi Davide,

I believe your guess about background processes is correct. I think that
the lldb process is stopped (or is continually getting stopped and
restarted) by SIGTTOU.

====
Macro: int SIGTTOU

    This is similar to SIGTTIN, but is generated when a process in a
background job attempts to write to the terminal or ***set its modes***.
Again, the default action is to stop the process. SIGTTOU is only
generated for an attempt to write to the terminal if the TOSTOP output
mode is set; see Output Modes.
====

Saving/restoring tty state before/after entering the python interpreter
does not sound like an unreasonable thing to do. However, I do see two
problems with this code:
- it unconditionally uses STDIN_FILENO -- it should use
SBDebugger::GetInputFileHandle (or equivalent) instead
- it has no test and it's impossible to track down why it exactly exists
and whether is really needed

With that in mind, I don't have a problem with deleting this code (and
later readding it properly, if needed) -- I might even say it's a good
idea. I cannot guarantee this will solve your problem completely, since
any other operation which will attempt to access stdin will trigger the
same problem. However, this, in combination with
SBDebugger::SetInputFileHandle(/dev/null) should in theory be sufficient
since nothing should be accessing the process stdin.

That said, if you just want to make your creduce script work,
redirecting stdin to /dev/null (lldb ... </dev/null) should be enough to
work around this.

pl

On 07/04/2020 02:42, Davide Italiano wrote:
> Hi Pavel, Jonas,
> 
> I was trying to reduce a bug through c-reduce, so I decided to write a
> SBAPI script to make it easier.
> I did find out, that after the first iteration, the reduction gets stuck
> forever.
> I sampled the process and I saw the following (trimmed for readability).
> 
> Call graph:
> […]
>                                                             8455 lldb_private::CommandInterpreter::GetScriptInterpreter(bool)  (in _lldb.so) + 84  [0x111aff826]
>                                                               8455 lldb_private::PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage, lldb_private::CommandInterpreter&)  (in _lldb.so) + 99  [0x111a1efcf]
>                                                                 8455 lldb_private::ScriptInterpreterPython::CreateInstance(lldb_private::CommandInterpreter&)  (in _lldb.so) + 26  [0x111d128f4]
>                                                                   8455 std::__1::shared_ptr<lldb_private::ScriptInterpreterPython> std::__1::shared_ptr<lldb_private::ScriptInterpreterPython>::make_shared<lldb_private::CommandInterpreter&>(lldb_private::CommandInterpreter&&&)  (in _lldb.so) + 72  [0x111d1b976]
>                                                                     8455 lldb_private::ScriptInterpreterPython::ScriptInterpreterPython(lldb_private::CommandInterpreter&)  (in _lldb.so) + 353  [0x111d11ff3]
>                                                                       8455 lldb_private::ScriptInterpreterPython::InitializePrivate()  (in _lldb.so) + 494  [0x111d12594]
>                                                                         8455 (anonymous namespace)::InitializePythonRAII::~InitializePythonRAII()  (in _lldb.so) + 146  [0x111d1b446]
>                                                                           8455 lldb_private::TerminalState::Restore() const  (in _lldb.so) + 74  [0x111ac8268]
>                                                                             8455 tcsetattr  (in libsystem_c.dylib) + 110  [0x7fff7b95b585]
>                                                                               8455 ioctl  (in libsystem_kernel.dylib) + 151  [0x7fff7ba19b44]
>                                                                                 8455 __ioctl  (in libsystem_kernel.dylib) + 10  [0x7fff7ba19b5a]
> 
> 
> It looks like lldb gets stuck forever in `tcsetattr()`, and there are no
> other threads waiting so it’s not entirely obvious to me why it’s
> waiting there.
> I was never able to reproduce this with an interactive session, I
> suspect this is somehow related to the fact that c-reduce spawns a
> thread in the background, hence it doesn’t have a TTY associated.
> I looked at the code that does this, and I wasn’t really able to find a
> reason why we need to do this work. Jim thinks it might have been needed
> historically.
> `git blame` doesn’t really help that much either. If I remove the code,
> everything still passes and it’s functional, but before moving forward
> with this I would like to collect your opinions.
> 
> $ git diff
> diff --git
> a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
> b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
> index ee94a183e0d..c53b3bd0fb6 100644
> ---
> a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
> +++
> b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
> @@ -224,10 +224,6 @@ struct InitializePythonRAII {
>  public:
>    InitializePythonRAII()
>        : m_gil_state(PyGILState_UNLOCKED),
> m_was_already_initialized(false) {
> -    // Python will muck with STDIN terminal state, so save off any
> current TTY
> -    // settings so we can restore them.
> -    m_stdin_tty_state.Save(STDIN_FILENO, false);
> -
>      InitializePythonHome();
> 
>  #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
> @@ -271,8 +267,6 @@ public:
>        // We initialized the threads in this function, just unlock the GIL.
>        PyEval_SaveThread();
>      }
> -
> -    m_stdin_tty_state.Restore();
>    }
> 
>  private:



More information about the lldb-dev mailing list