-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Open
Labels
Description
CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo
fails to extract the callable information from an std::function
which is constructed from a lambda inside a function which has multiple parameters due to this part of it's implementation:
llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
Lines 293 to 311 in 8ebd401
// Given case 1 or 3 we have a vtable name, we are want to extract the first | |
// template parameter | |
// | |
// ... __func<main::$_0, std::__1::allocator<main::$_0> ... | |
// ^^^^^^^^^ | |
// | |
// We could see names such as: | |
// main::$_0 | |
// Bar::add_num2(int)::'lambda'(int) | |
// Bar | |
// | |
// We do this by find the first < and , and extracting in between. | |
// | |
// This covers the case of the lambda known at compile time. | |
size_t first_open_angle_bracket = vtable_name.find('<') + 1; | |
size_t first_comma = vtable_name.find(','); | |
llvm::StringRef first_template_parameter = | |
vtable_name.slice(first_open_angle_bracket, first_comma); |
As a consequence, std::function
summary cannot print the target function's description, and stepping into operator()
does not work.
I have augmented LLDB's logging locally to confirm that this is indeed where things go wrong:
#include <functional>
std::function<void()> GetFunc() {
return []{ printf("func\n"); };
}
std::function<void()> GetFunc1(int a) {
return [=]{ printf("func1(%d)\n", a); };
}
std::function<void()> GetFunc2(int a, int b) {
return [=]{ printf("func2(%d,%d)\n", a, b); };
}
int main() {
auto f1 = GetFunc();
auto f2 = GetFunc1(10);
auto f3 = GetFunc2(10, 10);
printf("Breakpoint here\n");
/*
vtable_name='vtable for std::__1::__function::__func<GetFunc()::$_0, std::__1::allocator<GetFunc()::$_0>, void ()>'
first_template_parameter='GetFunc()::$_0'
vtable_name='vtable for std::__1::__function::__func<GetFunc1(int)::$_0, std::__1::allocator<GetFunc1(int)::$_0>, void ()>'
first_template_parameter='GetFunc1(int)::$_0'
vtable_name='vtable for std::__1::__function::__func<GetFunc2(int, int)::$_0, std::__1::allocator<GetFunc2(int, int)::$_0>, void ()>'
first_template_parameter='GetFunc2(int'
*/
return 0;
}