我想在多线程环境中超载新操作员,并希望在其中拥有线程ID,函数名称和行号。有什么方法可以做到吗?
您可以做一个新的operator new
超载:
void * operator new(std::size_t count, const char* file, int line)
{
// Do stuff
// ...
return ::operator new(count);
}
void * operator delete(void* p, const char* file, int line)
{
// Do stuff
// ...
return ::operator delete(p);
}
// ... and [] versions ..
然后您可以使用放置语法:
auto x = new (__FILE__, __LINE__) Foo;
然后您可以添加一个宏:
#define TRACE_NEW new (__FILE__, __LINE__)
auto x = TRACE_NEW Foo;
一般来说,没有办法做您想做的事(当然,除了使用Moldbnilo之类的宏或未来的STD :: source_location之类的宏)
但是,如果您使用的是最近的Linux系统,并且如果您使用的所有代码(以及它使用的大多数库,包括libstdc++
),则使用调试选项编译,您也可以考虑Ian Taylor的Libbacktrace(也可以使用它在GCC中)并在operator new
实现中使用它。libbacktrace
使您可以使用矮人调试信息检查呼叫堆栈中的通话帧。
您甚至可以在呼叫堆栈中具有大多数功能的源位置(尤其是operator new
呼叫者中的源位置)。
请记住,您可以使用调试信息(例如-g
)和一些优化标志(例如-O1
或-O2
)编译一些C 代码(使用GCC或Clang);当然,调试信息(在矮人中)将是"模糊的",但在实践中仍然大多可用。
顺便说一句,也许您只需要使用-fsanitize=address
仪器选项来编译valgrind或某些地址进行消毒(我们不知道,因为您的问题没有动机)。