Now I am working on this fair scheduling for my B Tech Project (BTP). Already having written a 1000 lines of code, it is a great pain to debug it. More so if you do not know which function might have caused the error. I needed a logger which could log all the events. The events include entering a function, any important calculation/decision it makes, any return values, so that if my program breaks down I can exactly pinpoint the source of error simply looking at the log file generated.
I have no idea if any inbuilt logging functionality exists for C programs or not. Either way, I did not have much time to google up and learn how to use it. I decided to make my own logger, a simple one, which would serve my purpose. It hardly took me 10 minutes to get over with it.
One of the important functionalities that I wanted my logger to have is indentation. The log should be properly indented, just the same way as we indent the code. When the program control enters a new function, the logging should get indented to right, and when it leaves the function, the logging should get indented by the same amount to the left. So I defined two macros, $$INDENT$$ and $$OUTDENT$$. To make them work, I defined a global variable – $$logIndent$$. The $$logIndent$$ would at any given time contain the amount of space by which the log has to be indented. Obviously, I initialized it with 0. Also defined is a global variable called $$indentVal$$ which is the amount of spaces with which the indentation should take place. I like the value to be 2. The two macros are
#define INDENT logIndent += indentVal
#define OUTDENT logIndent -= indentVal
int indentVal = 2;
int logIndent = 0;
I defined another macro called $$SPACES$$ which would print the number of spaces to produce the required indentation.
int tempIndent;
FILE *logFile;
#define SPACES for(tempIndent = 0; tempIndent < logIndent; tempIndent++) fprintf(logFile, " ");
Obviously $$tempIndent$$ is a globally declared temporary variable and $$logFile$$ is the file pointer to the file where the log has to be written. I initialize the $$logFile$$ pointer in the $$main()$$ part of my program.
And finally coming to the logger, I created a custom $$printf()$$ statement using the $$vprintf()$$ command. I call my logger as $$LogThis()$$. Its declaration is as follows
void LogThis(const char *format, ...);
It is constructed as follows
void LogThis(const char *format, ...) {
va_list args;
va_start(args, format);
SPACES;
vfprintf(logFile, format, args);
va_end(args);
}
That’s it ! To use this logger, I have to do the following in my function :
#include <stdio .h>
#include <stdarg .h>
void TestLogger() {
int returnVal;
float retVal;
LogThis("<testlogger>\n");
INDENT;
/**
* Inside the function do whatever you want to
*/
LogThis("Returns: %d, %f\n", retrunVal, retVal)
OUTDENT;
LogThis("</testlogger>\n");
}
Done ! A well indented log will be produced. This has really helped me debug the code. I do not have to gdb from the last point that worked in my program. Instead, I know which function the program control was in when it threw an error. I need to gdb from that function onwards only, thus reducing the debuging time considerably. Also, in case of errors, I can increase the debugging data for that particular function, thus eliminating the need to use gdb at all.
Popularity: 5% [?]