Depuración del programa MFC que llama a C DLL usando fprintf

I have an MFC program which calls a C dll that crashes in release, but not in debug. I have tried using fprintf to write messages to a file, and this works for the first pass through the program. However, the program crashes the second time the program runs a calculation.

I close the debug log file immediately after writing to it as the first executable statements at the top of the C routine. Info is written to the log file after the first calculation, but not during the 2nd calculation.

¿Alguna sugerencia?

preguntado el 31 de julio de 12 a las 14:07

Some code sample maybe ? -

I have found that I can add the following code: FILE *fp; fp = fopen("c:\\temp\\debugP2.txt","w"); to the top of the offending routine to open a file, and then move this code: fprintf(fp, "check P22\r\n"); fclose(fp); line by line down through routine to debug. If the "check P22" does not get written to the file, then I have passed the point where the bug exists. It is just cumbersome, because the file has to be closed before the bug is hit, or nothing gets written to the file. This is not true of FORTRAN. -

This is not strange, you mush do the "fflush(fp)" before closing the file to ensure there is nothing left in the buffer. Also check the "fp" for not being NULL. -

Thanks Viktor. By placing a "fflush(fp)" after each "fprintf" statement I can ensure that all information is written to the log file before a crash. Mike -

1 Respuestas

When working with this type of a problem in which I need to have a logging facility I typically will write a function that I call for the logging. I then wrap the function in a macro which allows me to enable or disable the logging. As part of this I will sometimes use a debug level indicator as well so that not all logs will be put into the log file.

The logging functions would be in a file by themselves as a separate, small library. There would be an include file that would contain the logging library function prototypes and a macro to enable or disable the logging.

I have found that there are some things that may be helpful for logs depending on the type of application such as time stamping each log to the second or to the millisecond. I have also found that having a standard line length makes reviewing the log a lot easier in a text editor. Having some idea of the source file's path as well as the source line number can be very helpful.

The following code is written free hand and has not been tested or even compiled so there may be an error or two in it.

The actual logging function, lets call it LogWriteLog() would be wrapped in a macro as follows:

#define LOGISSUELOG(level,logtext)  LogWriteLog(level, logtext, __FILE__, __LINE__);

By using a macro you can enable or disable the logging by changing the macro definition. This macro will also automatically generate the source file's path and the source line number of the log.

For this I will sometimes wrap this into the following preprocessor code sequence when I want to have variables as part of my log. The braces allow the multiple lines to be inserted in place in the source and have a char variable of local scope.

#if defined(LOGISSUELOG)
{
    char  xBuff[128];
    sprintf (xBuff, "value 1 %d, error %d", iValue, iErrorStatus);
    LOGISSUELOG(4, xBuff);
}
#endif

The simple logging library would have only a couple of functions, one to open the log file and specify the debug level, a second to actually do a log, and the third to close the logging file when done.

Using the standard C I/O routines the actual logging functions would look something like the following. You will need string.h y stdio.h for this as well. Also you may want to consider whether to truncate the file each time you restart or if you want to do an append to the file.

I have also done this be checking the file size and when it reaches a certain size to fseek () to the beginning of the file to wrap around. If you are doing wrap around, a time stamp becomes almost a necessity. If doing a wraparound really makes the standard line width for all log lines to be necessary so that things line up.

    // 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;
    }

Respondido 10 ago 12, 02:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.