Gentlemen,

The patch below fixes a crash which could occur during startup on some 
platforms, immediatly following this message:

00:15:05: [INI] Starting plugin Qt GUI (version 1.1.0).

The problem is that it is not portable to call multiple v[*]printf 
functions on the same va_list pointer after initializing it with 
va_start(). However, the CLogServer will do this when multiple 
CLogServices are registered, so it crashes trying to handle the first 
log message after the GUI plugin starts. 

The crash does not occur on x86 linux, but is a problem for PPC Linux 
and most likely other platforms as well depending on the way varargs are 
implemented.

This solution moves the vsnprintf() from CLogService::lprintf() to 
CLogServer::Log(), which ensures that it is only called once for a given 
va_list. It should not effect functionality at all. I renamed the 
CLogService::lprintf to LogMessage() to reflect the change.

regards,

Bryce.



diff -ur licq-20020209-orig/include/licq_log.h licq-20020209/include/licq_log.h
--- licq-20020209-orig/include/licq_log.h       Fri Nov 30 12:11:12 2001
+++ licq-20020209/include/licq_log.h    Mon Feb 11 23:50:11 2002
@@ -42,6 +42,7 @@
 const unsigned short S_STDOUT   = 1;
 const unsigned short S_FILE     = 2;
 const unsigned short S_PLUGIN   = 4;
+const unsigned short S_ALL     = S_STDOUT | S_FILE | S_PLUGIN;
 
 const unsigned short LOG_PREFIX_OFFSET = 10;
 
@@ -53,8 +54,8 @@
 {
 public:
   CLogService(unsigned short _nLogTypes);
-  virtual void lprintf(unsigned short _nLogType, const char *_szPrefix,
-                       const char *_szFormat, va_list argp) = 0;
+  virtual void LogMessage(const char *_szPrefix, const char *_szMessage, 
+                         unsigned short _nLogType) = 0;
   void SetLogTypes(unsigned short _nLogTypes);
   unsigned short ServiceType();
   unsigned short LogType(unsigned short _nLogType);
@@ -78,8 +79,8 @@
 {
 public:
   CLogService_StdOut(unsigned short _nLogTypes, bool _bUseColor);
-  virtual void lprintf(unsigned short _nLogType, const char *_szPrefix,
-                       const char *_szFormat, va_list argp);
+  virtual void LogMessage(const char *_szPrefix, const char *_szMessage, 
+                         unsigned short _nLogType);
 protected:
   bool m_bUseColor;
 };
@@ -91,8 +92,8 @@
 public:
    CLogService_File(unsigned short _nLogTypes);
    bool SetLogFile(const char *_szFile, const char *_szFlags);
-   virtual void lprintf(unsigned short _nLogType, const char *_szPrefix,
-                        const char *_szFormat, va_list argp);
+   virtual void LogMessage(const char *_szPrefix, const char *_szMessage, 
+                          unsigned short _nLogType);
 protected:
    FILE *m_fLog;
 };
@@ -121,8 +122,8 @@
   CLogService_Plugin(CPluginLog *_xWindow, unsigned short _nLogTypes);
   bool SetLogWindow(CPluginLog *_xWindow);
   CPluginLog *LogWindow() { return m_xLogWindow; }
-  virtual void lprintf(unsigned short _nLogType, const char *_szPrefix,
-                       const char *_szFormat, va_list argp);
+  virtual void LogMessage(const char *_szPrefix, const char *_szMessage, 
+                         const unsigned short _nLogType);
 protected:
   CPluginLog *m_xLogWindow;
 };

diff -ur licq-20020209-orig/src/log.cpp licq-20020209/src/log.cpp
--- licq-20020209-orig/src/log.cpp      Fri Nov 30 12:11:15 2001
+++ licq-20020209/src/log.cpp   Mon Feb 11 23:48:56 2002
@@ -97,16 +97,15 @@
 }
 
 
