我有一个MFC程序调用C dll在发布时崩溃,但不在调试中崩溃。我已经尝试使用fprintf将消息写入文件,这适用于第一次通过程序。但是,程序第二次运行计算时程序崩溃。
我在写入调试日志文件之后立即将其作为C例程顶部的第一个可执行语句关闭。第一次计算后,信息将写入日志文件,但在第二次计算时不会写入。
有什么建议吗?
答案 0 :(得分:0)
当处理我需要具有日志记录功能的这类问题时,我通常会编写一个我要求记录的函数。然后我将函数包装在一个宏中,允许我启用或禁用日志记录。作为其中的一部分,我有时也会使用调试级别指示器,以便不会将所有日志都放入日志文件中。
日志记录功能本身就是一个独立的小型库。将有一个包含日志库函数原型的包含文件和一个用于启用或禁用日志记录的宏。
我发现有些东西可能对日志有所帮助,具体取决于应用程序的类型,例如将每个日志标记为秒或毫秒。我还发现,使用标准行长度可以在文本编辑器中更轻松地查看日志。了解源文件的路径以及源行号可能非常有用。
以下代码是自由编写的,尚未经过测试甚至编译,因此可能存在错误或两个错误。
实际的日志记录功能,让我们调用它LogWriteLog()
将被包装在一个宏中,如下所示:
#define LOGISSUELOG(level,logtext) LogWriteLog(level, logtext, __FILE__, __LINE__);
通过使用宏,您可以通过更改宏定义来启用或禁用日志记录。该宏还将自动生成源文件的路径和日志的源行号。
为此,当我想将变量作为日志的一部分时,我有时将其包装到下面的预处理器代码序列中。大括号允许多行插入源中并具有局部作用域的char变量。
#if defined(LOGISSUELOG)
{
char xBuff[128];
sprintf (xBuff, "value 1 %d, error %d", iValue, iErrorStatus);
LOGISSUELOG(4, xBuff);
}
#endif
简单的日志记录库只有几个函数,一个用于打开日志文件并指定调试级别,另一个用于实际执行日志,第三个用于在完成后关闭日志文件。
使用标准C I / O例程,实际的日志记录功能如下所示。您也需要string.h
和stdio.h
。此外,您可能需要考虑每次重新启动时是否截断文件,或者是否要对文件进行追加。
我还做了这个,检查文件大小,当它达到一定大小到fseek ()
到文件的开头以便回绕。如果你正在进行环绕,时间戳几乎是必需的。如果进行环绕确实使得所有日志行的标准线宽都是必要的,那么事情就会排成一行。
// allocate the file scope globals used by the logging library
static FILE *fpLogWriteLog = 0;
static int iLogDebugLevel = 0;
int LogOpenLog (int iDebugLevel, char *aszLogFilePath)
{
// open the log file for writing, truncating what is there already
fpLogWriteLog = fopen (aszLogFilePath, "w");
iLogDebugLevel = iDebugLevel;
return (fpLogWriteLog == 0) ? 0 : 1;
}
void LogCloseLog (void)
{
if (fpLogWriteLog)
fclose (fpLogWriteLog);
}
// allow the debug logging level to be changed.
//return the current value so that it can be used in another call to set it back.
int LogChangeLogLevel (int iDebugLevelNew)
{
int iDebugLevelSave = iLogDebugLevel;
iLogDebugLevel = iDebugLevelNew;
return iDebugLevelSave;
}
// write a log to the log file
int LogWriteLog (int iDebugLevel, char *aszLogText, char *aszFileName, int iLineNo)
{
int iRetStatus = 0;
if (fpLogWriteLog && iDebugLevel < iLogDebugLevel) {
int iLen = strlen (aszFileName);
// we will keep only the last 30 characters of the source file path
if (iLen > 30)
iLen = 30;
else
iLen = 0;
// use print specifiers to provide the same line width for the output log
// use %-60.60s to print log text in case of print format specifiers in it
fprintf (fpLogWriteLog, "%3.3d %-30.30s - %6.6d: %-60.60s", iDebugLevel, aszFileName + iLen, iLineNo, aszLogText);
fflush (fpLogWriteLog);
iRetStatus = 1;
}
return iRetStatus;
}