summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2011-06-30 10:12:45 -0400
committerNat Goodspeed <nat@lindenlab.com>2011-06-30 10:12:45 -0400
commitb75eedb0dce0c6b11e248c4f244e0020a5b97a42 (patch)
tree5a082428b5970c67c0119045f684f5ca709dfc3d
parent21ff3d0d1ce10446cbb1cf9bc08d2c0ebe9705fe (diff)
CHOP-753: Fix errors in LLMemoryInfo Mac-specific code.
Handle conversion errors (boost::bad_lexical_cast). Glean additional LLSD statistics from vm_stat output.
-rw-r--r--indra/llcommon/llsys.cpp93
1 files changed, 73 insertions, 20 deletions
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 2897a533d9..e4404f31c7 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -50,6 +50,7 @@
#include <boost/regex.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
+#include <boost/range.hpp>
using namespace llsd;
@@ -955,7 +956,8 @@ LLMemoryInfo& LLMemoryInfo::refresh()
boost::regex pagesize_rx("\\(page size of ([0-9]+) bytes\\)");
boost::regex stat_rx("(.+): +([0-9]+)\\.");
- boost::regex pages_rx("Pages ");
+ boost::regex cache_rx("Object cache: ([0-9]+) hits of ([0-9]+) lookups "
+ "\\(([0-9]+)% hit rate\\)");
boost::cmatch matched;
LLSD::Integer pagesizekb(4096/1024);
@@ -970,41 +972,81 @@ LLMemoryInfo& LLMemoryInfo::refresh()
{
line[--linelen] = '\0';
}
- if (boost::regex_search(&line[0], line+linelen, matched, pagesize_rx))
+ if (boost::regex_search(line, matched, pagesize_rx))
{
// "Mach Virtual Memory Statistics: (page size of 4096 bytes)"
std::string pagesize_str(matched[1].first, matched[1].second);
- // Reasonable to assume that pagesize will always be a
- // multiple of 1Kb?
- pagesizekb = boost::lexical_cast<LLSD::Integer>(pagesize_str)/1024;
+ try
+ {
+ // Reasonable to assume that pagesize will always be a
+ // multiple of 1Kb?
+ pagesizekb = boost::lexical_cast<LLSD::Integer>(pagesize_str)/1024;
+ }
+ catch (const boost::bad_lexical_cast&)
+ {
+ LL_WARNS("LLMemoryInfo") << "couldn't parse '" << pagesize_str
+ << "' in vm_stat line: " << line << LL_ENDL;
+ continue;
+ }
+ mData.append(LLSDArray("page size")(pagesizekb));
}
- else if (boost::regex_match(&line[0], line+linelen, matched, stat_rx))
+ else if (boost::regex_match(line, matched, stat_rx))
{
// e.g. "Pages free: 462078."
// Strip double-quotes off certain statistic names
- if (matched[1].first[0] == '"' && matched[1].second[-1] == '"')
+ const char *key_begin(matched[1].first), *key_end(matched[1].second);
+ if (key_begin[0] == '"' && key_end[-1] == '"')
{
- ++matched[1].first;
- --matched[1].second;
+ ++key_begin;
+ --key_end;
}
- LLSD::String key(matched[1].first, matched[1].second);
+ LLSD::String key(key_begin, key_end);
LLSD::String value_str(matched[2].first, matched[2].second);
- LLSD::Integer value(boost::lexical_cast<LLSD::Integer>(value_str));
+ LLSD::Integer value(0);
+ try
+ {
+ value = boost::lexical_cast<LLSD::Integer>(value_str);
+ }
+ catch (const boost::bad_lexical_cast&)
+ {
+ LL_WARNS("LLMemoryInfo") << "couldn't parse '" << value_str
+ << "' in vm_stat line: " << line << LL_ENDL;
+ continue;
+ }
// Store this statistic.
mData.append(LLSDArray(key)(value));
// Is this in units of pages? If so, convert to Kb.
- // boost::regex_match() doc sez: "If you want to match a
- // prefix of the character string then use regex_search with
- // the flag match_continuous set."
- boost::smatch smatched;
- if (boost::regex_search(key, smatched, pages_rx, boost::match_continuous))
+ static const LLSD::String pages("Pages ");
+ if (key.substr(0, pages.length()) == pages)
{
- // Synthesize a new key with kB in place of Pages
- LLSD::String kbkey("kB ");
- kbkey.append(smatched[0].second, key.end());
+ // Synthesize a new key with kb in place of Pages
+ LLSD::String kbkey("kb ");
+ kbkey.append(key.substr(pages.length()));
mData.append(LLSDArray(kbkey)(value * pagesizekb));
}
}
+ else if (boost::regex_match(line, matched, cache_rx))
+ {
+ // e.g. "Object cache: 841598 hits of 7629869 lookups (11% hit rate)"
+ static const char* cache_keys[] = { "cache hits", "cache lookups", "cache hit%" };
+ std::vector<LLSD::Integer> cache_values;
+ for (size_t i = 0; i < (sizeof(cache_keys)/sizeof(cache_keys[0])); ++i)
+ {
+ LLSD::String value_str(matched[i+1].first, matched[i+1].second);
+ LLSD::Integer value(0);
+ try
+ {
+ value = boost::lexical_cast<LLSD::Integer>(value_str);
+ }
+ catch (boost::bad_lexical_cast&)
+ {
+ LL_WARNS("LLMemoryInfo") << "couldn't parse '" << value_str
+ << "' in vm_stat line: " << line << LL_ENDL;
+ continue;
+ }
+ mData.append(LLSDArray(cache_keys[i])(value));
+ }
+ }
else
{
LL_WARNS("LLMemoryInfo") << "unrecognized vm_stat line: " << line << LL_ENDL;
@@ -1055,7 +1097,18 @@ LLMemoryInfo& LLMemoryInfo::refresh()
// e.g. "MemTotal: 4108424 kB"
LLSD::String key(matched[1].first, matched[1].second);
LLSD::String value_str(matched[2].first, matched[2].second);
- LLSD::Integer value(boost::lexical_cast<LLSD::Integer>(value_str));
+ LLSD::Integer value(0);
+ try
+ {
+ value = boost::lexical_cast<LLSD::Integer>(value_str);
+ }
+ catch (const boost::bad_lexical_cast&)
+ {
+ LL_WARNS("LLMemoryInfo") << "couldn't parse '" << value_str
+ << "' in " << MEMINFO_FILE << " line: "
+ << line << LL_ENDL;
+ continue;
+ }
// Store this statistic.
mData.append(LLSDArray(key)(value));
}