-
-inline
-void CLogService_StdOut::lprintf(unsigned short _nLogType, const char *_szPrefix,
-                                 const char *_szFormat, va_list argp)
+void CLogService_StdOut::LogMessage(const char *_szPrefix, 
+                                   const char *_szMessage,
+                                   const unsigned short _nLogType)
 {
   if (m_bUseColor)
     printf("%s%s%s", COLOR_PREFIX, _szPrefix, COLOR_MSG[_nLogType == L_MESSAGE ? 
L_INFO : _nLogType]);
   else
     printf("%s", _szPrefix);
-  vprintf(_szFormat, argp);
+  printf("%s", _szMessage);
   if (m_bUseColor) printf("%s", COLOR_NORMAL);
   fflush(stdout);
 }
@@ -128,13 +127,12 @@
    return (m_fLog != NULL);
 }
 
-inline
-void CLogService_File::lprintf(unsigned short _nLogType, const char *_szPrefix,
-                               const char *_szFormat, va_list argp)
+void CLogService_File::LogMessage(const char *_szPrefix, 
+                                 const char *_szMessage,
+                                 const unsigned short _nLogType)
 {
   if (m_fLog == NULL) return;
-  fprintf(m_fLog, "%s", _szPrefix);
-  vfprintf(m_fLog, _szFormat, argp);
+  fprintf(m_fLog, "%s%s", _szPrefix, _szMessage);
   fflush(m_fLog);
   // Avoid warnings
   if (_nLogType);
@@ -196,16 +194,15 @@
    return true;
 }
 
-inline
-void CLogService_Plugin::lprintf(unsigned short _nLogType, const char *_szPrefix,
-                                 const char *_szFormat, va_list argp)
+void CLogService_Plugin::LogMessage(const char *_szPrefix, 
+                                   const char *_szMessage,
+                                   const unsigned short _nLogType)
 {
   static char szMsgMax[MAX_MSG_SIZE];
 
   if (m_xLogWindow == NULL) return;
 
-  unsigned n = sprintf(szMsgMax, "%s", _szPrefix);
-  vsnprintf(&szMsgMax[n], (MAX_MSG_SIZE - n - 1), _szFormat, argp);
+  snprintf(szMsgMax, MAX_MSG_SIZE, "%s%s", _szPrefix, _szMessage);
   szMsgMax[MAX_MSG_SIZE - 1] = '\0';
   m_xLogWindow->AddLog(strdup(szMsgMax), _nLogType);
 }
@@ -390,30 +387,14 @@
 
 void CLogServer::Log(const unsigned short _nLogType, const char *_szFormat, va_list 
argp)
 {
-  static char szTime[32];
-  static struct tm stm;
-
-  pthread_mutex_lock(&mutex);
-
-  // Create a time string for the log
-  time_t t = time(NULL);
-  localtime_r(&t, &stm);
-  strftime(szTime, 32, "%T: ", &stm);
-
-  // Log the event to each server
-  vector<CLogService *>::iterator iter;
-  for (iter = m_vxLogServices.begin(); iter != m_vxLogServices.end(); iter++)
-  {
-    if ((*iter)->LogType(_nLogType))
-        (*iter)->lprintf(_nLogType, szTime, _szFormat, argp);
-  }
-  pthread_mutex_unlock(&mutex);
+  CLogServer::Log(S_ALL, _nLogType, _szFormat, argp);
 }
 
 void CLogServer::Log(const unsigned short _nServiceTypes, const unsigned short 
_nLogType, const char *_szFormat, va_list argp)
 {
   static char szTime[32];
   static struct tm stm;
+  static char szMsgMax[MAX_MSG_SIZE];
 
   pthread_mutex_lock(&mutex);
 
@@ -422,13 +403,16 @@
   localtime_r(&t, &stm);
   strftime(szTime, 32, "%T: ", &stm);
 
+  vsnprintf(szMsgMax, MAX_MSG_SIZE, _szFormat, argp);
+  szMsgMax[MAX_MSG_SIZE - 1] = '\0';
+
   // Log the event to each server
   vector<CLogService *>::iterator iter;
   for (iter = m_vxLogServices.begin(); iter != m_vxLogServices.end(); iter++)
   {
     if ((*iter)->LogType(_nLogType) || (*iter)->ServiceType() & _nServiceTypes)
-        (*iter)->lprintf(_nLogType, szTime, _szFormat, argp);
-  }
+        (*iter)->LogMessage(szTime, szMsgMax, _nLogType);
+  }  
   pthread_mutex_unlock(&mutex);
 }

Reply via email to