假设你有一些代码推送到这样的队列:
template <typename T>
void submitJobToPool(T callable)
{
someJobQueue.push(callable)
}
......以及稍后:
template <typename T>
void runJobFromPool(T callable)
{
auto job = someJobQueue.pop();
job();
}
现在想象一下,由于job()
调用内部的一些错误导致代码崩溃。如果提交的作业是正常函数,则调用堆栈可能如下所示:
void myFunction() 0x345678901
void runJobFromPool() 0x234567890
int main(int, char**) 0x123456789
很容易看到这里崩溃了什么功能。如果它是一个仿函数,它会类似但在某处有一个operator()
(忽略内联)。但是,对于一个lambda ......
void lambda_a7009ccf8810b62b59083b4c1779e569() 0x345678901
void runJobFromPool() 0x234567890
int main(int, char**) 0x123456789
这不是那么容易调试。如果在发生调试器时附加了调试器,或者核心转储可用,则可以使用该信息来导出哪个lambda崩溃,但该信息并不总是可用。据我所知,反汇编是确定从此崩溃的几种方法之一。
我必须做的更好的想法是:
addr2line
之类的工具。这有时会起作用,有时候不行。第四个选项看起来很有希望,所以我做了一些调查,但找不到任何东西。如果它很重要,我可用的编译器是clang ++ 5.0和MSVC 19(Visual Studio 2015)。
我的问题是,有哪些其他工具/技术可以帮助将带有lambda函数的callstack映射到相应的源代码行?
答案 0 :(得分:2)
我担心这是不可能的。您应该设计自己的技术,如何在lamdas中存储所需的信息。您的选项2适用于此处。您可以查看Google如何:https://cs.chromium.org/chromium/src/base/task_scheduler/post_task.h
以下是非常原始的方法(https://ideone.com/OFCgAq)
#include <iostream>
#include <stack>
#include <functional>
std::stack<std::function<void(void)>> someJobQueue;
template <typename T>
void submitJobToPool(std::string from_here, T callable) {
someJobQueue.push(std::bind([callable](std::string from_here) { callable(); }, from_here));
}
void runJobFromPool() {
auto job = someJobQueue.top();
someJobQueue.pop();
job();
}
int main() {
submitJobToPool(__func__, [](){ std::cout << "It's me." << std::endl; });
runJobFromPool();
return 0;
}
不幸的是,你不会看到一个完美的调用堆栈。但是你可以在调试器中看到from_here
。
void lambda_1a7009ccf8810b62b59083b4c1779e56() 0x345678920
void lambda_a7009ccf8810b62b59083b4c1779e569() 0x345678910 <-- Here `from_here` will be available: "main"
void runJobFromPool() 0x234567890
int main(int, char**) 0x123456780