Bug 611930: Annotate crash reports with LSP information. r=ted sr=rs a=b
☠☠ backed out by 4572c4175526 ☠ ☠
authorKyle Huey <khuey@kylehuey.com>
Sun, 21 Nov 2010 13:58:33 -0500
changeset 57971 c8a4b4ed9160aa0693360d6ab68e79f130db3ae0
parent 57970 885574b5c18c0d50a8903cfd880aed4b1afeb39a
child 57972 4572c41755267cb0af3f7c98afe90acebca2b2f6
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersted, rs, b
bugs611930
milestone2.0b8pre
Bug 611930: Annotate crash reports with LSP information. r=ted sr=rs a=b
toolkit/crashreporter/google-breakpad/src/client/windows/handler/Makefile.in
toolkit/library/Makefile.in
widget/src/build/Makefile.in
widget/src/windows/LSPAnnotator.cpp
widget/src/windows/Makefile.in
widget/src/windows/nsAppShell.cpp
--- a/toolkit/crashreporter/google-breakpad/src/client/windows/handler/Makefile.in
+++ b/toolkit/crashreporter/google-breakpad/src/client/windows/handler/Makefile.in
@@ -40,17 +40,17 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= handler
 LIBRARY_NAME	= exception_handler_s
 XPI_NAME 	= crashreporter
 
-LOCAL_INCLUDES 	= -I$(srcdir)/../../..
+LOCAL_INCLUDES 	= -I$(topsrcdir)/toolkit/crashreporter/google-breakpad/src
 DEFINES += -DUNICODE -D_UNICODE -DBREAKPAD_NO_TERMINATE_THREAD
 
 CPPSRCS		= \
 		exception_handler.cc \
 		$(NULL)
 
 # need static lib
 FORCE_STATIC_LIB = 1
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -242,17 +242,17 @@ ifeq ($(OS_ARCH),SunOS)
 ifdef GNU_CC
 EXTRA_DSO_LDOPTS += -lelf
 else
 EXTRA_DSO_LDOPTS += -lelf -ldemangle
 endif
 endif
 
 ifeq ($(OS_ARCH),WINNT)
-OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32 imm32 winmm wsock32 msimg32 shlwapi psapi)
+OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32 imm32 winmm wsock32 msimg32 shlwapi psapi Ws2_32)
 ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
 OS_LIBS += $(call EXPAND_LIBNAME,imagehlp)
 endif
 endif # WINNT
 ifeq ($(OS_ARCH),WINCE)
 OS_LIBS += $(call EXPAND_LIBNAME, aygshell uuid ole32 oleaut32 Ws2 ddraw)
 OS_LIBS += $(call EXPAND_LIBNAME, ceosutil libcmt comsuppw)
 ifdef WINCE_WINDOWS_MOBILE
--- a/widget/src/build/Makefile.in
+++ b/widget/src/build/Makefile.in
@@ -58,17 +58,17 @@ EXTRA_DSO_LIBS	= gkgfx \
 		  $(NULL)
 
 LOCAL_INCLUDES	= \
 		-I$(srcdir) \
 		-I$(srcdir)/../xpwidgets \
 		-I$(srcdir)/../windows \
 		$(NULL)
 
-OS_LIBS += $(call EXPAND_LIBNAME, uuid ole32 oleaut32)
+OS_LIBS += $(call EXPAND_LIBNAME, uuid ole32 oleaut32 Ws2_32)
 
 ifneq ($(OS_ARCH), WINCE)
 OS_LIBS += $(call EXPAND_LIBNAME, comctl32 comdlg32 shell32 imm32 shlwapi winspool msimg32)
 else
 OS_LIBS += $(call EXPAND_LIBNAME, aygshell ddraw)
 EXTRA_DSO_LDOPTS += $(DEPTH)/gfx/cairo/libpixman/src/mozlibpixman.lib
 endif
 
