When LLDB receives a SIGINT while running the embedded Python REPL it
currently just crashes in ScriptInterpreterPythonImpl::Interrupt with an
error such as the one below:
Fatal Python error: PyThreadState_Get: the function must be called
with the GIL held, but the GIL is released (the current Python thread
state is NULL)
The faulty code that causes this error is this part of
ScriptInterpreterPythonImpl::Interrupt:
PyThreadState *state = PyThreadState_GET();
if (!state)
state = GetThreadState();
if (state) {
long tid = state->thread_id;
PyThreadState_Swap(state);
int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
The obvious fix I tried is to just acquire the GIL before this code is
running which fixes the crash but the KeyboardInterrupt we want to raise
immediately is actually just queued and would only be raised once the
next line of input has been parsed (which e.g. won't interrupt Python
code that is currently waiting on a timer or IO from what I can see).
Also none of the functions we call here is marked as safe to be called
from a signal handler from what I can see, so we might still end up
crashing here with some bad timing.
Python 3.2 introduced PyErr_SetInterrupt to solve this and the function
takes care of all the details and avoids doing anything that isn't safe
to do inside a signal handler. The only thing we need to do is to
manually setup our own fake SIGINT handler that behaves the same way as
the standalone Python REPL signal handler (which raises a
KeyboardInterrupt).
From what I understand the old code used to work with Python 2 so I kept
the old code around until we officially drop support for Python 2.
There is a small gap here with Python 3.0->3.1 where we might still be
crashing, but those versions have reached their EOL more than a decade
ago so I think we don't need to bother about them.
Differential revision: https://reviews.llvm.org/D104886
When LLDB receives a SIGINT while running the embedded Python REPL it currently
just crashes in `ScriptInterpreterPythonImpl::Interrupt` with an error such as
the one below:
```
Fatal Python error: PyThreadState_Get: the function must be called with the GIL
held, but the GIL is released (the current Python thread state is NULL)
```
The faulty code that causes this error is this part of `ScriptInterpreterPythonImpl::Interrupt`:
```
PyThreadState *state = PyThreadState_GET();
if (!state)
state = GetThreadState();
if (state) {
long tid = state->thread_id;
PyThreadState_Swap(state);
int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
```
The obvious fix I tried is to just acquire the GIL before this code is running
which fixes the crash but the `KeyboardInterrupt` we want to raise immediately
is actually just queued and would only be raised once the next line of input has
been parsed (which e.g. won't interrupt Python code that is currently waiting on
a timer or IO from what I can see). Also none of the functions we call here is
marked as safe to be called from a signal handler from what I can see, so we
might still end up crashing here with some bad timing.
Python 3.2 introduced `PyErr_SetInterrupt` to solve this and the function takes
care of all the details and avoids doing anything that isn't safe to do inside a
signal handler. The only thing we need to do is to manually setup our own fake
SIGINT handler that behaves the same way as the standalone Python REPL signal
handler (which raises a KeyboardInterrupt).
From what I understand the old code used to work with Python 2 so I kept the old
code around until we officially drop support for Python 2.
There is a small gap here with Python 3.0->3.1 where we might still be crashing,
but those versions have reached their EOL more than a decade ago so I think we
don't need to bother about them.
Reviewed By: JDevlieghere
Differential Revision: https://reviews.llvm.org/D104886
When I run a lldb command that uses filename completion, if I enter a string
that is not only a filename but also a string with a non-file name string added,
such as "./" that is relative path string , it will crash as soon as I press the
[Tab] key. For example, debugging an executable file named "hello" that is
compiled from a file named "hello.c" , and I’ll put a breakpoint on line 3 of
hello.c.
```
$ lldb ./hello
(lldb) breakpoint set --file hello.c --line 3
```
This is not a problem, but if I set "--file ./hello." and then press [Tab] key
to complete file name, lldb crashes.
```
$ lldb ./hello
(lldb) breakpoint set --file ./hello.terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr: __pos (which is 8) > this->size() (which is 7)
```
The crash was caused because substr() (in lldb/source/Host/common/Editline.cpp)
cut out string which size is user's input string from the completion string.
I modified the code that erase the user's intput string from current line and
then add the completion string.
Differential Revision: https://reviews.llvm.org/D108817
Following tests fail on Arm/AArch64 randomly with timeouts:
TestMultilineNavigation.py
TestBatchMode.py
TestUnicode.py
TestGdbRemote_vContThreads.py
I am marking them as skipped until we find a away make to pass reliably.
Following LLDB tests fail randomly on LLDB Arm/AArch64 Linux buildbots.
We still not have a reliable solution for these tests to pass
consistently. I am marking them skipped for now.
TestBreakpointCallbackCommandSource.py
TestIOHandlerResize.py
TestEditline.py
TestGuiViewLarge.py
TestGuiExpandThreadsTree.py
TestGuiBreakpoints.py
Following tests have been failing randomly on LLDB Arm and AArch64 Linux
builtbots:
TestMultilineNavigation.py
TestMultilineCompletion.py
TestIOHandlerCompletion.py
TestGuiBasic.py
I have increased allocated CPU resources to these bots but it has not
improved situation to an acceptable level. This patch marks them as
skipped on Arm/AArch64 for now.
This is relanding D81001. The patch originally failed as on newer editline
versions it seems CC_REFRESH will move the cursor to the start of the line via
\r and then back to the original position. On older editline versions like
the one used by default on macOS, CC_REFRESH doesn't move the cursor at all.
As the patch changed the way we handle tab completion (previously we did
REDISPLAY but now we're doing CC_REFRESH), this caused a few completion tests
to receive this unexpected cursor movement in the output stream.
This patch updates those tests to also accept output that contains the specific
cursor movement commands (\r and then \x1b[XC). lldbpexpect.py received an
utility method for generating the cursor movement escape sequence.
Original summary:
I implemented autosuggestion if there is one possible suggestion.
I set the keybinds for every character. When a character is typed, Editline::TypedCharacter is called.
Then, autosuggestion part is displayed in gray, and you can actually input by typing C-k.
Editline::Autosuggest is a function for finding completion, and it is like Editline::TabCommand now, but I will add more features to it.
Testing does not work well in my environment, so I can't confirm that it goes well, sorry. I am dealing with it now.
Reviewed By: teemperor, JDevlieghere, #lldb
Differential Revision: https://reviews.llvm.org/D81001
This reverts commit 246afe0cd1. This broke
the following tests on Linux it seems:
lldb-api :: commands/expression/multiline-completion/TestMultilineCompletion.py
lldb-api :: iohandler/completion/TestIOHandlerCompletion.py
I implemented autosuggestion if there is one possible suggestion.
I set the keybinds for every character. When a character is typed, Editline::TypedCharacter is called.
Then, autosuggestion part is displayed in gray, and you can actually input by typing C-k.
Editline::Autosuggest is a function for finding completion, and it is like Editline::TabCommand now, but I will add more features to it.
Testing does not work well in my environment, so I can't confirm that it goes well, sorry. I am dealing with it now.
Reviewed By: teemperor, JDevlieghere, #lldb
Differential Revision: https://reviews.llvm.org/D81001
io.BytesIO seems to produce a stream in Python 2 which isn't recognized
as a file object in the SWIG API, so this test fails for Python 2 (and I assume
also an old SWIG version needs to be involved).
Instead just open an empty input file which is a file object in all Python
versions to make this test pass everywhere.
Summary:
TerminalSizeChanged is called from our SIGWINCH signal handler but the
IOHandlerEditline currently doesn't check if we are actually using the real
editline backend. If we're not using the real editline backend, `m_editline_up`
won't be set and `IOHandlerEditline::TerminalSizeChanged` will access
the empty unique_ptr. In a real use case we don't use the editline backend
when we for example read input from a file. We also create some temporary
IOHandlerEditline's during LLDB startup it seems that are also treated
as non-interactive (apparently to read startup commands).
This patch just adds a nullptr check for`m_editline_up` as we do in the rest of
IOHandlerEditline.
Fixes rdar://problem/63921950
Reviewers: labath, friss
Reviewed By: friss
Subscribers: abidh, JDevlieghere
Differential Revision: https://reviews.llvm.org/D81729
Summary:
The comment in the Editine.h header made it sound like editline was
just unable to handle terminal resizing. We were not ever telling
editline that the terminal had changed size, which might explain why
it wasn't working.
This patch threads a `TerminalSizeChanged()` callback through the
IOHandler and invokes it from the SIGWINCH handler in the driver. Our
`Editline` class already had a `TerminalSizeChanged()` method which
was invoked only when editline was configured.
This patch also changes `Editline` to not apply the changes right away
in `TerminalSizeChanged()`, but instead defer that to the next
character read. During my testing, it happened once that the signal
was received while our `ConnectionFileDescriptor::Read` was allocating
memory. As `el_resize` seems to allocate memory too, this crashed.
Reviewers: labath, teemperor
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D79654
Summary: Moves lldbsuite tests to lldb/test/API.
This is a largely mechanical change, moved with the following steps:
```
rm lldb/test/API/testcases
mkdir -p lldb/test/API/{test_runner/test,tools/lldb-{server,vscode}}
mv lldb/packages/Python/lldbsuite/test/test_runner/test lldb/test/API/test_runner
for d in $(find lldb/packages/Python/lldbsuite/test/* -maxdepth 0 -type d | egrep -v "make|plugins|test_runner|tools"); do mv $d lldb/test/API; done
for d in $(find lldb/packages/Python/lldbsuite/test/tools/lldb-vscode -maxdepth 1 -mindepth 1 | grep -v ".py"); do mv $d lldb/test/API/tools/lldb-vscode; done
for d in $(find lldb/packages/Python/lldbsuite/test/tools/lldb-server -maxdepth 1 -mindepth 1 | egrep -v "gdbremote_testcase.py|lldbgdbserverutils.py|socket_packet_pump.py"); do mv $d lldb/test/API/tools/lldb-server; done
```
lldb/packages/Python/lldbsuite/__init__.py and lldb/test/API/lit.cfg.py were also updated with the new directory structure.
Reviewers: labath, JDevlieghere
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D71151