[vlc-devel] [PATCH 2/2] win32: Use breakpad for crash reporting

Hugo Beauzée-Luyssen hugo at beauzee.fr
Thu Dec 21 11:11:44 CET 2017


---
 bin/Makefile.am  |  9 ++++++
 bin/breakpad.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 bin/winvlc.c     | 16 ++++++++--
 3 files changed, 113 insertions(+), 2 deletions(-)
 create mode 100644 bin/breakpad.cpp

diff --git a/bin/Makefile.am b/bin/Makefile.am
index 23b4100c4b..5452577e86 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -32,6 +32,15 @@ vlc_SOURCES = winvlc.c
 vlc_DEPENDENCIES = vlc_win32_rc.$(OBJEXT)
 vlc_LDFLAGS = -mwindows
 vlc_LDADD += vlc_win32_rc.$(OBJEXT)
+libbreakpad_wrapper_la_SOURCES = breakpad.cpp
+libbreakpad_wrapper_la_LIBADD = $(BREAKPAD_LIBS)
+libbreakpad_wrapper_la_LDFLAGS = -static
+libbreakpad_wrapper_la_CXXFLAGS = $(AM_CXXFLAGS) $(BREAKPAD_CFLAGS) -DBREAKPAD_URL=\"@BREAKPAD_URL@\"
+noinst_LTLIBRARIES = libbreakpad_wrapper.la
+if HAVE_BREAKPAD
+vlc_LDADD += libbreakpad_wrapper.la -lstdc++ -lwininet
+vlc_CPPFLAGS = -DHAVE_BREAKPAD
+endif
 endif
 
 vlc_osx_SOURCES = darwinvlc.m
diff --git a/bin/breakpad.cpp b/bin/breakpad.cpp
new file mode 100644
index 0000000000..15baae5d8e
--- /dev/null
+++ b/bin/breakpad.cpp
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * breakpad.cpp: Wrapper to breakpad crash handler
+ *****************************************************************************
+ * Copyright (C) 1998-2017 VLC authors
+ *
+ * Authors: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <windows.h>
+#include "client/windows/handler/exception_handler.h"
+#include "common/windows/http_upload.h"
+#include <memory>
+#include <map>
+#include <string>
+
+using google_breakpad::ExceptionHandler;
+
+static bool FilterCallback(void*, EXCEPTION_POINTERS*, MDRawAssertionInfo*)
+{
+    // Don't spam breakpad if we're debugging
+    return !IsDebuggerPresent();
+}
+
+extern "C"
+{
+
+void CheckCrashDump( const wchar_t* path )
+{
+    wchar_t pattern[MAX_PATH];
+    WIN32_FIND_DATA data;
+    _snwprintf( pattern, MAX_PATH, L"%s/*.dmp", path );
+    HANDLE h = FindFirstFile( pattern, &data );
+    if (h == INVALID_HANDLE_VALUE)
+        return;
+    int answer = MessageBox( NULL, L"Ooops: VLC media player just crashed.\n" \
+        "Would you like to send a bug report to the developers team?",
+        L"VLC crash reporting", MB_YESNO);
+    std::map<std::wstring, std::wstring> params;
+    params[L"prod"] = L"VLC";
+    params[L"ver"] = TEXT(PACKAGE_VERSION);
+    do
+    {
+        wchar_t fullPath[MAX_PATH];
+        _snwprintf( fullPath, MAX_PATH, L"%s/%s", path, data.cFileName );
+        if( answer == IDYES )
+        {
+            std::map<std::wstring, std::wstring> files;
+            files[L"upload_file_minidump"] = fullPath;
+            google_breakpad::HTTPUpload::SendRequest(
+                            TEXT( BREAKPAD_URL "/reports" ), params, files,
+                            NULL, NULL, NULL );
+        }
+        DeleteFile( fullPath );
+    } while ( FindNextFile( h, &data ) );
+    FindClose(h);
+}
+
+void* InstallCrashHandler( const wchar_t* crashdump_path )
+{
+    // Breakpad needs the folder to exist to generate the crashdump
+    CreateDirectory( crashdump_path, NULL );
+    return new(std::nothrow) ExceptionHandler( crashdump_path, FilterCallback,
+                                NULL, NULL, ExceptionHandler::HANDLER_ALL);
+}
+
+void ReleaseCrashHandler( void* handler )
+{
+    ExceptionHandler* eh = reinterpret_cast<ExceptionHandler*>( handler );
+    delete eh;
+}
+
+}
diff --git a/bin/winvlc.c b/bin/winvlc.c
index 61a86f1b4b..9d081bf43f 100644
--- a/bin/winvlc.c
+++ b/bin/winvlc.c
@@ -43,7 +43,12 @@
 #include <io.h>
 #include <shlobj.h>
 #define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS)1
-static const wchar_t *crashdump_path;
+
+#ifdef HAVE_BREAKPAD
+void CheckCrashDump( const wchar_t* crashdump_path );
+void* InstallCrashHandler( const wchar_t* crashdump_path );
+void ReleaseCrashHandler( void* handler );
+#endif
 
 static char *FromWide (const wchar_t *wide)
 {
@@ -192,14 +197,18 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
     argv[argc] = NULL;
     LocalFree (wargv);
 
+    void* eh = NULL;
     if(crash_handling)
     {
+#ifdef HAVE_BREAKPAD
         static wchar_t path[MAX_PATH];
         if( S_OK != SHGetFolderPathW( NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
                     NULL, SHGFP_TYPE_CURRENT, path ) )
             fprintf( stderr, "Can't open the vlc conf PATH\n" );
         _snwprintf( path+wcslen( path ), MAX_PATH,  L"%s", L"\\vlc\\crashdump" );
-        crashdump_path = &path[0];
+        CheckCrashDump( &path[0] );
+        eh = InstallCrashHandler( &path[0] );
+#endif
     }
 
     _setmode( _fileno( stdin ), _O_BINARY ); /* Needed for pipes */
@@ -248,6 +257,9 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     MB_OK|MB_ICONERROR);
 
 
+#ifdef HAVE_BREAKPAD
+    ReleaseCrashHandler( eh );
+#endif
     for (int i = 0; i < argc; i++)
         free (argv[i]);
 
-- 
2.11.0



More information about the vlc-devel mailing list