This patch makes use of c++ type checking and scoped enums to make
logging statements shorter and harder to misuse.
Defines like LIBLLDB_LOG_PROCESS are replaces with LLDBLog::Process.
Because it now carries type information we do not need to worry about
matching a specific enum value with the right getter function -- the
compiler will now do that for us.
The main entry point for the logging machinery becomes the GetLog
(template) function, which will obtain the correct Log object based on
the enum type. It achieves this through another template function
(LogChannelFor<T>), which must be specialized for each type, and should
return the appropriate channel object.
This patch also removes the ability to log a message if multiple
categories are enabled simultaneously as it was unused and confusing.
This patch does not actually remove any of the existing interfaces. The
defines and log retrieval functions are left around as wrappers around
the new interfaces. They will be removed in follow-up patch.
Differential Revision: https://reviews.llvm.org/D117490
I considered keeping this change strictly downstream. Since we still
have a bunch of places that check for Python 2, I figured it doesn't
harm to land it upstream and avoid the conflict when I eventually do
remove them (hopefully soon!).
Add statistics about the memory usage of the string pool. I'm
particularly interested in the memory used by the allocator, i.e. the
number of bytes actually used by the allocator it self as well as the
number of bytes allocated through the allocator.
Differential revision: https://reviews.llvm.org/D117914
This patch changes the `ScriptedInterface::ErrorWithMessage` method to
make it `static` which makes it easier to call.
The patch also updates its various call sites to reflect this change.
Differential Revision: https://reviews.llvm.org/D117374
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
When listing all the Scripted Threads of a ScriptedProcess, we can see that all
have the thread index set to 1. This is caused by the lldb_private::Thread
constructor, which sets the m_index_id member using the provided thread id `tid`.
Because the call to the super constructor is done before instantiating
the `ScriptedThreadInterface`, lldb can't fetch the thread id from the
script instance, so it uses `LLDB_INVALID_THREAD_ID` instead.
To mitigate this, this patch takes advantage of the `ScriptedThread::Create`
fallible constructor idiom to defer calling the `ScriptedThread` constructor
(and the `Thread` super constructor with it), until we can fetch a valid
thread id `tid` from the `ScriptedThreadInterface`.
rdar://87432065
Differential Revision: https://reviews.llvm.org/D117076
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This patch adds Exceptions to the list of supported stop reasons for
Scripted Threads.
The main motivation for this is that breakpoints are triggered as a
special exception class on ARM platforms, so adding it as a stop reason
allows the ScriptedProcess to selected the ScriptedThread that stopped at
a breakpoint (or crashed :p).
rdar://87430376
Differential Revision: https://reviews.llvm.org/D117074
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This patch adds support of multiple Scripted Threads in a ScriptedProcess.
This is done by fetching the Scripted Threads info dictionary at every
ScriptedProcess::DoUpdateThreadList and iterate over each element to
create a new ScriptedThread using the object instance, if it was not
already available.
This patch also adds the ability to pass a pointer of a script interpreter
object instance to initialize a ScriptedInterface instead of having to call
the script object initializer in the ScriptedInterface constructor.
This is used to instantiate the ScriptedThreadInterface from the
ScriptedThread constructor, to be able to perform call on that script
interpreter object instance.
Finally, the patch also updates the scripted process test to check for
multiple threads.
rdar://84507704
Differential Revision: https://reviews.llvm.org/D117071
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
Since we can have multiple Scripted Threads per Scripted Process, having
only a single ScriptedThreadInterface (with a single object instance)
will cause the method calls to be done on the wrong object.
Instead, this patch creates a separate ScriptedThreadInterface for each
new lldb_private::ScriptedThread to make sure we interact with the right
instance.
rdar://87427911
Differential Revision: https://reviews.llvm.org/D117070
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This patch adds a new method to the Scripted Process interface to
retrive a dictionary of Scripted Threads. It uses the thread ID as a key
and the Scripted Thread instance as the value.
This dictionary will be used to create Scripted Threads in lldb and
perform calls to the python scripted thread object.
rdar://87427126
Differential Revision: https://reviews.llvm.org/D117068
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This removes the non-address bits before we try to use
the addresses.
Meaning that when results are shown, those results won't
show non-address bits either. This follows what "memory read"
has done. On the grounds that non-address bits are a property
of a pointer, not the memory pointed to.
I've added testing and merged the find and read tests into one
file.
Note that there are no API side changes because "memory find"
does not have an equivalent API call.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D117299
Allow users to create aliases for aliases to raw input commands. That probably
sounds convoluted, so here's an example:
```
command alias some-setup env SOMEVAR=SOMEVALUE
```
This an alias based on `env`, which itself is an alias for `_regex-env`.
`_regex-env` is a `command regex` command, which takes raw input.
The above `some-setup` alias fails with:
```
error: Unable to create requested alias.
```
This change allows such aliases to be created. lldb already supports aliases to
aliases for parsed commands.
Differential Revision: https://reviews.llvm.org/D117259
The logic of `g_quiet` was inverted in D26243. This corrects the issue.
Without this, running `log timers enable` produces a high volume of incremental
timer output.
Differential Revision: https://reviews.llvm.org/D117837
The cleanup was manual, but assisted by "include-what-you-use". It consists in
1. Removing unused forward declaration. No impact expected.
2. Removing unused headers in .cpp files. No impact expected.
3. Removing unused headers in .h files. This removes implicit dependencies and
is generally considered a good thing, but this may break downstream builds.
I've updated llvm, clang, lld, lldb and mlir deps, and included a list of the
modification in the second part of the commit.
4. Replacing header inclusion by forward declaration. This has the same impact
as 3.
Notable changes:
- llvm/Support/TargetParser.h no longer includes llvm/Support/AArch64TargetParser.h nor llvm/Support/ARMTargetParser.h
- llvm/Support/TypeSize.h no longer includes llvm/Support/WithColor.h
- llvm/Support/YAMLTraits.h no longer includes llvm/Support/Regex.h
- llvm/ADT/SmallVector.h no longer includes llvm/Support/MemAlloc.h nor llvm/Support/ErrorHandling.h
You may need to add some of these headers in your compilation units, if needs be.
As an hint to the impact of the cleanup, running
clang++ -E -Iinclude -I../llvm/include ../llvm/lib/Support/*.cpp -std=c++14 -fno-rtti -fno-exceptions | wc -l
before: 8000919 lines
after: 7917500 lines
Reduced dependencies also helps incremental rebuilds and is more ccache
friendly, something not shown by the above metric :-)
Discourse thread on the topic: https://llvm.discourse.group/t/include-what-you-use-include-cleanup/5831
Instrument the SB API with signposts on Darwin. This gives us a time
profile on whose behalf LLDB spends time (particularly when run via the
SBAPI from an IDE).
Differential revision: https://reviews.llvm.org/D117632
Remove the last remaining references to the reproducers from the
instrumentation. This patch renames the relevant files and macros.
Differential revision: https://reviews.llvm.org/D117712
This patch works around what looks like a bug in Clang itself.
The error on the bot is:
https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/40466/consoleText
In module 'LLVM_Utils' imported from /Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h:18:
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/llvm/include/llvm/Support/Error.h:720:3: error: 'llvm::Expected<bool>::(anonymous)' from module 'LLVM_Utils.Support.Error' is not present in definition of 'llvm::Expected<bool>' in module 'LLVM_Utils.Support.Error'
union {
^
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/llvm/include/llvm/Support/Error.h:720:3: note: declaration of '' does not match
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/llvm/include/llvm/Support/Error.h:720:3: note: declaration of '' does not match
1 error generated.
The intention is to revert this as soon as a proper fix has been identified!
rdar://87845391
Although the memory tag commands use a memory tag manager to handle
addresses, that only removes the top byte.
That top byte is 4 bits of memory tag and 4 free bits, which is more
than it should strictly remove but that's how it is for now.
There are other non-address bit uses like pointer authentication.
To ensure the memory tag manager only has to deal with memory tags,
use the ABI plugin to remove the rest.
The tag access test has been updated to sign all the relevant pointers
and require that we're running on a system with pointer authentication
in addition to memory tagging.
The pointers will look like:
<4 bit user tag><4 bit memory tag><signature><bit virtual address>
Note that there is currently no API for reading memory tags. It will
also have to consider this when it arrives.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D117672
This better describes the intent of the method. Which for AArch64
is removing the top byte which includes the memory tags.
It does not include pointer signatures, for those we need to use
the ABI plugin. The rename makes this a little more clear.
It's a bit awkward that the memory tag manager is removing the whole
top byte not just the memory tags but it's an improvement for now.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D117671
We got a few crash reports that showed LLDB initializing Python on two
separate threads. Make sure Python is initialized exactly once.
rdar://87287005
Differential revision: https://reviews.llvm.org/D117601
std::chrono::duration types are not thread-safe, and they cannot be
concurrently updated from multiple threads. Currently, we were doing
such a thing (only) in the DWARF indexing code
(DWARFUnit::ExtractDIEsRWLocked), but I think it can easily happen that
someone else tries to update another statistic like this without
bothering to check for thread safety.
This patch changes the StatsDuration type from a simple typedef into a
class in its own right. The class stores the duration internally as
std::atomic<uint64_t> (so it can be updated atomically), but presents it
to its users as the usual chrono type (duration<float>).
Differential Revision: https://reviews.llvm.org/D117474
It complements the existing SBDebugger::SetCurrentPlatformSDKRoot and
allows one to set the sysroot of a platform without making it current.
Differential Revision: https://reviews.llvm.org/D117550
This macro was being used to select the proper import/export annotations
on SB classes. Non-windows clients do not have such requirements.
Instead introduce a new macro (LLDB_IN_LIBLLDB), which signals that
we're compiling liblldb itself (and should use dllexport). The default
(no macro) is to use dllimport. I've moved the macro definition to
SBDefines.h, since it only makes sense when building the API library.
Differential Revision: https://reviews.llvm.org/D117564
Use libobjc.A.dylib as a sentinel to detect situations where we're
reading libraries from process memory instead of the shared cache.
Differential revision: https://reviews.llvm.org/D117623
Return our PythonObject wrappers instead of raw PyObjects (obfuscated as
void *). This ensures that ownership (reference counts) of python
objects is automatically tracked.
Differential Revision: https://reviews.llvm.org/D117462
Provide minimal register definition defaults for working with servers
that implement neither target.xml nor qRegisterInfo packets. This is
useful e.g. when interacting with FreeBSD's kernel minimal gdbserver
that does not send target.xml but uses the same layout for its supported
register subset as GDB.
The prerequisite for this is the ability to determine the correct
architecture, e.g. from the target executable.
Differential Revision: https://reviews.llvm.org/D116896
The GIL must be held when calling any Python C API functions. In multithreaded applications that use callbacks this requirement can easily be violated by accident. A general tool to ensure GIL health is not available, but patching Python Py_INCREF to add an assert provides a basic health check:
```
+int PyGILState_Check(void); /* Include/internal/pystate.h */
+
#define Py_INCREF(op) ( \
+ assert(PyGILState_Check()), \
_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \
((PyObject *)(op))->ob_refcnt++)
#define Py_DECREF(op) \
do { \
+ assert(PyGILState_Check()); \
PyObject *_py_decref_tmp = (PyObject *)(op); \
if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \
--(_py_decref_tmp)->ob_refcnt != 0) \
```
Adding this assertion causes around 50 test failures in LLDB. Adjusting the scope of things guarded by `py_lock` fixes them.
More background: https://docs.python.org/3/glossary.html#term-global-interpreter-lock
Patch by Ralf Grosse-Kunstleve
Differential Revision: https://reviews.llvm.org/D114722
Ensure that errors in `frame variable` are reflected in result object.
The statistics for `frame variable` show invocations as being successful, even
when executing one of the error paths.
This change replaces `result.GetErrorStream()` with `result.AppendError()`,
which also sets the status to `eReturnStatusFailed`.
Differential Revision: https://reviews.llvm.org/D116788
Recommitting after D116901 and D116863.
(cherry picked from commit 2c7d10c41278181e3e45c68f28b501cd95193a8a)
This also removes the corresponding unit tests. I wrote them to sanity
check my original refactoring and checked them in because why not. The
current implementation, without the added complexity of indices, is
simple enough that we can do without it.
Currently, when connecting to a remote iOS device from the command line
on Apple Silicon, we end up using the host platform (PlatfromMacOSX)
instead of remote-ios (PlatformRemoteiOS). This happens because
PlatfromMacOSX includes arm64-apple-ios and arm64e-apple-ios as
compatible architectures, presumably to support debugging iOS Apps on
Apple Silicon [1].
This is a problem for debugging remote ios devices, because the host
platform doesn't look for an expanded shared cache on disk and as a
result we end up reading everything from memory, incurring a significant
performance hit.
The crux of this patch is to make PlatfromMacOSX *not* compatible with
arm64(e)-apple-ios. This also means that we now use remote-ios
(PlatformRemoteiOS) as the platform for debugging iOS apps on Apple
Silicon. This has the (unintended) side effect that unlike we do for the
host platform, we no longer check our local shared cache, and incur a
performance hit on debugging these apps.
To avoid that, PlatformRemoteiOS now also check the local cache to
support this use case, which is cheap enough to do unconditionally for
PlatformRemoteiOS.
[1] https://support.apple.com/guide/app-store/iphone-ipad-apps-mac-apple-silicon-fird2c7092da/mac
Differential revision: https://reviews.llvm.org/D117340
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
Implement the qXfer:siginfo:read that is used to read the siginfo_t
(extended signal information) for the current thread. This is currently
implemented on FreeBSD and Linux.
Differential Revision: https://reviews.llvm.org/D117113
Set the current thread ID to the thread where an event happened.
As a result, e.g. when a signal is delivered to a thread other than
the first one, the respective T packet refers to the signaled thread
rather than the first thread (with no stop reason). While this doesn't
strictly make a difference to the LLDB client, it is the expected
behavior.
Differential Revision: https://reviews.llvm.org/D117103