When debugging CC, I try to enable all the TRACE() macros. Also, I have pass the "--debug-log-to-file" on the C::B startup options. When C::B hit a BP, I try to see the file "codeblocks-debug.log", it contains some partial logs, not the full logs.
I dig it further, and found that
/** a logger which prints messages to a file */
class DLLIMPORT FileLogger : public Logger
{
protected:
wxFFile f;
public:
FileLogger(const wxString& filename) : f(filename, _T("wb")) {};
FileLogger() {};
virtual void Append(const wxString& msg, cb_unused Logger::level lv)
{
fputs(wxSafeConvertWX2MB(msg), f.fp());
fputs(::newline_string.mb_str(), f.fp());
};
virtual void Open(const wxString& filename) { Close(); f.Open(filename, _T("wb")); };
virtual void Close(){ if(f.IsOpened()) f.Close(); };
};
Look, it use the standard C function to output, but once a message is append to the log file, it does not call "flush()" function.
I noticed that Morten use some similar method to enforce the flush in cclogger.cpp, (he just call f.Close() to ensure the flush of log message), see:
#define TRACE_TO_FILE(msg) \
if (g_EnableDebugTraceFile && !g_DebugTraceFile.IsEmpty()) \
{ \
wxTextFile f(g_DebugTraceFile); \
if ((f.Exists() && f.Open()) || (!f.Exists() && f.Create())) \
{ \
f.AddLine(msg); \
cbAssert(f.Write() && f.Close()); \
} \
} \
#define TRACE_THIS_TO_FILE(msg) \
if (!g_DebugTraceFile.IsEmpty()) \
{ \
wxTextFile f(g_DebugTraceFile); \
if ((f.Exists() && f.Open()) || (!f.Exists() && f.Create())) \
{ \
f.AddLine(msg); \
cbAssert(f.Write() && f.Close()); \
} \
}
For those who need to do real-time logging, flush() is needed, otherwise if C::B crashes/breaks, you only get some partial logs in codeblocks-debug.log file.
EDIT:
Even wx internally use buffer for logging, see:
http://docs.wxwidgets.org/trunk/overview_log.htmlStarting with wxWidgets 2.9.1, logging functions can be safely called from any thread. Messages logged from threads other than the main one will be buffered until wxLog::Flush() is called in the main thread (which usually happens during idle time, i.e. after processing all pending events) and will be really output only then. Notice that the default GUI logger already only output the messages when it is flushed, so by default messages from the other threads will be shown more or less at the same moment as usual. However if you define a custom log target, messages may be logged out of order, e.g. messages from the main thread with later timestamp may appear before messages with earlier timestamp logged from other threads. wxLog does however guarantee that messages logged by each thread will appear in order in which they were logged.
Also notice that wxLog::EnableLogging() and wxLogNull class which uses it only affect the current thread, i.e. logging messages may still be generated by the other threads after a call to EnableLogging(false).