new file mode 100644
--- /dev/null
+++ b/widget/src/windows/LSPAnnotator.cpp
@@ -0,0 +1,146 @@
+/* ***** 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.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Kyle Huey <me@kylehuey.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * 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 ***** */
+
+/**
+ * LSPs are evil little bits of code that are allowed to inject into our
+ * networking stack by Windows.  Once they have wormed into our process
+ * they gnaw at our innards until we crash.  Here we force the buggers
+ * into the light by recording them in our crash information.
+ * We do the enumeration on a thread because I'm concerned about startup perf
+ * on machines with several LSPs.
+ */
+
+#include "nsICrashReporter.h"
+#include "nsISupportsImpl.h"
+#include "nsServiceManagerUtils.h"
+#include "nsThreadUtils.h"
+#include <windows.h>
+#include <Ws2spi.h>
+
+namespace mozilla {
+namespace crashreporter {
+
+class LSPAnnotationGatherer : public nsRunnable
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIRUNNABLE
+
+  void Annotate();
+  nsCString mString;
+  nsCOMPtr<nsIThread> mThread;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(LSPAnnotationGatherer, nsIRunnable)
+
+void
+LSPAnnotationGatherer::Annotate()
+{
+  nsCOMPtr<nsICrashReporter> cr =
+    do_GetService("@mozilla.org/toolkit/crash-reporter;1");
+  PRBool enabled;
+  if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) {
+    cr->AnnotateCrashReport(NS_LITERAL_CSTRING("Winsock_LSP"), mString);
+    nsCString note = NS_LITERAL_CSTRING("Winsock LSPs: ");
+    note.Append(mString);
+    // XXXkhuey Once Bug 613874 is fixed we should stop adding to the appnotes.
+    cr->AppendAppNotesToCrashReport(mString);
+  }
+  mThread->Shutdown();
+}
+
+NS_IMETHODIMP
+LSPAnnotationGatherer::Run()
+{
+  mThread = NS_GetCurrentThread();
+
+  DWORD size = 0;
+  int err;
+  // Get the size of the buffer we need
+  if (SOCKET_ERROR != WSCEnumProtocols(NULL, NULL, &size, &err) ||
+      err != WSAENOBUFS) {
+    // Er, what?
+    NS_NOTREACHED("WSCEnumProtocols suceeded when it should have failed ...");
+    return NS_ERROR_FAILURE;
+  }
+
+  nsAutoPtr<char> byteArray = new char[size];
+  WSAPROTOCOL_INFO* providers =
+    reinterpret_cast<WSAPROTOCOL_INFO*>(byteArray.get());
+
+  int n = WSCEnumProtocols(NULL, providers, &size, &err);
+  if (n == SOCKET_ERROR) {
+    // Lame. We provided the right size buffer; we'll just give up now.
+    NS_WARNING("Could not get LSP list");
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCString str;
+  for (int i = 0; i < n; i++) {
+    AppendUTF16toUTF8(nsDependentString(providers[i].szProtocol), str);
+    str.AppendLiteral(" : ");
+    str.AppendInt(providers[i].iVersion);
+    str.AppendLiteral(" : ");
+    str.AppendInt(providers[i].iSocketType);
+    str.AppendLiteral(" : ");
+
+    wchar_t path[MAX_PATH];
+    int dummy;
+    if (!WSCGetProviderPath(&providers[i].ProviderId, path,
+                            &dummy, &err)) {
+      AppendUTF16toUTF8(nsDependentString(path), str);
+    }
+
+    if (i + 1 != n) {
+      str.AppendLiteral(" \n ");
+    }
+  }
+
+  mString = str;
+  NS_DispatchToMainThread(NS_NewRunnableMethod(this, &LSPAnnotationGatherer::Annotate));
+  return NS_OK;
+}
+
+void LSPAnnotate()
+{
+  nsCOMPtr<nsIThread> thread;
+  nsCOMPtr<nsIRunnable> runnable =
+    do_QueryObject(new LSPAnnotationGatherer());
+  NS_NewThread(getter_AddRefs(thread), runnable);
+}
+
+} // namespace crashreporter
+} // namespace mozilla
--- a/widget/src/windows/Makefile.in
+++ b/widget/src/windows/Makefile.in
@@ -69,16 +69,20 @@ CPPSRCS		= \
 	TaskbarTabPreview.cpp \
 	TaskbarWindowPreview.cpp \
 	TaskbarPreviewButton.cpp \
  	JumpListBuilder.cpp \
  	JumpListItem.cpp \
 	GfxInfo.cpp \
 	$(NULL)
 
+ifdef MOZ_CRASHREPORTER
+CPPSRCS += LSPAnnotator.cpp
+endif
+
 ifdef NS_PRINTING
 CPPSRCS		+= \
 	nsPrintOptionsWin.cpp \
 	nsPrintSettingsWin.cpp \
 	nsDeviceContextSpecWin.cpp \
 	$(NULL)
 endif
 
--- a/widget/src/windows/nsAppShell.cpp
+++ b/widget/src/windows/nsAppShell.cpp
@@ -70,16 +70,24 @@ static UINT sMsgId;
 static UINT sTaskbarButtonCreatedMsg;
 
 /* static */
 UINT nsAppShell::GetTaskbarButtonCreatedMessage() {
 	return sTaskbarButtonCreatedMsg;
 }
 #endif
 
+namespace mozilla {
+namespace crashreporter {
+void LSPAnnotate();
+} // namespace crashreporter
+} // namespace mozilla
+
+using mozilla::crashreporter::LSPAnnotate;
+
 //-------------------------------------------------------------------------
 
 static BOOL PeekKeyAndIMEMessage(LPMSG msg, HWND hwnd)
 {
   MSG msg1, msg2, *lpMsg;
   BOOL b1, b2;
   b1 = ::PeekMessageW(&msg1, NULL, WM_KEYFIRST, WM_IME_KEYLAST, PM_NOREMOVE);
   b2 = ::PeekMessageW(&msg2, NULL, NS_WM_IMEFIRST, NS_WM_IMELAST, PM_NOREMOVE);
@@ -122,16 +130,20 @@ nsAppShell::~nsAppShell()
     // the UI thread.
     SendMessage(mEventWnd, WM_CLOSE, 0, 0);
   }
 }
 
 nsresult
 nsAppShell::Init()
 {
+#ifdef MOZ_CRASHREPORTER
+  LSPAnnotate();
+#endif
+
   if (!sMsgId)
     sMsgId = RegisterWindowMessageW(L"nsAppShell:EventID");
 
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
   sTaskbarButtonCreatedMsg = ::RegisterWindowMessageW(L"TaskbarButtonCreated");
   NS_ASSERTION(sTaskbarButtonCreatedMsg, "Could not register taskbar button creation message");
 
   // Global app registration id for Win7 and up. See