I’m trying to debug small c++ program which uses STL containers, let’s take a list
for example:
#include <list>
#include <iostream>
using namespace std;
template<typename T>
void print(T& container) {
for (const auto& v: container) {
cout << v << ' ';
}
cout << endl;
}
void simple_list() {
list<int> l{2048};
print(l);
}
int main() {
simple_list();
return 0;
}
I’m trying to change list value (from 2048 to any other number) through vscode
(lldb-mi) and python scripting in lldb - in both cases I see that this change is reverted after each next line
command (please take a look at attached gif). Reproduction steps:
- Set breakpoint
- Stop at this breakpoinnt, change value of the list element
- VSCode shows updated value
- Execute
next line
command in lldb - VSCode shows original value of the list element
I start digging into whats happened and find out that there are different types of ValueType
s for synthetic values in lldb ( https://github.com/llvm/llvm-project/blob/llvmorg-16.0.6/lldb/include/lldb/Core/Value.h#L41 ), in my case the problem was in HostAddress
/ LoadAddress
- in a comment it is stated that HostAddress
is for values created in process which uses liblldb (lldb / lldb-mi) and LoadAddress
is for values in debugging process (as I understand, please correct me if I wrong).
When program starts, the list’s values are marked as LoadAddress
, but when I change them in VSCode - their type became HostAddress
.
This happens in ListFrontEnd::GetChildAtIndex
( https://github.com/llvm/llvm-project/blob/llvmorg-16.0.6/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp#L392 ), and when value is changed, liblldb creates new object in its own memory with type HostAddress
.
After that lldb-mi (after each step) sends delete-all-variables
request to the debug server ( https://github.com/lldb-tools/lldb-mi/blob/main/src/MICmdCmdVar.cpp#L669 ), and after that on each step lldb-mi requests variables from debugging process’s frame ( https://github.com/lldb-tools/lldb-mi/blob/main/src/MICmdCmdStack.cpp#L850 ).
Therefore all HostAddress
values are removed and all changes are lost. I didn’t yet dig into lldb, but I suppose something similar happens there.
So, the question is : is it expected that liblldb frontends (lldb, lldb-mi, etc) should manage HostAddress
values properly and save values between steps? Or it should be done somehow somewhere in lldb? At this point it is unclear how to handle such values. If someone can provide helpful information for this - I would really appreciate it (maybe there are some good resources about how lldb works internally)
Note: in this question I took a list only as an example, but same issue happens for all STL containers except map/set (they use same synthetic frontend) which were fixed recently: https://reviews.llvm.org/D140624 (similar fix is applicable for most other containers, but I want to clarify how it was supposed to work initially, maybe properly it should be done in some another way)