diff options
author | Martin Felke <martin.felke@googlemail.com> | 2018-09-08 03:00:56 +0300 |
---|---|---|
committer | Martin Felke <martin.felke@googlemail.com> | 2018-09-08 03:00:56 +0300 |
commit | 07e497db295ebd5bd09eb07c6d2d8aebc7499c65 (patch) | |
tree | 784f6c076240b8c0b88e5e72a9b520dab3cb8403 /source/creator | |
parent | d6b64849310852e91957a89c29b282afcb511d88 (diff) |
backported existing crashpad support (win, mac, needs testing) and added breakpad support (linux)
Diffstat (limited to 'source/creator')
-rw-r--r-- | source/creator/CMakeLists.txt | 36 | ||||
-rw-r--r-- | source/creator/creator.c | 4 | ||||
-rw-r--r-- | source/creator/creator_breakpad_linux.cpp | 129 | ||||
-rw-r--r-- | source/creator/creator_crashpad_apple.cpp | 123 | ||||
-rw-r--r-- | source/creator/creator_crashpad_win.cpp | 149 | ||||
-rw-r--r-- | source/creator/creator_intern.h | 2 | ||||
-rw-r--r-- | source/creator/creator_signals.c | 30 |
7 files changed, 468 insertions, 5 deletions
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index b8d3d1e6384..e2d4ab2d5f2 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -62,6 +62,21 @@ if(WITH_CODEC_FFMPEG) add_definitions(-DWITH_FFMPEG) endif() +if(WITH_CRASHPAD) + add_definitions(-DWITH_CRASHPAD) + add_definitions(-DCRASHPAD_URL="${CRASHPAD_URL}") + blender_include_dirs(${CRASHPAD_INCLUDE_DIRS}) + if(MSVC) + set(CRASHPAD_SRC creator_crashpad_win.cpp) + endif() + if(APPLE) + set(CRASHPAD_SRC creator_crashpad_apple.cpp) + endif() + if(UNIX) + set(CRASHPAD_SRC creator_breakpad_linux.cpp) + endif() +endif() + if(WITH_PYTHON) blender_include_dirs(../blender/python) add_definitions(-DWITH_PYTHON) @@ -104,6 +119,7 @@ set(SRC creator.c creator_args.c creator_signals.c + ${CRASHPAD_SRC} creator_intern.h ) @@ -323,6 +339,7 @@ install( "file(REMOVE_RECURSE ${TARGETDIR_VER})" ) + if(WITH_PYTHON) # install(CODE "message(\"copying blender scripts...\")") @@ -422,6 +439,25 @@ if("${CMAKE_GENERATOR}" MATCHES ".*Makefiles.*") ) endif() +if(WITH_CRASHPAD) + if(MSVC) + add_custom_command( + TARGET blender POST_BUILD MAIN_DEPENDENCY blender + COMMAND ${LIBDIR}/crashpad/bin/dump_syms $<TARGET_FILE_DIR:blender>/blender.pdb > $<TARGET_FILE_DIR:blender>/blender.syms + COMMAND ${LIBDIR}/crashpad/bin/sentry-cli-Windows-x86_64.exe upload-dif $<TARGET_FILE_DIR:blender>/blender.syms + ) + install( + FILES ${LIBDIR}/crashpad/bin/crashpad_handler.exe + DESTINATION "." + ) +elseif(APPLE) + install( + PROGRAMS ${LIBDIR}/crashpad/bin/crashpad_handler + DESTINATION $<TARGET_FILE_DIR:blender>/../Resources/crashpad/ + ) + endif() +endif() + # ----------------------------------------------------------------------------- # Install Targets (Platform Specific) diff --git a/source/creator/creator.c b/source/creator/creator.c index a59a45f885c..fa5b05846a4 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -405,6 +405,8 @@ int main( psys_init_rng(); /* end second init */ + //int* whoops = (int*)0; + //*whoops = 41; #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS) G.background = true; /* python module mode ALWAYS runs in background mode (for now) */ @@ -523,7 +525,7 @@ int main( WM_init_splash(C); } } - + WM_main(C); return 0; diff --git a/source/creator/creator_breakpad_linux.cpp b/source/creator/creator_breakpad_linux.cpp new file mode 100644 index 00000000000..fd6b88b95a7 --- /dev/null +++ b/source/creator/creator_breakpad_linux.cpp @@ -0,0 +1,129 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file creator/creator_crashpad.cpp + * \ingroup creator + */ + +#include <map> +#include <string> +#include <vector> + +#include "client/linux/handler/exception_handler.h" +#include "common/linux/http_upload.h" +extern "C" +{ + +//old dummy shit for game engine... taken from creator.c + +/* for passing information between creator and gameengine */ +#ifdef WITH_GAMEENGINE +# include "BL_System.h" +#else /* dummy */ +# define SYS_SystemHandle int +#endif + +#include "BLI_path_util.h" +#include "BLI_utildefines.h" +#include "BKE_appdir.h" +#include "BKE_blender_version.h" +#include "creator_intern.h" +} + +using namespace google_breakpad; + +namespace { + + static bool dumpCallback(const MinidumpDescriptor& descriptor, void* context, bool succeeded) + { + std::map<std::string, std::string> files; + std::map<std::string, std::string> annotations; + std::string url(CRASHPAD_URL); + char blender_version[PATH_MAX] = { 0 }; + + printf("Minidump file: %s\n", descriptor.path()); + + files["upload_file_minidump"] = descriptor.path(); + + sprintf(blender_version, BLEND_VERSION_STRING_FMT); + annotations["product"] = "blender"; //prod + annotations["build_version"] = blender_version; //ver + + #ifdef BUILD_DATE + annotations["build_version_char"] = STRINGIFY(BLENDER_VERSION_CHAR); + annotations["build_cycle"] = STRINGIFY(BLENDER_VERSION_CYCLE); + annotations["build_date"] = build_date; + annotations["build_time"] = build_time; + annotations["build_hash"] = build_hash; + annotations["build_commit_date"] = build_commit_date; + annotations["build_commit_time"] = build_commit_time; + annotations["build_branch"] = build_branch; + annotations["build_platform"] = build_platform; + annotations["build_type"] = build_type; + annotations["build_cflags"] = build_cflags; + annotations["build_cxxflags"] = build_cxxflags; + annotations["build_linkflags"] = build_linkflags; + annotations["build_system"] = build_system; + #endif + + // Send it + string response, error; + bool success = HTTPUpload::SendRequest(url, + annotations, + files, + "", //options->proxy, + "", // options->proxy_user_pwd, + "", + &response, + NULL, + &error); + if (success) { + printf("Successfully sent the minidump file.\n"); + } else { + printf("Failed to send minidump: %s\n", error.c_str()); + } + printf("Response:\n"); + printf("%s\n", response.c_str()); + + return succeeded; + } + + static void startCrashHandler() + { +#if 0 + MinidumpDescriptor descriptor("/tmp"); + ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1); + printf("Exception Handler registered!\n"); + + //int* whoops = (int*)0; + //*whoops = 41; +#endif + ExceptionHandler::WriteMinidump("/tmp", dumpCallback, NULL); + } +} + +extern "C" +{ + void breakpad_write() + { + startCrashHandler(); + } +} + diff --git a/source/creator/creator_crashpad_apple.cpp b/source/creator/creator_crashpad_apple.cpp new file mode 100644 index 00000000000..2314b4aa6bb --- /dev/null +++ b/source/creator/creator_crashpad_apple.cpp @@ -0,0 +1,123 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file creator/creator_crashpad.cpp + * \ingroup creator + */ + +#include <map> +#include <string> +#include <vector> + +#include "client/crashpad_client.h" +#include "client/settings.h" +#include "base/files/file_path.h" +#include "client/crash_report_database.h" +extern "C" +{ +#include "BLI_path_util.h" +#include "BLI_utildefines.h" +#include "BKE_appdir.h" +#include "BKE_blender_version.h" +#include "creator_intern.h" +} + +using namespace std; + +using namespace crashpad; + +static CrashpadClient client; +static bool startCrashHandler() +{ + bool rc; + std::map<std::string, std::string> annotations; + std::vector<std::string> arguments; + char handler_path_cstr[PATH_MAX] = { 0 }; + char blender_version[PATH_MAX] = { 0 }; + + std::string db_path = BKE_appdir_folder_id_create(BLENDER_USER_DATAFILES, "crashpad"); + + BLI_path_append(handler_path_cstr, sizeof(handler_path_cstr), BKE_appdir_program_dir()); + BLI_path_append(handler_path_cstr, sizeof(handler_path_cstr), "../Resources/crashpad/crashpad_handler"); + + std::string handler_path(handler_path_cstr); + + printf("handler: %s\n", handler_path_cstr); + + std::string url(CRASHPAD_URL); + + arguments.push_back("--no-upload-gzip"); + arguments.push_back("--no-rate-limit"); + + sprintf(blender_version, BLEND_VERSION_STRING_FMT); + annotations["build_version"] = blender_version; +#ifdef BUILD_DATE + annotations["build_version_char"] = STRINGIFY(BLENDER_VERSION_CHAR); + annotations["build_cycle"] = STRINGIFY(BLENDER_VERSION_CYCLE); + annotations["build_date"] = build_date; + annotations["build_time"] = build_time; + annotations["build_hash"] = build_hash; + annotations["build_commit_date"] = build_commit_date; + annotations["build_commit_time"] = build_commit_time; + annotations["build_branch"] = build_branch; + annotations["build_platform"] = build_platform; + annotations["build_type"] = build_type; + annotations["build_cflags"] = build_cflags; + annotations["build_cxxflags"] = build_cxxflags; + annotations["build_linkflags"] = build_linkflags; + annotations["build_system"] = build_system; +#endif + + base::FilePath db(db_path); + base::FilePath handler(handler_path); + + std::unique_ptr<CrashReportDatabase> database = + crashpad::CrashReportDatabase::Initialize(db); + if (database == nullptr || database->GetSettings() == NULL) + return false; + + /* Enable automated uploads. however the handler will only be called when */ + /* the user consents to it, this way no crashdumps will be made if they */ + /* decline, and we can still have some custom UI */ + database->GetSettings()->SetUploadsEnabled(true); + + rc = client.StartHandler(handler, + db, + db, + url, + annotations, + arguments, + true, + true); + if (rc == false) + return false; + + return true; + } + + +extern "C" +{ + void crashpad_init() + { + startCrashHandler(); + } +} + diff --git a/source/creator/creator_crashpad_win.cpp b/source/creator/creator_crashpad_win.cpp new file mode 100644 index 00000000000..5a8dfc9360b --- /dev/null +++ b/source/creator/creator_crashpad_win.cpp @@ -0,0 +1,149 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file creator/creator_crashpad.cpp + * \ingroup creator + */ + +#include <map> +#include <string> +#include <vector> + +#include "client/crashpad_client.h" +#include "client/settings.h" +#include "base/files/file_path.h" +#include "client/crash_report_database.h" +extern "C" +{ +#include "BLI_path_util.h" +#include "BLI_utildefines.h" +#include "BKE_appdir.h" +#include "BKE_blender_version.h" +#include "creator_intern.h" +} + +#include <WinBase.h> + +using namespace std; + +using namespace crashpad; +#if _MSC_VER +static std::wstring StringToWString(const std::string& s) +{ + std::wstring temp(s.length(), L' '); + std::copy(s.begin(), s.end(), temp.begin()); + return temp; +} +#endif + +static CrashpadClient client; +static bool startCrashHandler() +{ + bool rc; + std::map<std::string, std::string> annotations; + std::vector<std::string> arguments; + char handler_path_cstr[MAX_PATH] = { 0 }; + char blender_version[MAX_PATH] = { 0 }; + + + std::string db_path_ascii = BKE_appdir_folder_id_create(BLENDER_USER_DATAFILES, "crashpad"); + std::wstring db_path(StringToWString(db_path_ascii)); + + BLI_path_append(handler_path_cstr, sizeof(handler_path_cstr), BKE_appdir_program_dir()); + BLI_path_append(handler_path_cstr, sizeof(handler_path_cstr), "crashpad_handler.exe"); + std::string handler_str(handler_path_cstr); + std::wstring handler_path(StringToWString(handler_str)); + printf("x"); + + std::string url(CRASHPAD_URL); + arguments.push_back("--no-upload-gzip"); + arguments.push_back("--no-rate-limit"); + + sprintf(blender_version, BLEND_VERSION_STRING_FMT); + annotations["build_version"] = blender_version; +#ifdef BUILD_DATE + annotations["build_version_char"] = STRINGIFY(BLENDER_VERSION_CHAR); + annotations["build_cycle"] = STRINGIFY(BLENDER_VERSION_CYCLE); + annotations["build_date"] = build_date; + annotations["build_time"] = build_time; + annotations["build_hash"] = build_hash; + annotations["build_commit_date"] = build_commit_date; + annotations["build_commit_time"] = build_commit_time; + annotations["build_branch"] = build_branch; + annotations["build_platform"] = build_platform; + annotations["build_type"] = build_type; + annotations["build_cflags"] = build_cflags; + annotations["build_cxxflags"] = build_cxxflags; + annotations["build_linkflags"] = build_linkflags; + annotations["build_system"] = build_system; +#endif + + base::FilePath db(db_path); + base::FilePath handler(handler_path); + + std::unique_ptr<CrashReportDatabase> database = + crashpad::CrashReportDatabase::Initialize(db); + if (database == nullptr || database->GetSettings() == NULL) + return false; + + /* Enable automated uploads. however the handler will only be called when */ + /* the user consents to it, this way no crashdumps will be made if they */ + /* decline, and we can still have some custom UI */ + database->GetSettings()->SetUploadsEnabled(true); + + rc = client.StartHandler(handler, + db, + db, + url, + annotations, + arguments, + true, + true); + if (rc == false) + return false; + + /* Optional, wait for Crashpad to initialize. */ + rc = client.WaitForHandlerStart(INFINITE); + if (rc == false) + return false; + + return true; + } + + + extern "C" + { + void crashpad_init() + { + startCrashHandler(); + } + + void crashpad_activate(void *ExceptionInfo) + { + if (MessageBoxA(NULL, + "Would you like to submit information about this crash to blender.org\n" + "to help improving future versions of blender?", + "Uh-Ow something unexpected has happened", + MB_YESNO | MB_ICONERROR) == IDYES) { + client.DumpAndCrash((EXCEPTION_POINTERS*)ExceptionInfo); + } + } + } + diff --git a/source/creator/creator_intern.h b/source/creator/creator_intern.h index a972a926677..fb6798d1a64 100644 --- a/source/creator/creator_intern.h +++ b/source/creator/creator_intern.h @@ -74,7 +74,7 @@ extern struct ApplicationState app_state; /* creator.c */ /* from buildinfo.c */ #ifdef BUILD_DATE - extern char build_date[]; +extern char build_date[]; extern char build_time[]; extern char build_hash[]; extern unsigned long build_commit_timestamp; diff --git a/source/creator/creator_signals.c b/source/creator/creator_signals.c index 80aba762cfc..51b5ffbb0c1 100644 --- a/source/creator/creator_signals.c +++ b/source/creator/creator_signals.c @@ -75,6 +75,14 @@ #include "creator_intern.h" /* own include */ +#ifdef WITH_CRASHPAD + void crashpad_init(void); + void breakpad_write(void); + #ifdef WIN32 + void crashpad_activate(void *ExceptionInfo); + #endif +#endif + /* set breakpoints here when running in debug mode, useful to catch floating point errors */ #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE) static void sig_handle_fpe(int UNUSED(sig)) @@ -174,6 +182,12 @@ static void sig_handle_crash(int signum) /* Delete content of temp dir! */ BKE_tempdir_session_purge(); +#if defined(WITH_CRASHPAD) && !defined(__APPLE__) + //linux only, try to write the dump now (instead of relying on own exception handler) + //this generates DUMP_REQUESTED issues + breakpad_write(); +#endif + /* really crash */ signal(signum, SIG_DFL); #ifndef WIN32 @@ -258,7 +272,11 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo) * where the error happened */ if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { #ifdef NDEBUG + #ifdef WITH_CRASHPAD + crashpad_activate(ExceptionInfo); + #else TerminateProcess(GetCurrentProcess(), SIGSEGV); + #endif #else sig_handle_crash(SIGSEGV); #endif @@ -279,10 +297,16 @@ void main_signal_setup(void) { if (app_state.signal.use_crash_handler) { #ifdef WIN32 - SetUnhandledExceptionFilter(windows_exception_handler); + #ifdef WITH_CRASHPAD + crashpad_init(); + #endif + SetUnhandledExceptionFilter(windows_exception_handler); #else + #if defined(WITH_CRASHPAD) && defined(__APPLE__) + crashpad_init(); + #endif /* after parsing args */ - signal(SIGSEGV, sig_handle_crash); + signal(SIGSEGV, sig_handle_crash); #endif } @@ -325,4 +349,4 @@ void main_signal_setup_fpe(void) #endif } -#endif /* WITH_PYTHON_MODULE */
\ No newline at end of file +#endif /* WITH_PYTHON_MODULE */ |