bug 376545 - AnnotateCrashReport needs to handle re-setting same key. r=bsmedberg
authorted.mielczarek@gmail.com
Wed, 18 Apr 2007 14:30:36 -0700
changeset 632 0ed60be23ebda749e14bcc15949b01271c44bafb
parent 631 d4bd2e209032c383931c717474790e19efdc73e5
child 633 7015bbccae326608c482645ecd1be1f7d08ffa51
push idunknown
push userunknown
push dateunknown
reviewersbsmedberg
bugs376545
milestone1.9a4pre
bug 376545 - AnnotateCrashReport needs to handle re-setting same key. r=bsmedberg
toolkit/airbag/nsAirbagExceptionHandler.cpp
--- a/toolkit/airbag/nsAirbagExceptionHandler.cpp
+++ b/toolkit/airbag/nsAirbagExceptionHandler.cpp
@@ -52,16 +52,17 @@
 #error "This code expects a 2 byte wchar_t.  You should --disable-airbag."
 #endif
 
 #include <stdlib.h>
 #include <prenv.h>
 #include "nsDebug.h"
 #include "nsCRT.h"
 #include "nsILocalFile.h"
+#include "nsDataHashtable.h"
 
 #ifdef XP_WIN32
 #define CRASH_REPORTER_FILENAME "crashreporter.exe"
 #define PATH_SEPARATOR "\\"
 #else
 #define CRASH_REPORTER_FILENAME "crashreporter"
 #define PATH_SEPARATOR "/"
 #endif
@@ -91,16 +92,17 @@ static PRUnichar* crashReporterCmdLine =
 // points at the end of the previous string
 // so we can append the minidump filename
 static PRUnichar* crashReporterCmdLineEnd = nsnull;
 // space to hold a filename for the API data
 static PRUnichar* crashReporterAPIDataFilename = nsnull;
 static PRUnichar* crashReporterAPIDataFilenameEnd = nsnull;
 
 // this holds additional data sent via the API
+static nsDataHashtable<nsCStringHashKey,nsCString>* crashReporterAPIData_Hash;
 static nsCString* crashReporterAPIData = nsnull;
 
 bool MinidumpCallback(const wchar_t *dump_path,
                       const wchar_t *minidump_id,
                       void *context,
                       EXCEPTION_POINTERS *exinfo,
                       MDRawAssertionInfo *assertion,
                       bool succeeded)
@@ -220,16 +222,23 @@ nsresult SetExceptionHandler(nsILocalFil
 
   // allocate our strings
   crashReporterCmdLine_withoutDumpPath = new nsString();
   NS_ENSURE_TRUE(crashReporterCmdLine_withoutDumpPath, NS_ERROR_OUT_OF_MEMORY);
 
   crashReporterAPIData = new nsCString();
   NS_ENSURE_TRUE(crashReporterAPIData, NS_ERROR_OUT_OF_MEMORY);
 
+  crashReporterAPIData_Hash =
+    new nsDataHashtable<nsCStringHashKey,nsCString>();
+  NS_ENSURE_TRUE(crashReporterAPIData_Hash, NS_ERROR_OUT_OF_MEMORY);
+
+  rv = crashReporterAPIData_Hash->Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // locate crashreporter executable
   nsString exePath;
 
   if (aXREDirectory) {
     aXREDirectory->GetPath(exePath);
   }
   else {
     rv = GetExecutablePath(exePath);
@@ -307,16 +316,20 @@ nsresult UnsetExceptionHandler()
   if (crashReporterCmdLine_withoutDumpPath) {
     delete crashReporterCmdLine_withoutDumpPath;
     crashReporterCmdLine_withoutDumpPath = nsnull;
   }
   if (crashReporterAPIData) {
     delete crashReporterAPIData;
     crashReporterAPIData = nsnull;
   }
+  if (crashReporterAPIData_Hash) {
+    delete crashReporterAPIData_Hash;
+    crashReporterAPIData_Hash = nsnull;
+  }
 
   if (!gExceptionHandler)
     return NS_ERROR_NOT_INITIALIZED;
 
   delete gExceptionHandler;
   gExceptionHandler = nsnull;
 
   if(crashReporterCmdLine != nsnull) {
@@ -356,16 +369,25 @@ static PRBool DoFindInReadable(const nsA
 {
   nsACString::const_iterator start, end;
   str.BeginReading(start);
   str.EndReading(end);
 
   return FindInReadable(value, start, end);
 }
 
+static PLDHashOperator PR_CALLBACK EnumerateEntries(const nsACString& key,
+                                                    nsCString entry,
+                                                    void* userData)
+{
+  crashReporterAPIData->Append(key + NS_LITERAL_CSTRING("=") + entry +
+                               NS_LITERAL_CSTRING("\n"));
+  return PL_DHASH_NEXT;
+}
+
 nsresult AnnotateCrashReport(const nsACString &key, const nsACString &data)
 {
   if (!gExceptionHandler)
     return NS_ERROR_NOT_INITIALIZED;
 
   if (DoFindInReadable(key, NS_LITERAL_CSTRING("=")) ||
       DoFindInReadable(key, NS_LITERAL_CSTRING("\n")))
     return NS_ERROR_INVALID_ARG;
@@ -377,14 +399,20 @@ nsresult AnnotateCrashReport(const nsACS
   
   // escape backslashes
   ReplaceChar(escapedData, NS_LITERAL_CSTRING("\\"),
               NS_LITERAL_CSTRING("\\\\"));
   // escape newlines
   ReplaceChar(escapedData, NS_LITERAL_CSTRING("\n"),
               NS_LITERAL_CSTRING("\\n"));
 
-  crashReporterAPIData->Append(key + NS_LITERAL_CSTRING("=") + escapedData +
-                               NS_LITERAL_CSTRING("\n"));
+  nsresult rv = crashReporterAPIData_Hash->Put(key, escapedData);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // now rebuild the file contents
+  crashReporterAPIData->Truncate(0);
+  crashReporterAPIData_Hash->EnumerateRead(EnumerateEntries,
+                                           crashReporterAPIData);
+
   return NS_OK;
 }
 
 } // namespace CrashReporter