在日志宏中使用__FILE__、__LINE__和__FUNCTION__时NULL_CLASS_PTR_DEREFER

NULL_CLASS_PTR_DEREFERENCE when using __FILE__, __LINE__ and __FUNCTION__ in log macro

本文关键字:FUNCTION NULL DEREFER PTR CLASS LINE 日志 FILE      更新时间:2023-10-16

我的一个程序有一个奇怪的行为。我定义了一个宏LOG_FUNCTION,可扩展到

#define LOG_FUNCTION 
{ 
std::string strFile = __FILE__; 
std::string strLine = std::to_string(__LINE__); 
std::string strFunction = __FUNCTION__; 
logger.log(strFile + ", line " + strLine + ", " + strFunction + "()"); 
} 
CIndentor _indentor_(&logger);

在 Logger.h 中声明。记录器也在 Logger.h 中声明:

// Declare the one and only logger object (which is defined in Logger.cpp):
extern CLogger logger;

日志函数如下所示:

void CLogger::log(const string &strText)
{
lock_guard<mutex> lockGuard(_mutex);
m_count++;
string strIndentation(m_indentation, ' ');
string strTime = getCurrentDateTime();
FILE* pFileStream = nullptr;
errno_t err = fopen_s(&pFileStream, m_strLogFilePath.c_str(), "a+");
if (err == 0)
{
fprintf(pFileStream, "[#%05d] [%s] %s%sn", m_count, strTime.c_str(), strIndentation.c_str(), strText.c_str());  
fclose(pFileStream); 
}
}

现在有时我的程序崩溃了。 使用 windbg 检查堆转储,这恰好发生在我在其中一个函数中调用 LOG_FUNCTION 宏的代码行中。这并不总是发生,当然,我也在没有发生此类崩溃的其他地方使用宏。仅在单个函数中(其中它是第一行):

void MyClass::SetInfoText(wstring& text)
{
LOG_FUNCTION;  // <= this is the place where windbg says it crashes
...
}

谁能对此有所了解?

编辑

上面添加了一些代码来显示声明记录器的位置

NULL_CLASS_PTR_DEREFERENCE表示带有指针this的东西是错误的 -thisNULL

如果在通过此 nullptrthis访问的第一个成员处在空指针上调用非虚拟成员函数,则可能会发生这种情况。

您需要在堆栈上后退一步,并确保这不会在调用方站点发生。