Bug 1533531 - Make NSPRIOInterposer report filenames, r=aklotz.
authorFlorian Quèze <florian@queze.net>
Fri, 08 Mar 2019 12:28:12 +0000
changeset 521028 fa25d5068254
parent 521027 33c69b500eed
child 521029 d689ce995f0a
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1533531
milestone67.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 1533531 - Make NSPRIOInterposer report filenames, r=aklotz. Differential Revision: https://phabricator.services.mozilla.com/D22585
xpcom/build/NSPRInterposer.cpp
--- a/xpcom/build/NSPRInterposer.cpp
+++ b/xpcom/build/NSPRInterposer.cpp
@@ -7,87 +7,132 @@
 #include "IOInterposer.h"
 #include "NSPRInterposer.h"
 
 #include "prio.h"
 #include "private/pprio.h"
 #include "nsDebug.h"
 #include "nscore.h"
 
+#include <sys/param.h>
+#ifdef XP_MACOSX
+#include <fcntl.h>
+#else
+#include "prprf.h"
+#include <unistd.h>
+#endif
+
 namespace {
 
 using namespace mozilla;
 
 /* Original IO methods */
 PRCloseFN sCloseFn = nullptr;
 PRReadFN sReadFn = nullptr;
 PRWriteFN sWriteFn = nullptr;
 PRFsyncFN sFSyncFn = nullptr;
 PRFileInfoFN sFileInfoFn = nullptr;
 PRFileInfo64FN sFileInfo64Fn = nullptr;
 
+static int32_t GetPathFromFd(int32_t aFd, char *aBuf, size_t aBufSize) {
+#ifdef XP_MACOSX
+  NS_ASSERTION(aBufSize >= MAXPATHLEN,
+               "aBufSize should be a least MAXPATHLEN long");
+
+  return fcntl(aFd, F_GETPATH, aBuf);
+#else
+  char procPath[32];
+  if (PR_snprintf(procPath, sizeof(procPath),
+                  "/proc/self/fd/%i", aFd) == (PRUint32)-1) {
+    return -1;
+  }
+
+  int32_t ret = readlink(procPath, aBuf, aBufSize - 1);
+  if (ret > -1) {
+    aBuf[ret] = '\0';
+  }
+
+  return ret;
+#endif
+}
+
 /**
  * RAII class for timing the duration of an NSPR I/O call and reporting the
  * result to the IOInterposeObserver API.
  */
 class NSPRIOAutoObservation : public IOInterposeObserver::Observation {
  public:
-  explicit NSPRIOAutoObservation(IOInterposeObserver::Operation aOp)
-      : IOInterposeObserver::Observation(aOp, "NSPRIOInterposer") {}
+  explicit NSPRIOAutoObservation(IOInterposeObserver::Operation aOp,
+                                 PRFileDesc *aFd)
+      : IOInterposeObserver::Observation(aOp, "NSPRIOInterposer") {
+    char filename[MAXPATHLEN];
+    if (mShouldReport && aFd &&
+        GetPathFromFd(PR_FileDesc2NativeHandle(aFd), filename,
+                      sizeof(filename)) != -1) {
+      mFilename = NS_ConvertUTF8toUTF16(filename);
+    } else {
+      mFilename.Truncate();
+    }
+  }
+
+  void Filename(nsAString& aFilename) override { aFilename = mFilename; }
 
   ~NSPRIOAutoObservation() override { Report(); }
+
+ private:
+  nsString mFilename;
 };
 
 PRStatus PR_CALLBACK interposedClose(PRFileDesc* aFd) {
   // If we don't have a valid original function pointer something is very wrong.
   NS_ASSERTION(sCloseFn, "NSPR IO Interposing: sCloseFn is NULL");
 
-  NSPRIOAutoObservation timer(IOInterposeObserver::OpClose);
+  NSPRIOAutoObservation timer(IOInterposeObserver::OpClose, aFd);
   return sCloseFn(aFd);
 }
 
 int32_t PR_CALLBACK interposedRead(PRFileDesc* aFd, void* aBuf, int32_t aAmt) {
   // If we don't have a valid original function pointer something is very wrong.
   NS_ASSERTION(sReadFn, "NSPR IO Interposing: sReadFn is NULL");
 
-  NSPRIOAutoObservation timer(IOInterposeObserver::OpRead);
+  NSPRIOAutoObservation timer(IOInterposeObserver::OpRead, aFd);
   return sReadFn(aFd, aBuf, aAmt);
 }
 
 int32_t PR_CALLBACK interposedWrite(PRFileDesc* aFd, const void* aBuf,
                                     int32_t aAmt) {
   // If we don't have a valid original function pointer something is very wrong.
   NS_ASSERTION(sWriteFn, "NSPR IO Interposing: sWriteFn is NULL");
 
-  NSPRIOAutoObservation timer(IOInterposeObserver::OpWrite);
+  NSPRIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd);
   return sWriteFn(aFd, aBuf, aAmt);
 }
 
 PRStatus PR_CALLBACK interposedFSync(PRFileDesc* aFd) {
   // If we don't have a valid original function pointer something is very wrong.
   NS_ASSERTION(sFSyncFn, "NSPR IO Interposing: sFSyncFn is NULL");
 
-  NSPRIOAutoObservation timer(IOInterposeObserver::OpFSync);
+  NSPRIOAutoObservation timer(IOInterposeObserver::OpFSync, aFd);
   return sFSyncFn(aFd);
 }
 
 PRStatus PR_CALLBACK interposedFileInfo(PRFileDesc* aFd, PRFileInfo* aInfo) {
   // If we don't have a valid original function pointer something is very wrong.
   NS_ASSERTION(sFileInfoFn, "NSPR IO Interposing: sFileInfoFn is NULL");
 
-  NSPRIOAutoObservation timer(IOInterposeObserver::OpStat);
+  NSPRIOAutoObservation timer(IOInterposeObserver::OpStat, aFd);
   return sFileInfoFn(aFd, aInfo);
 }
 
 PRStatus PR_CALLBACK interposedFileInfo64(PRFileDesc* aFd,
                                           PRFileInfo64* aInfo) {
   // If we don't have a valid original function pointer something is very wrong.
   NS_ASSERTION(sFileInfo64Fn, "NSPR IO Interposing: sFileInfo64Fn is NULL");
 
-  NSPRIOAutoObservation timer(IOInterposeObserver::OpStat);
+  NSPRIOAutoObservation timer(IOInterposeObserver::OpStat, aFd);
   return sFileInfo64Fn(aFd, aInfo);
 }
 
 }  // namespace
 
 namespace mozilla {
 
 void InitNSPRIOInterposing() {