feature add sentry for catch crash on win (#50)

* feature add sentry for soft catch dmp

* feature add cli upload pdb to sentry server

* feature add flag for control sentry to use

* fix  flag not effect on src/makefile

* feature unzip for dmp file to upload sentry server

* feature remove test code

* feature add api for function report log to server

* feature update the soft version
This commit is contained in:
Alves
2025-12-05 09:19:32 +08:00
committed by GitHub
parent b28f1f2de4
commit b0b7890c9e
17 changed files with 599 additions and 159 deletions

View File

@@ -6,16 +6,15 @@
#include <Windows.h>
#include <shellapi.h>
#include <wchar.h>
#include <shlobj.h>
#include "sentry_wrapper/SentryWrapper.hpp"
#ifdef SLIC3R_GUI
extern "C"
{
// Let the NVIDIA and AMD know we want to use their graphics card
// on a dual graphics card system.
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000000;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0;
extern "C" {
// Let the NVIDIA and AMD know we want to use their graphics card
// on a dual graphics card system.
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000000;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0;
}
#endif /* SLIC3R_GUI */
@@ -23,7 +22,7 @@ extern "C"
#include <stdio.h>
#ifdef SLIC3R_GUI
#include <GL/GL.h>
#include <GL/GL.h>
#endif /* SLIC3R_GUI */
#include <string>
@@ -31,9 +30,11 @@ extern "C"
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/asio/ip/host_name.hpp>
#include <stdio.h>
using namespace Slic3r;
#ifdef SLIC3R_GUI
class OpenGLVersionCheck
{
@@ -43,23 +44,24 @@ public:
std::string vendor;
std::string renderer;
HINSTANCE hOpenGL = nullptr;
bool success = false;
HINSTANCE hOpenGL = nullptr;
bool success = false;
bool load_opengl_dll()
{
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc;
wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr);
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.hInstance = (HINSTANCE) GetModuleHandle(nullptr);
wc.hbrBackground = (HBRUSH) (COLOR_BACKGROUND);
wc.lpszClassName = L"Snapmaker_Orca_opengl_version_check";
wc.style = CS_OWNDC;
wc.style = CS_OWNDC;
if (RegisterClass(&wc)) {
HWND hwnd = CreateWindowW(wc.lpszClassName, L"Snapmaker_Orca_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this);
HWND hwnd = CreateWindowW(wc.lpszClassName, L"Snapmaker_Orca_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0,
wc.hInstance, (LPVOID) this);
if (hwnd) {
message_pump_exit = false;
while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit)
while (GetMessage(&msg, NULL, 0, 0) > 0 && !message_pump_exit)
DispatchMessage(&msg);
}
}
@@ -115,40 +117,47 @@ protected:
return;
}
typedef HGLRC (WINAPI *Func_wglCreateContext)(HDC);
typedef BOOL (WINAPI *Func_wglMakeCurrent )(HDC, HGLRC);
typedef BOOL (WINAPI *Func_wglDeleteContext)(HGLRC);
typedef GLubyte* (WINAPI *Func_glGetString )(GLenum);
typedef HGLRC(WINAPI * Func_wglCreateContext)(HDC);
typedef BOOL(WINAPI * Func_wglMakeCurrent)(HDC, HGLRC);
typedef BOOL(WINAPI * Func_wglDeleteContext)(HGLRC);
typedef GLubyte*(WINAPI * Func_glGetString)(GLenum);
Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext");
Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent");
Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext");
Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString");
Func_wglCreateContext wglCreateContext = (Func_wglCreateContext) GetProcAddress(hOpenGL, "wglCreateContext");
Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent");
Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext) GetProcAddress(hOpenGL, "wglDeleteContext");
Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString");
if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) {
printf("Failed loading the system opengl32.dll: The library is invalid.\n");
return;
}
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Color depth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
PIXELFORMATDESCRIPTOR pfd = {sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Color depth of the framebuffer.
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0,
0,
0};
HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd);
// Gdi32.dll
@@ -159,17 +168,17 @@ protected:
HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext);
wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext);
// Opengl32.dll
const char *data = (const char*)glGetString(GL_VERSION);
const char* data = (const char*) glGetString(GL_VERSION);
if (data != nullptr)
this->version = data;
// printf("check -version: %s\n", version.c_str());
data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION
data = (const char*) glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION
if (data != nullptr)
this->glsl_version = data;
data = (const char*)glGetString(GL_VENDOR);
data = (const char*) glGetString(GL_VENDOR);
if (data != nullptr)
this->vendor = data;
data = (const char*)glGetString(GL_RENDERER);
data = (const char*) glGetString(GL_RENDERER);
if (data != nullptr)
this->renderer = data;
// Opengl32.dll
@@ -180,21 +189,16 @@ protected:
static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
{
CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
OpenGLVersionCheck *ogl_data = reinterpret_cast<OpenGLVersionCheck*>(pCreate->lpCreateParams);
switch (message) {
case WM_CREATE: {
CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
OpenGLVersionCheck* ogl_data = reinterpret_cast<OpenGLVersionCheck*>(pCreate->lpCreateParams);
ogl_data->check(hWnd);
DestroyWindow(hWnd);
return 0;
}
case WM_NCDESTROY:
message_pump_exit = true;
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_NCDESTROY: message_pump_exit = true; return 0;
default: return DefWindowProc(hWnd, message, wParam, lParam);
}
}
};
@@ -203,18 +207,18 @@ bool OpenGLVersionCheck::message_pump_exit = false;
#endif /* SLIC3R_GUI */
extern "C" {
typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv);
Slic3rMainFunc Snapmaker_Orca_main = nullptr;
typedef int(__stdcall* Slic3rMainFunc)(int argc, wchar_t** argv);
Slic3rMainFunc Snapmaker_Orca_main = nullptr;
}
extern "C" {
#ifdef SLIC3R_WRAPPER_NOCONSOLE
int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */)
{
int argc;
wchar_t **argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
int argc;
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
#else
int wmain(int argc, wchar_t **argv)
int wmain(int argc, wchar_t** argv)
{
#endif
// Allow the asserts to open message box, such message box allows to ignore the assert and continue with the application.
@@ -222,9 +226,10 @@ int wmain(int argc, wchar_t **argv)
// the application will be killed even if "Ignore" button is pressed.
_set_error_mode(_OUT_TO_MSGBOX);
initSentry();
std::vector<wchar_t*> argv_extended;
argv_extended.emplace_back(argv[0]);
#ifdef SLIC3R_WRAPPER_GCODEVIEWER
wchar_t gcodeviewer_param[] = L"--gcodeviewer";
argv_extended.emplace_back(gcodeviewer_param);
@@ -234,7 +239,7 @@ int wmain(int argc, wchar_t **argv)
// Here one may push some additional parameters based on the wrapper type.
bool force_mesa = false;
#endif /* SLIC3R_GUI */
for (int i = 1; i < argc; ++ i) {
for (int i = 1; i < argc; ++i) {
#ifdef SLIC3R_GUI
if (wcscmp(argv[i], L"--sw-renderer") == 0)
force_mesa = true;
@@ -247,14 +252,14 @@ int wmain(int argc, wchar_t **argv)
#ifdef SLIC3R_GUI
OpenGLVersionCheck opengl_version_check;
bool load_mesa =
bool load_mesa =
// Forced from the command line.
force_mesa ||
// Try to load the default OpenGL driver and test its context version.
! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0);
!opengl_version_check.load_opengl_dll() || !opengl_version_check.is_version_greater_or_equal_to(2, 0);
#endif /* SLIC3R_GUI */
wchar_t path_to_exe[MAX_PATH + 1] = { 0 };
wchar_t path_to_exe[MAX_PATH + 1] = {0};
::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH);
wchar_t drive[_MAX_DRIVE];
wchar_t dir[_MAX_DIR];
@@ -264,11 +269,11 @@ int wmain(int argc, wchar_t **argv)
_wmakepath(path_to_exe, drive, dir, nullptr, nullptr);
#ifdef SLIC3R_GUI
// https://wiki.qt.io/Cross_compiling_Mesa_for_Windows
// http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
// https://wiki.qt.io/Cross_compiling_Mesa_for_Windows
// http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
if (load_mesa) {
opengl_version_check.unload_opengl_dll();
wchar_t path_to_mesa[MAX_PATH + 1] = { 0 };
wchar_t path_to_mesa[MAX_PATH + 1] = {0};
wcscpy(path_to_mesa, path_to_exe);
wcscat(path_to_mesa, L"mesa\\opengl32.dll");
printf("Loading MESA OpenGL library: %S\n", path_to_mesa);
@@ -280,31 +285,36 @@ int wmain(int argc, wchar_t **argv)
}
#endif /* SLIC3R_GUI */
wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 };
wchar_t path_to_slic3r[MAX_PATH + 1] = {0};
wcscpy(path_to_slic3r, path_to_exe);
wcscat(path_to_slic3r, L"Snapmaker_Orca.dll");
// printf("Loading Slic3r library: %S\n", path_to_slic3r);
// printf("Loading Slic3r library: %S\n", path_to_slic3r);
HINSTANCE hInstance_Slic3r = LoadLibraryExW(path_to_slic3r, nullptr, 0);
if (hInstance_Slic3r == nullptr) {
printf("Snapmaker_Orca.dll was not loaded, error=%d\n", GetLastError());
exitSentry();
return -1;
}
// resolve function address here
Snapmaker_Orca_main = (Slic3rMainFunc)GetProcAddress(hInstance_Slic3r,
Snapmaker_Orca_main = (Slic3rMainFunc)
GetProcAddress(hInstance_Slic3r,
#ifdef _WIN64
// there is just a single calling conversion, therefore no mangling of the function name.
"Snapmaker_Orca_main"
#else // stdcall calling convention declaration
"_bambustu_main@8"
// there is just a single calling conversion, therefore no mangling of the function name.
"Snapmaker_Orca_main"
#else // stdcall calling convention declaration
"_bambustu_main@8"
#endif
);
if (Snapmaker_Orca_main == nullptr) {
printf("could not locate the function Snapmaker_Orca_main in Snapmaker_Orca.dll\n");
exitSentry();
return -1;
}
// argc minus the trailing nullptr of the argv
return Snapmaker_Orca_main((int)argv_extended.size() - 1, argv_extended.data());
auto res = Snapmaker_Orca_main((int) argv_extended.size() - 1, argv_extended.data());
exitSentry();
return res;
}
}