From: VMware, Inc <> Date: Mon, 26 Jul 2010 19:23:17 +0000 (-0700) Subject: lib/log: Formally handle the maximum message length X-Git-Tag: 2010.07.25-280253~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f735f387ed6bbafe388425fff5328f89a347f18e;p=thirdparty%2Fopen-vm-tools.git lib/log: Formally handle the maximum message length 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 --- diff --git a/open-vm-tools/lib/include/log.h b/open-vm-tools/lib/include/log.h index 47a02b428..a9be6850c 100644 --- a/open-vm-tools/lib/include/log.h +++ b/open-vm-tools/lib/include/log.h @@ -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 diff --git a/open-vm-tools/lib/lock/ulStats.c b/open-vm-tools/lib/lock/ulStats.c index f1ccaad90..e8739cc8c 100644 --- a/open-vm-tools/lib/lock/ulStats.c +++ b/open-vm-tools/lib/lock/ulStats.c @@ -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 }