bug 372831 - provide API to submit extra data with minidump. r=bsmedberg, r=sayrer for the unit test
authorted.mielczarek@gmail.com
Tue, 24 Jul 2007 18:05:57 -0700
changeset 3870 a9ba97687b706813853f8ed9c0f875b5cdbe5332
parent 3869 be59e0089a72a8c6de191410aa8cd0663b48bec6
child 3871 7fed37fb1a3fedbac3f666dd9da79dbb52b2ea1f
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherderautoland@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, sayrer
bugs372831
milestone1.9a7pre
bug 372831 - provide API to submit extra data with minidump. r=bsmedberg, r=sayrer for the unit test
toolkit/crashreporter/Makefile.in
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/crashreporter/nsICrashReporter.idl
toolkit/crashreporter/test/Makefile.in
toolkit/crashreporter/test/TestCrashReporterAPI.cpp
--- a/toolkit/crashreporter/Makefile.in
+++ b/toolkit/crashreporter/Makefile.in
@@ -60,19 +60,27 @@ ifeq  ($(OS_ARCH),WINNT)
 		$(NULL)
 endif
 
 DIRS += client
 
 LOCAL_INCLUDES = -I$(srcdir)/airbag/src
 DEFINES += -DUNICODE -D_UNICODE
 
+XPIDLSRCS = \
+	nsICrashReporter.idl \
+	$(NULL)
+
 EXPORTS = \
 	nsAirbagExceptionHandler.h \
 	$(NULL)
 
 CPPSRCS = \
 	nsAirbagExceptionHandler.cpp \
 	$(NULL)
 
 FORCE_STATIC_LIB = 1
 
