]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
lib/log: Formally handle the maximum message length
authorVMware, Inc <>
Mon, 26 Jul 2010 19:23:17 +0000 (12:23 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 26 Jul 2010 19:23:17 +0000 (12:23 -0700)
Provide a way to ask what the maximum message length is. Use it
to avoid creating a line too long within the MXUser lock statistics
code.

With a bit of minor code rearranging, only a single, full-sized
message buffer needs to be kept on the stack to log a message.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/include/log.h
open-vm-tools/lib/lock/ulStats.c

index 47a02b428ba9ec79ab7a2374ced26887f44a73d6..a9be6850cdd019b124ffec5ebbe20b444abe8865 100644 (file)
@@ -79,6 +79,8 @@ Bool Log_SwitchFile(const char *fileName, const char *config, Bool copy);
 Bool Log_CopyFile(const char *fileName);
 
 size_t Log_MakeTimeString(Bool millisec, char *buf, size_t max);
+uint32 Log_MaxLineLength(void);
+
 
 void LogV(const char *fmt, va_list args);
 void WarningV(const char *fmt, va_list args);
@@ -122,8 +124,6 @@ void GuestLog_Log(const char *fmt, ...) PRINTF_DECL(1, 2);
 
 #define LOG_DEFAULT_THROTTLE_THRESHOLD 1000000
 
-#define LOG_MAX_MSG_SIZE (12 * 1024)
-
 
 /*
  * Debugging
index f1ccaad90c0e75136f7bcc724d81508500e6151e..e8739cc8c6ef194e920b5eb1529af2e9b9921906 100644 (file)
@@ -300,40 +300,69 @@ MXUserHistoDump(MXUserHisto *histo,    // IN:
 
 #if defined(MXUSER_STATS)
    if (histo->totalSamples) {
+      char *p;
       uint32 i;
-      char histoData[LOG_MAX_MSG_SIZE];
+      uint32 spaceLeft;
 
-      char *p = histoData;
-      uint32 numEntries = 0;
-      uint32 spaceLeft = sizeof(histoData) - 1;
+      static uint32 maxLine = 0;
+      static char *histoLine = NULL;
 
-      histoData[0] = '\0';
+      /*
+       * Statistics are reported from a single thread. This avoids allocating
+       * a potentially large buffer on the stack.
+       */ 
+
+      if (maxLine == 0) {
+         maxLine = Log_MaxLineLength();  // includes terminating NUL
+         ASSERT(maxLine >= 1024);        // assert a rational minimum
+
+         histoLine = Util_SafeMalloc(maxLine);
+      }
+
+      i = Str_Sprintf(histoLine, maxLine,
+                      "MXUser: h l=%u t=%s min=%"FMT64"u max=%"FMT64"u\n",
+                      header->identifier, histo->typeName, histo->minValue,
+                      histo->maxValue);
 
+      /*
+       * The terminating "\n\0" will be overwritten each time a histogram
+       * bin is added to the line. This will ensure that the line is always
+       * properly terminated no matter what happens.
+       */
+
+      p = &histoLine[i - 1];
+      spaceLeft = maxLine - i - 2;
+
+      /* Add as many histogram bins as possible within the line limitations */
       for (i = 0; i < histo->numBins; i++) {
          if (histo->binData[i] != 0) {
             uint32 len;
             char binEntry[32];
 
-            Str_Sprintf(binEntry, sizeof(binEntry), " %u-%"FMT64"u",
+            Str_Sprintf(binEntry, sizeof binEntry, " %u-%"FMT64"u\n",
                         i, histo->binData[i]);
 
             len = strlen(binEntry);
 
             if (len < spaceLeft) {
+               /*
+                * Append the bin number, bin count pair to the end of the
+                * string. This includes the terminating "\n\0". Update the
+                * pointer to the next free place to point to the '\n'. If
+                * another entry is made, things work out properly. If not
+                * the string is properly terminated as a line.
+                */
+
                Str_Strcpy(p, binEntry, len + 1);
-               p += len;
+               p += len - 1;
                spaceLeft -= len;
-
-               numEntries++;
             } else {
                break;
             }
          }
       }
 
-      StatsLog("MXUser: h l=%u t=%s min=%"FMT64"u max=%"FMT64"u n=%u %s\n",
-                header->identifier, histo->typeName, histo->minValue,
-                histo->maxValue, numEntries, histoData);
+      StatsLog(histoLine);
    }
 #endif
 }