Bug 693101 - Unbreak about:memory's parsing of /proc/smaps entries which live in /dev/ashmem on Android. r=khuey
authorJustin Lebar <justin.lebar@gmail.com>
Mon, 10 Oct 2011 11:10:50 -0400
changeset 78436 8e85383d821eb5d38c9fea754384ac271e4180ec
parent 78435 17eecce51c43cd1e9f44bb502312db9ec47aa9b1
child 78490 8692821e87e1f370c5bfd9df61023605fcd6a67b
push id2542
push userjlebar@mozilla.com
push dateMon, 10 Oct 2011 15:15:10 +0000
treeherdermozilla-inbound@8e85383d821e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs693101
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 693101 - Unbreak about:memory's parsing of /proc/smaps entries which live in /dev/ashmem on Android. r=khuey
xpcom/base/MapsMemoryReporter.cpp
--- a/xpcom/base/MapsMemoryReporter.cpp
+++ b/xpcom/base/MapsMemoryReporter.cpp
@@ -95,23 +95,34 @@ void GetDirname(const nsCString &aPath, 
   }
   else {
     aOut.Assign(Substring(aPath, 0, idx));
   }
 }
 
 void GetBasename(const nsCString &aPath, nsACString &aOut)
 {
+  nsCString out;
   PRInt32 idx = aPath.RFind("/");
   if (idx == -1) {
-    aOut.Assign(aPath);
+    out.Assign(aPath);
   }
   else {
-    aOut.Assign(Substring(aPath, idx + 1));
+    out.Assign(Substring(aPath, idx + 1));
   }
+
+  // On Android, some entries in /dev/ashmem end with "(deleted)" (e.g.
+  // "/dev/ashmem/libxul.so(deleted)").  We don't care about this modifier, so
+  // cut it off when getting the entry's basename.
+  if (EndsWithLiteral(out, "(deleted)")) {
+    out.Assign(Substring(out, 0, out.RFind("(deleted)")));
+  }
+  out.StripChars(" ");
+
+  aOut.Assign(out);
 }
 
 // MapsReporter::CollectReports uses this stuct to keep track of whether it's
 // seen a mapping under 'map/resident', 'map/vsize', and 'map/swap'.
 struct CategoriesSeen {
   CategoriesSeen() :
     mSeenResident(false),
     mSeenPss(false),
@@ -221,18 +232,19 @@ MapsReporter::CollectReports(nsIMemoryMu
 
 nsresult
 MapsReporter::FindLibxul()
 {
   mLibxulDir.Truncate();
 
   // Note that we're scanning /proc/self/*maps*, not smaps, here.
   FILE *f = fopen("/proc/self/maps", "r");
-  if (!f)
+  if (!f) {
     return NS_ERROR_FAILURE;
+  }
 
   while (true) {
     // Skip any number of non-slash characters, then capture starting with the
     // slash to the newline.  This is the path part of /proc/self/maps.
     char path[1025];
     int numRead = fscanf(f, "%*[^/]%1024[^\n]", path);
     if (numRead != 1) {
       break;
@@ -261,19 +273,19 @@ MapsReporter::ParseMapping(
   nsISupports *aClosure,
   CategoriesSeen *aCategoriesSeen)
 {
   // We need to use native types in order to get good warnings from fscanf, so
   // let's make sure that the native types have the sizes we expect.
   PR_STATIC_ASSERT(sizeof(long long) == sizeof(PRInt64));
   PR_STATIC_ASSERT(sizeof(int) == sizeof(PRInt32));
 
-  if (mLibxulDir.IsEmpty()) {
-    NS_ENSURE_SUCCESS(FindLibxul(), NS_ERROR_FAILURE);
-  }
+  // Don't bail if FindLibxul fails.  We can still gather meaningful stats
+  // here.
+  FindLibxul();
 
   // The first line of an entry in /proc/self/smaps looks just like an entry
   // in /proc/maps:
   //
   //   address           perms offset  dev   inode  pathname
   //   02366000-025d8000 rw-p 00000000 00:00 0      [heap]
 
   const int argCount = 8;
@@ -357,27 +369,26 @@ MapsReporter::GetReporterNameAndDescript
     aName.Append("vdso");
     aDesc.Append("The virtual dynamically-linked shared object, also known as "
                  "the 'vsyscall page'. This is a memory region mapped by the "
                  "operating system for the purpose of allowing processes to "
                  "perform some privileged actions without the overhead of a "
                  "syscall.");
   }
   else if (!basename.IsEmpty()) {
-    NS_ASSERTION(!mLibxulDir.IsEmpty(), "mLibxulDir should not be empty.");
-
     nsCAutoString dirname;
     GetDirname(absPath, dirname);
 
     // Hack: A file is a shared library if the basename contains ".so" and its
     // dirname contains "/lib", or if the basename ends with ".so".
     if (EndsWithLiteral(basename, ".so") ||
         (basename.Find(".so") != -1 && dirname.Find("/lib") != -1)) {
       aName.Append("shared-libraries/");
-      if (dirname.Equals(mLibxulDir) || mMozillaLibraries.Contains(basename)) {
+      if ((!mLibxulDir.IsEmpty() && dirname.Equals(mLibxulDir)) ||
+          mMozillaLibraries.Contains(basename)) {
         aName.Append("shared-libraries-mozilla/");
       }
       else {
         aName.Append("shared-libraries-other/");
       }
     }
     else {
       aName.Append("other-files/");