+ifdef ENABLE_TESTS
+DIRS += test
+endif
+
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -349,16 +349,19 @@ nsresult AnnotateCrashReport(const nsACS
 {
   if (!gExceptionHandler)
     return NS_ERROR_NOT_INITIALIZED;
 
   if (DoFindInReadable(key, NS_LITERAL_CSTRING("=")) ||
       DoFindInReadable(key, NS_LITERAL_CSTRING("\n")))
     return NS_ERROR_INVALID_ARG;
 
+  if (DoFindInReadable(data, NS_LITERAL_CSTRING("\0")))
+    return NS_ERROR_INVALID_ARG;
+
   nsCString escapedData(data);
   
   // escape backslashes
   ReplaceChar(escapedData, NS_LITERAL_CSTRING("\\"),
               NS_LITERAL_CSTRING("\\\\"));
   // escape newlines
   ReplaceChar(escapedData, NS_LITERAL_CSTRING("\n"),
               NS_LITERAL_CSTRING("\\n"));
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/nsICrashReporter.idl
@@ -0,0 +1,62 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Breakpad Integration.
+ *
+ * The Initial Developer of the Original Code is
+ * Ted Mielczarek <ted.mielczarek@gmail.com>
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+/**
+ * Provides access to crash reporting functionality.
+ * @status UNSTABLE - This interface is not frozen and will probably change in
+ *                    future releases.
+ */
+
+[scriptable, uuid(da7020ad-fad4-443e-b02b-c5cc9d482e2f)]
+interface nsICrashReporter : nsISupports
+{
+  /**
+   * Add some extra data to be submitted with a crash report.
+   * @param key
+   *        Name of the data to be added.
+   * @param data
+   *        Data to be added.
+   *
+   * @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized
+   * @throw NS_ERROR_INVALID_ARG if key or data contain invalid characters.
+   *                             Invalid characters for key are '=' and
+   *                             '\n'.  Invalid character for data is '\0'.
+   */
+  void annotateCrashReport(in ACString key, in ACString data);
+};
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/test/Makefile.in
@@ -0,0 +1,77 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Breakpad integration.
+#
+# The Initial Developer of the Original Code is
+#   Ted Mielczarek <ted.mielczarek@gmail.com>
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+PROGRAM = TestCrashReporterAPI$(BIN_SUFFIX)
+
+CPPSRCS = TestCrashReporterAPI.cpp
+
+REQUIRES = \
+	xpcom \
+	string \
+	airbag \
+	$(NULL)
+
+LIBS = \
+	$(EXTRA_DSO_LIBS) \
+	$(XPCOM_GLUE_LDOPTS) \
+	$(XPCOM_LIBS) \
+	$(NSPR_LIBS) \
+        $(DEPTH)/toolkit/airbag/$(LIB_PREFIX)airbagexception_s.$(LIB_SUFFIX) \
+	$(NULL)
+
+MOZILLA_INTERNAL_API = 1
+
+include $(topsrcdir)/config/rules.mk
+
+ifeq ($(OS_ARCH),WINNT)
+LIBS += \
+	$(DEPTH)/toolkit/airbag/airbag/src/client/windows/handler/$(LIB_PREFIX)exception_handler.$(LIB_SUFFIX) \
+	$(DEPTH)/toolkit/airbag/airbag/src/common/windows/$(LIB_PREFIX)airbag_common_s.$(LIB_SUFFIX)
+LIBS += $(call expand_libname shell32)
+endif
+
+OS_LIBS += $(call EXPAND_LIBNAME,ole32)
+
+check:: $(PROGRAM)
+	$(RUN_TEST_PROGRAM) $(DIST)/bin/TestCrashReporterAPI
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/test/TestCrashReporterAPI.cpp
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Breakpad integration
+ *
+ * The Initial Developer of the Original Code is
+ * Ted Mielczarek <ted.mielczarek@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "prenv.h"
+#include "nsIComponentManager.h"
+#include "nsISimpleEnumerator.h"
+#include "nsIServiceManager.h"
+#include "nsServiceManagerUtils.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsIProperties.h"
+#include "nsCOMPtr.h"
+#include "nsILocalFile.h"
+
+#include "nsAirbagExceptionHandler.h"
+#include "nsICrashReporter.h"
+
+#define mu_assert(message, test) do { if (NS_FAILED(test)) \
+                                       return message; } while (0)
+#define mu_assert_failure(message, test) do { if (NS_SUCCEEDED(test)) \
+                                               return message; } while (0)
+#define mu_run_test(test) do { char *message = test(); tests_run++; \
+                                if (message) return message; } while (0)
+int tests_run;
+
+char *
+test_init_exception_handler()
+{
+  mu_assert("CrashReporter::SetExceptionHandler",
+            CrashReporter::SetExceptionHandler(nsnull));
+  return 0;
+}
+
+char *
+test_set_minidump_path()
+{
+  nsresult rv;
+  nsCOMPtr<nsIProperties> directoryService = 
+    do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
+
+  mu_assert("do_GetService", rv);
+
+  nsCOMPtr<nsILocalFile> currentDirectory;
+  rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
+                             NS_GET_IID(nsILocalFile),
+                             getter_AddRefs(currentDirectory));
+  mu_assert("directoryService->Get", rv);
+
+  nsAutoString currentDirectoryPath;
+  rv = currentDirectory->GetPath(currentDirectoryPath);
+  mu_assert("currentDirectory->GetPath", rv);
+  
+  mu_assert("CrashReporter::SetMinidumpPath",
+            CrashReporter::SetMinidumpPath(currentDirectoryPath));
+
+  return 0;
+}
+
+char *
+test_annotate_crash_report_basic()
+{
+  mu_assert("CrashReporter::AnnotateCrashReport: basic",
+     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("test"),
+                                        NS_LITERAL_CSTRING("some data")));
+
+  return 0;
+}
+
+char *
+test_annotate_crash_report_invalid_equals()
+{
+  mu_assert_failure("CrashReporter::AnnotateCrashReport: invalid = in key",
+     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("test=something"),
+                                        NS_LITERAL_CSTRING("some data")));
+  return 0;
+}
+
+char *
+test_annotate_crash_report_invalid_cr()
+{
+  mu_assert_failure("CrashReporter::AnnotateCrashReport: invalid \n in key",
+     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("test\nsomething"),
+                                        NS_LITERAL_CSTRING("some data")));
+  return 0;
+}
+
+char *
+test_unset_exception_handler()
+{
+  mu_assert("CrashReporter::UnsetExceptionHandler",
+            CrashReporter::UnsetExceptionHandler());
+  return 0;
+}
+
+static char* all_tests()
+{
+  mu_run_test(test_init_exception_handler);
+  mu_run_test(test_set_minidump_path);
+  mu_run_test(test_annotate_crash_report_basic);
+  mu_run_test(test_annotate_crash_report_invalid_equals);
+  mu_run_test(test_annotate_crash_report_invalid_cr);
+  mu_run_test(test_unset_exception_handler);
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  NS_InitXPCOM2(nsnull, nsnull, nsnull);
+
+  char* env = new char[13];
+  strcpy(env, "MOZ_AIRBAG=1");
+  PR_SetEnv(env);
+
+  char* result = all_tests();
+  if (result != 0) {
+    printf("FAIL: %s\n", result);
+  }
+  else {
+    printf("ALL TESTS PASSED\n");
+  }
+  printf("Tests run: %d\n", tests_run);
+ 
+  return result != 0;
+}