Bug 1654379 - Allow filtering the IPC log by multiple toplevel protocol names. r=nika
authorJon Bauman <jbauman@mozilla.com>
Thu, 23 Jul 2020 17:47:39 +0000
changeset 541814 f8e83f5b68e0e151df25cf6021fc3ab985a6a012
parent 541813 d9e15f6cc3505d97898daafe3e6c7282060f2021
child 541815 b1aa825d8c531f81f8945ab5a5da290987a22ccc
push id37633
push userccoroiu@mozilla.com
push dateFri, 24 Jul 2020 09:32:06 +0000
treeherdermozilla-central@141543043270 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika
bugs1654379
milestone80.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 1654379 - Allow filtering the IPC log by multiple toplevel protocol names. r=nika Differential Revision: https://phabricator.services.mozilla.com/D84587
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/gtest/TestLogging.cpp
ipc/gtest/moz.build
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -14,16 +14,19 @@
 
 #include "mozilla/IntegerPrintfMacros.h"
 
 #include "mozilla/ipc/ProtocolUtils.h"
 
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/ipc/Transport.h"
 #include "mozilla/StaticMutex.h"
+#if defined(DEBUG) || defined(FUZZING)
+#  include "mozilla/Tokenizer.h"
+#endif
 #include "mozilla/Unused.h"
 #include "nsPrintfCString.h"
 
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
 #  include "mozilla/sandboxTarget.h"
 #endif
 
 #if defined(XP_WIN)
@@ -111,16 +114,42 @@ void AnnotateSystemError() {
 }
 
 #if defined(XP_MACOSX)
 void AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error) {
   CrashReporter::AnnotateCrashReport(tag, error);
 }
 #endif  // defined(XP_MACOSX)
 
+#if defined(DEBUG) || defined(FUZZING)
+// This overload is for testability; application code should use the single-
+// argument version (defined in the ProtocolUtils.h) which takes the filter from
+// the environment.
+bool LoggingEnabledFor(const char* aTopLevelProtocol, const char* aFilter) {
+  if (!aFilter) {
+    return false;
+  }
+  if (strcmp(aFilter, "1") == 0) {
+    return true;
+  }
+
+  const char kDelimiters[] = ", ";
+  Tokenizer tokens(aFilter, kDelimiters);
+  Tokenizer::Token t;
+  while (tokens.Next(t)) {
+    if (t.Type() == Tokenizer::TOKEN_WORD &&
+        t.AsString() == aTopLevelProtocol) {
+      return true;
+    }
+  }
+
+  return false;
+}
+#endif  // defined(DEBUG) || defined(FUZZING)
+
 void LogMessageForProtocol(const char* aTopLevelProtocol,
                            base::ProcessId aOtherPid,
                            const char* aContextDescription, uint32_t aMessageId,
                            MessageDirection aDirection) {
   nsPrintfCString logMessage(
       "[time: %" PRId64 "][%d%s%d] [%s] %s %s\n", PR_Now(),
       base::GetCurrentProcId(),
       aDirection == MessageDirection::eReceiving ? "<-" : "->", aOtherPid,
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -1,14 +1,13 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=4 et :
- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ipc_ProtocolUtils_h
 #define mozilla_ipc_ProtocolUtils_h 1
 
 #include "base/process.h"
 #include "base/process_util.h"
 #include "chrome/common/ipc_message_utils.h"
 
@@ -568,23 +567,23 @@ class IShmemAllocator {
 inline bool LoggingEnabled() {
 #if defined(DEBUG) || defined(FUZZING)
   return !!PR_GetEnv("MOZ_IPC_MESSAGE_LOG");
 #else
   return false;
 #endif
 }
 
+#if defined(DEBUG) || defined(FUZZING)
+bool LoggingEnabledFor(const char* aTopLevelProtocol, const char* aFilter);
+#endif
+
 inline bool LoggingEnabledFor(const char* aTopLevelProtocol) {
 #if defined(DEBUG) || defined(FUZZING)
-  const char* filter = PR_GetEnv("MOZ_IPC_MESSAGE_LOG");
-  if (!filter) {
-    return false;
-  }
-  return strcmp(filter, "1") == 0 || strcmp(filter, aTopLevelProtocol) == 0;
+  return LoggingEnabledFor(aTopLevelProtocol, PR_GetEnv("MOZ_IPC_MESSAGE_LOG"));
 #else
   return false;
 #endif
 }
 
 MOZ_NEVER_INLINE void LogMessageForProtocol(const char* aTopLevelProtocol,
                                             base::ProcessId aOtherPid,
                                             const char* aContextDescription,
new file mode 100644
--- /dev/null
+++ b/ipc/gtest/TestLogging.cpp
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/ipc/ProtocolUtils.h"
+
+namespace mozilla::ipc {
+
+#if defined(DEBUG) || defined(FUZZING)
+TEST(IPCLogging, EmptyFilter)
+{
+  const char* emptyFilter = "";
+  EXPECT_FALSE(LoggingEnabledFor("PContentParent", emptyFilter));
+  EXPECT_FALSE(LoggingEnabledFor("PContentChild", emptyFilter));
+}
+
+TEST(IPCLogging, SingleProtocolFilter)
+{
+  const char* contentParentFilter = "PContentParent";
+  EXPECT_TRUE(LoggingEnabledFor("PContentParent", contentParentFilter));
+  EXPECT_FALSE(LoggingEnabledFor("PContentChild", contentParentFilter));
+}
+
+TEST(IPCLogging, CommaDelimitedProtocolsFilter)
+{
+  const char* gmpContentFilter = "PGMPContentChild,PGMPContentParent";
+  EXPECT_TRUE(LoggingEnabledFor("PGMPContentChild", gmpContentFilter));
+  EXPECT_TRUE(LoggingEnabledFor("PGMPContentParent", gmpContentFilter));
+  EXPECT_FALSE(LoggingEnabledFor("PContentParent", gmpContentFilter));
+  EXPECT_FALSE(LoggingEnabledFor("PContentChild", gmpContentFilter));
+}
+
+TEST(IPCLogging, SpaceDelimitedProtocolsFilter)
+{
+  const char* gmpContentFilter = "PGMPContentChild PGMPContentParent";
+  EXPECT_TRUE(LoggingEnabledFor("PGMPContentChild", gmpContentFilter));
+  EXPECT_TRUE(LoggingEnabledFor("PGMPContentParent", gmpContentFilter));
+  EXPECT_FALSE(LoggingEnabledFor("PContentParent", gmpContentFilter));
+  EXPECT_FALSE(LoggingEnabledFor("PContentChild", gmpContentFilter));
+}
+
+TEST(IPCLogging, CatchAllFilter)
+{
+  const char* catchAllFilter = "1";
+  EXPECT_TRUE(LoggingEnabledFor("PGMPContentChild", catchAllFilter));
+  EXPECT_TRUE(LoggingEnabledFor("PGMPContentParent", catchAllFilter));
+  EXPECT_TRUE(LoggingEnabledFor("PContentParent", catchAllFilter));
+  EXPECT_TRUE(LoggingEnabledFor("PContentChild", catchAllFilter));
+}
+#endif  // defined(DEBUG) || defined(FUZZING)
+
+}  // namespace mozilla::ipc
--- a/ipc/gtest/moz.build
+++ b/ipc/gtest/moz.build
@@ -2,14 +2,15 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 Library('ipctest')
 
 SOURCES += [
+    'TestLogging.cpp',
     'TestSharedMemory.cpp',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul-gtest'