This is motivated by exposing some Swift language-specific flags through
the API, in the example here it is used to communicate the Objective-C
runtime version. This could also be a meaningful extension point to get
information about "embedded: languages, such as extracting the C++
version in an Objective-C++ frame or something along those lines.
We got a bug report that this message is confusing. In this particular
case, the line zero was due to compiler tail merging (in optimized
code). The main issue was the "no source code" part: in this case it's
kind of incorrect because -- even though we can't really know that --
the address is arguably associated with *multiple* lines of source code.
I've tried to make the new wording more neutral, and added a wink
towards compiler optimizations. I left out the "compiler generated" part
of the message because I couldn't find a way to squeeze that in nicely.
I'm also not entirely sure what it was referring to -- if this was
(just) function prologue/epilogue, then maybe leaving it out is fine, as
we're not likely to stop there anyway (?)
I also left out the function name, because:
- for template functions it gets rather long
- it's already present in the message, potentially twice (once in the
"frame summary" line and once in the snippet of code we show for the
function declaration)
---------
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
This patch is a follow-up to 9c7701fa78
and adds extra-null checks before dereferencing the inlined_info
pointer.
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
This patch moves some of the logic implemented in the SBFrame APIs to
the lldb_private::StackFrame class so it can be re-used elsewhere.
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
Add the framework code for hooking up and calling the Data Inspection
Language (DIL) implementation, as an alternate implementation for the
'frame variable' command. For now, this is an opt-in option, via a
target setting 'target.experimental.use-DIL'. See
https://discourse.llvm.org/t/rfc-data-inspection-language/69893 for more
information about this project.
This PR does not actually call any of the DIL code; instead the piece
that will eventually call the DIL code
(StackFrame::DILEvaluateVariableExpression) calls back into the original
'frame variable' implementation.
When retrieving the location of the function declaration, we were
dropping the file component on the floor, which resulted in an amusingly
confusing situation were we displayed the file containing the
implementation of the function, but used the line number of the
declaration. This patch fixes that.
It required a small refactor Function::GetStartLineSourceLineInfo to
return a SupportFile (instead of just the file spec), which in turn
necessitated changes in a couple of other places as well.
Add the ability to override the disassembly CPU and CPU features through
a target setting (`target.disassembly-cpu` and
`target.disassembly-features`) and a `disassemble` command option
(`--cpu` and `--features`).
This is especially relevant for architectures like RISC-V which relies
heavily on CPU extensions.
The majority of this patch is plumbing the options through. I recommend
looking at DisassemblerLLVMC and the test for the observable change in
behavior.
ValueObject is part of lldbCore for historical reasons, but conceptually
it deserves to be its own library. This does introduce a (link-time) circular
dependency between lldbCore and lldbValueObject, which is unfortunate
but probably unavoidable because so many things in LLDB rely on
ValueObject. We already have cycles and these libraries are never built
as dylibs so while this doesn't improve the situation, it also doesn't
make things worse.
The header includes were updated with the following command:
```
find . -type f -exec sed -i.bak "s%include \"lldb/Core/ValueObject%include \"lldb/ValueObject/ValueObject%" '{}' \;
```
This fixes the following assertion: "Cannot create Expected<T> from
Error success value." The problem was that GetFrameBaseValue return
false without updating the Status argument. This patch eliminates the
opportunity for mistakes by returning an llvm:Error.
This patch removes all of the Set.* methods from Status.
This cleanup is part of a series of patches that make it harder use the
anti-pattern of keeping a long-lives Status object around and updating
it while dropping any errors it contains on the floor.
This patch is largely NFC, the more interesting next steps this enables
is to:
1. remove Status.Clear()
2. assert that Status::operator=() never overwrites an error
3. remove Status::operator=()
Note that step (2) will bring 90% of the benefits for users, and step
(3) will dramatically clean up the error handling code in various
places. In the end my goal is to convert all APIs that are of the form
` ResultTy DoFoo(Status& error)
`
to
` llvm::Expected<ResultTy> DoFoo()
`
How to read this patch?
The interesting changes are in Status.h and Status.cpp, all other
changes are mostly
` perl -pi -e 's/\.SetErrorString/ = Status::FromErrorString/g' $(git
grep -l SetErrorString lldb/source)
`
plus the occasional manual cleanup.
Compilers and language runtimes often use helper functions that are
fundamentally uninteresting when debugging anything but the
compiler/runtime itself. This patch introduces a user-extensible
mechanism that allows for these frames to be hidden from backtraces and
automatically skipped over when navigating the stack with `up` and
`down`.
This does not affect the numbering of frames, so `f <N>` will still
provide access to the hidden frames. The `bt` output will also print a
hint that frames have been hidden.
My primary motivation for this feature is to hide thunks in the Swift
programming language, but I'm including an example recognizer for
`std::function::operator()` that I wished for myself many times while
debugging LLDB.
rdar://126629381
Example output. (Yes, my proof-of-concept recognizer could hide even
more frames if we had a method that returned the function name without
the return type or I used something that isn't based off regex, but it's
really only meant as an example).
before:
```
(lldb) thread backtrace --filtered=false
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000100001f04 a.out`foo(x=1, y=1) at main.cpp:4:10
frame #1: 0x0000000100003a00 a.out`decltype(std::declval<int (*&)(int, int)>()(std::declval<int>(), std::declval<int>())) std::__1::__invoke[abi:se200000]<int (*&)(int, int), int, int>(__f=0x000000016fdff280, __args=0x000000016fdff224, __args=0x000000016fdff220) at invoke.h:149:25
frame #2: 0x000000010000399c a.out`int std::__1::__invoke_void_return_wrapper<int, false>::__call[abi:se200000]<int (*&)(int, int), int, int>(__args=0x000000016fdff280, __args=0x000000016fdff224, __args=0x000000016fdff220) at invoke.h:216:12
frame #3: 0x0000000100003968 a.out`std::__1::__function::__alloc_func<int (*)(int, int), std::__1::allocator<int (*)(int, int)>, int (int, int)>::operator()[abi:se200000](this=0x000000016fdff280, __arg=0x000000016fdff224, __arg=0x000000016fdff220) at function.h:171:12
frame #4: 0x00000001000026bc a.out`std::__1::__function::__func<int (*)(int, int), std::__1::allocator<int (*)(int, int)>, int (int, int)>::operator()(this=0x000000016fdff278, __arg=0x000000016fdff224, __arg=0x000000016fdff220) at function.h:313:10
frame #5: 0x0000000100003c38 a.out`std::__1::__function::__value_func<int (int, int)>::operator()[abi:se200000](this=0x000000016fdff278, __args=0x000000016fdff224, __args=0x000000016fdff220) const at function.h:430:12
frame #6: 0x0000000100002038 a.out`std::__1::function<int (int, int)>::operator()(this= Function = foo(int, int) , __arg=1, __arg=1) const at function.h:989:10
frame #7: 0x0000000100001f64 a.out`main(argc=1, argv=0x000000016fdff4f8) at main.cpp:9:10
frame #8: 0x0000000183cdf154 dyld`start + 2476
(lldb)
```
after
```
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000100001f04 a.out`foo(x=1, y=1) at main.cpp:4:10
frame #1: 0x0000000100003a00 a.out`decltype(std::declval<int (*&)(int, int)>()(std::declval<int>(), std::declval<int>())) std::__1::__invoke[abi:se200000]<int (*&)(int, int), int, int>(__f=0x000000016fdff280, __args=0x000000016fdff224, __args=0x000000016fdff220) at invoke.h:149:25
frame #2: 0x000000010000399c a.out`int std::__1::__invoke_void_return_wrapper<int, false>::__call[abi:se200000]<int (*&)(int, int), int, int>(__args=0x000000016fdff280, __args=0x000000016fdff224, __args=0x000000016fdff220) at invoke.h:216:12
frame #6: 0x0000000100002038 a.out`std::__1::function<int (int, int)>::operator()(this= Function = foo(int, int) , __arg=1, __arg=1) const at function.h:989:10
frame #7: 0x0000000100001f64 a.out`main(argc=1, argv=0x000000016fdff4f8) at main.cpp:9:10
frame #8: 0x0000000183cdf154 dyld`start + 2476
Note: Some frames were hidden by frame recognizers
```
Change the signature of `DWARFExpression::Evaluate` and
`DWARFExpressionList::Evaluate` to return an `llvm::Expected` instead of a
boolean. This eliminates the `Status` output parameter and generally improves
error handling.
that separates out language and version. To avoid reinventing the wheel
and introducing subtle incompatibilities, this API uses the table of
languages and versiond defined by the upcoming DWARF 6 standard
(https://dwarfstd.org/languages-v6.html). While the DWARF 6 spec is not
finialized, the list of languages is broadly considered stable.
The primary motivation for this is to allow the Swift language plugin to
switch between language dialects between, e.g., Swift 5.9 and 6.0 with
out introducing a ton of new language codes. On the main branch this
change is considered NFC.
Depends on https://github.com/llvm/llvm-project/pull/89980
This is another step towards supporting DWARF5 checksums and inline
source code in LLDB. This is a reland of #85468 but without the
functional change of storing the support file from the line table (yet).
Change GetNumChildren()/CalculateNumChildren() methods return
llvm::Expected
This is an NFC change that does not yet add any error handling or change
any code to return any errors.
This is the second big change in the patch series started with
https://github.com/llvm/llvm-project/pull/83501
A follow-up PR will wire up error handling.
Change GetNumChildren()/CalculateNumChildren() methods return
llvm::Expected
This is an NFC change that does not yet add any error handling or change
any code to return any errors.
This is the second big change in the patch series started with
https://github.com/llvm/llvm-project/pull/83501
A follow-up PR will wire up error handling.
This commits fixes a few subtle bugs where the method:
1. Declares a local `Status error` which eclipses the method's parameter
`Status &error`.
- The method then sets the error state to the local `error` and returns
without ever touching the parameter `&error`.
- This effectively traps the error state and its message from ever
reaching the caller.
- I also threw in a null pointer check in case the callee doesn't set
its `Status` parameter but returns `0`/`nullptr`.
2. Declares a local `Status deref_error` (good), passes it to the
`Dereference` method (also good), but then checks the status of the
method's `Status &error` parameter (not good).
- The fix checks `deref_error` instead and also checks for a `nullptr`
return value.
- There's a good opportunity here for a future PR that changes the
`Dereference` method to fold an error state into the `ValueObject`
return value's `m_error` instead of using a parameter.
3. Declares another local `Status error`, which it doesn't pass to a
method (because there isn't a parameter for it), and then checks for an
error condition that never happens.
- The fix just checks the callee's return value, because that's all it
has to go on.
- This likely comes from a copy/paste from issue 1 above.
rdar://119155810
When this option gets enabled, descriptions of stack frames will be
generated using the format provided in the launch configuration instead
of simply calling `SBFrame::GetDisplayFunctionName`. This allows
lldb-dap to show an output similar to the one in the CLI.
Fix incorrect uses of LLDB_LOG_ERROR. The macro doesn't automatically
inject the error in the log message: it merely passes the error as the
first argument to formatv and therefore must be referenced with {0}.
Thanks to Nicholas Allegra for collecting a list of places where the
macro was misused.
rdar://111581655
Differential revision: https://reviews.llvm.org/D154530
Existing callers of `GetChildAtIndex` pass true for can_create. This change
makes true the default value, callers don't have to pass an opaque true.
See also D151966 for the same change to `GetChildMemberWithName`.
Differential Revision: https://reviews.llvm.org/D152031
It turns out all existing callers of `GetChildMemberWithName` pass true for `can_create`.
This change makes `true` the default value, callers don't have to pass an opaque true.
Differential Revision: https://reviews.llvm.org/D151966
The `v` (`frame variable`) command can directly access ivars/fields of `this` or `self`.
Such as `v field`, instead of `v this->field`. This change relaxes the criteria for
finding `this`/`self` variables.
There are cases where a `this`/`self` variable does exist, but up to now the `v` command
has not made use of it. The user would have to explicitly run `v this->field` or
`self->_ivar` to access ivars. This change allows such cases to also work (without
explicitly dereferencing `this`/`self`).
A very common example in Objective-C (and Swift) is weakly capturing `self`:
```
__weak Type *weakSelf = self;
void (^block)(void) = ^{
Type *self = weakSelf; // Re-establish strong reference.
// `v _ivar` should work just as well as `v self->_ivar`.
};
```
In this case, `self` exists but `v` would not have used it. With this change, the fact
that a variable named `self` exists is enough for it to be used.
Differential Revision: https://reviews.llvm.org/D145276
When a process gets restarted TypeSystem objects associated with it
may get deleted, and any CompilerType objects holding on to a
reference to that type system are a use-after-free in waiting. Because
of the SBAPI, we don't have tight control over where CompilerTypes go
and when they are used. This is particularly a problem in the Swift
plugin, where the scratch TypeSystem can be restarted while the
process is still running. The Swift plugin has a lock to prevent
abuse, but where there's a lock there can be bugs.
This patch changes CompilerType to store a std::weak_ptr<TypeSystem>.
Most of the std::weak_ptr<TypeSystem>* uglyness is hidden by
introducing a wrapper class CompilerType::WrappedTypeSystem that has a
dyn_cast_or_null() method. The only sites that need to know about the
weak pointer implementation detail are the ones that deal with
creating TypeSystems.
rdar://101505232
Differential Revision: https://reviews.llvm.org/D136650
Summary:
Many times when debugging variables might not be available even though a user can successfully set breakpoints and stops somewhere. Letting the user know will help users fix these kinds of issues and have a better debugging experience.
Examples of this include:
- enabling -gline-tables-only and being able to set file and line breakpoints and yet see no variables
- unable to open object file for DWARF in .o file debugging for darwin targets due to modification time mismatch or not being able to locate the N_OSO file.
This patch adds an new API to SBValueList:
lldb::SBError lldb::SBValueList::GetError();
object so that if you request a stack frame's variables using SBValueList SBFrame::GetVariables(...), you can get an error the describes why the variables were not available.
This patch adds the ability to get an error back when requesting variables from a lldb_private::StackFrame when calling GetVariableList.
It also now shows an error in response to "frame variable" if we have debug info and are unable to get varialbes due to an error as mentioned above:
(lldb) frame variable
error: "a.o" object from the "/tmp/libfoo.a" archive: either the .o file doesn't exist in the archive or the modification time (0x63111541) of the .o file doesn't match
Reviewers: labath JDevlieghere aadsm yinghuitan jdoerfert sscalpone
Subscribers:
Differential Revision: https://reviews.llvm.org/D133164
Many times when debugging variables might not be available even though a user can successfully set breakpoints and stops somewhere. Letting the user know will help users fix these kinds of issues and have a better debugging experience.
Examples of this include:
- enabling -gline-tables-only and being able to set file and line breakpoints and yet see no variables
- unable to open object file for DWARF in .o file debugging for darwin targets due to modification time mismatch or not being able to locate the N_OSO file.
This patch adds an new API to SBValueList:
lldb::SBError lldb::SBValueList::GetError();
object so that if you request a stack frame's variables using SBValueList SBFrame::GetVariables(...), you can get an error the describes why the variables were not available.
This patch adds the ability to get an error back when requesting variables from a lldb_private::StackFrame when calling GetVariableList.
It also now shows an error in response to "frame variable" if we have debug info and are unable to get varialbes due to an error as mentioned above:
(lldb) frame variable
error: "a.o" object from the "/tmp/libfoo.a" archive: either the .o file doesn't exist in the archive or the modification time (0x63111541) of the .o file doesn't match
Differential Revision: https://reviews.llvm.org/D133164
This can cause a deadlock if other threads use the common pattern of
"lock the StackFrameList, get a frame, lock the StackFrame."
Differential Revision: https://reviews.llvm.org/D130524
The `frame variable` command supports an implicit `this`/`self`, allowing a
user to run `v some_field` instead of `v this->some_field`. However, some
languages have non-pointer `this`/`self` types (for example, Swift).
This change adds support for non-pointer implicit `this`/`self`. This is done
by consulting the type of the instance variable. If the type is known to be
non-pointer, the dot operator is used instead of the arrow operator.
The C language of families each have a pointer instance type, which makes
testing of this difficult. Tests for this feature will be done in the Swift
downstream fork, as Swift's `self` is a non-pointer (reference) type.
rdar://82095148
Reviewed By: aprantl
Differential Revision: https://reviews.llvm.org/D127605
Most of our code was including Log.h even though that is not where the
"lldb" log channel is defined (Log.h defines the generic logging
infrastructure). This worked because Log.h included Logging.h, even
though it should.
After the recent refactor, it became impossible the two files include
each other in this direction (the opposite inclusion is needed), so this
patch removes the workaround that was put in place and cleans up all
files to include the right thing. It also renames the file to LLDBLog to
better reflect its purpose.
This is a post-review update for D115313, to rephrase source display
warning messages for artificial locations, making them more
understandable for the end-user.
Differential Revision: https://reviews.llvm.org/D115461
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
It can happen that a line entry reports that some source code is located
at line 0. In DWARF, line 0 is a special location which indicates that
code has no 1-1 mapping with source.
When stopping in one of those artificial locations, lldb doesn't know which
line to display and shows the beginning of the file instead.
This patch mitigates this behaviour by checking if the current symbol context
of the line entry has a matching function, in which case, it slides the
source listing to the start of that function.
This patch also shows the user a warning explaining why lldb couldn't
show sources at that location.
rdar://83118425
Differential Revision: https://reviews.llvm.org/D115313
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>