Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #135

Merged
merged 3 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build_scripts/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ def download_addon(name,addonName,url,commitId=None):
curDir = os.getcwd()
if not skip_repository_updates:
if with_pfm:
download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","183eaf445f648b7c055b2ba1f5ff4f7681c3ae36")
download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","66f6c05d0fa36272c5caba1dcc8e15a34386cc50")
download_addon("model editor","tool_model_editor","https://github.com/Silverlan/pragma_model_editor.git","a9ea4820f03be250bdf1e6951dad313561b75b17")

if with_vr:
Expand Down
1 change: 1 addition & 0 deletions core/client/src/c_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,7 @@ bool CEngine::Initialize(int argc, char *argv[])
contextCreateInfo.width = 1280;
contextCreateInfo.height = 1024;
contextCreateInfo.windowless = g_windowless;
contextCreateInfo.enableDiagnostics = IsGfxDiagnosticsModeEnabled();

std::shared_ptr<udm::Data> renderApiData {};
try {
Expand Down
12 changes: 9 additions & 3 deletions core/pragma/include/pragma/pragma_executable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ namespace pragma {
~ModuleWrapper()
{
#ifdef _WIN32
if(std::uncaught_exceptions() > 0) {
// If we're stack unwinding due to an uncaught exception,
// we DON'T want to release the library, since we'll need
// the library to collect information for our crashdump!
return;
}
FreeLibrary(handle);
#else
dlclose(handle);
Expand All @@ -103,9 +109,9 @@ namespace pragma {
static std::unique_ptr<ModuleWrapper> launch_pragma(int argc, char *argv[], bool server = false)
{
#ifdef __linux__
const char *library = server ? "libshared.so" : "libclient.so";
const char *library = server ? "libshared.so" : "libclient.so";
#else
const char *library = server ? "shared.dll" : "client.dll";
const char *library = server ? "shared.dll" : "client.dll";
#endif
const char *runEngineSymbol = server ? "RunEngine" : "RunCEngine";

Expand Down Expand Up @@ -149,7 +155,7 @@ namespace pragma {
#if 0
std::thread t([]() { std::cout << "Linux Thread Test"; });
#endif
void (*runEngine)(int, char *[]) = (void (*)(int, char *[]))dlsym(hEngine, runEngineSymbol);
void (*runEngine)(int, char *[]) = (void (*)(int, char *[]))dlsym(hEngine, runEngineSymbol);
if(runEngine != nullptr) {
runEngine(argc, argv);
return wrapper;
Expand Down
4 changes: 3 additions & 1 deletion core/shared/include/pragma/debug/mdump.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ typedef BOOL(WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFi
namespace pragma::debug {
class DLLNETWORK CrashHandler {
public:
CrashHandler(const std::string &appName);
static CrashHandler &Get();
CrashHandler();
~CrashHandler();
void SetAppName(const std::string &appName);
private:
bool GenerateCrashDump() const;
std::string m_appName;
Expand Down
4 changes: 2 additions & 2 deletions core/shared/include/pragma/engine_init.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ template<class T>
std::shared_ptr<T> InitializeEngine(int argc, char *argv[])
{
auto exe = engine_info::get_executable_name();
pragma::debug::CrashHandler dmp(exe);
pragma::debug::CrashHandler::Get().SetAppName(exe);
auto en = std::shared_ptr<T> {new T {argc, argv}, [](T *p) {
#ifdef _WIN32
if(std::uncaught_exceptions() > 0) {
Expand All @@ -40,7 +40,7 @@ std::shared_ptr<T> InitializeEngine(int argc, char *argv[])
inline DLLNETWORK std::shared_ptr<Engine> InitializeServer(int argc, char *argv[])
{
auto exe = engine_info::get_executable_name();
pragma::debug::CrashHandler dmp(exe);
pragma::debug::CrashHandler::Get().SetAppName(exe);
auto en = std::shared_ptr<Engine> {new Engine {argc, argv}, [](Engine *p) {
if(std::uncaught_exceptions() > 0) {
// If we're stack unwinding due to an uncaught exception,
Expand Down
34 changes: 20 additions & 14 deletions core/shared/src/debug/mdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,17 @@ extern DLLNETWORK Engine *engine;
using namespace pragma::debug;

std::string g_crashExceptionMessage = {};
static CrashHandler *g_crashHandler = nullptr;
CrashHandler::CrashHandler(const std::string &appName) : m_appName {appName}
static CrashHandler g_crashHandler {};
CrashHandler &CrashHandler::Get() { return g_crashHandler; }
CrashHandler::CrashHandler()
{
assert(!g_crashHandler);
g_crashHandler = this;
#ifdef _WIN32
::SetUnhandledExceptionFilter(TopLevelFilter);
#else
signal(
SIGSEGV, +[](int sig) {
if(!g_crashHandler) {
exit(1);
return;
}
g_crashHandler->m_sig = sig;
g_crashHandler->GenerateCrashDump();
g_crashHandler.m_sig = sig;
g_crashHandler.GenerateCrashDump();
exit(1);
});
#endif
Expand All @@ -72,7 +67,9 @@ CrashHandler::CrashHandler(const std::string &appName) : m_appName {appName}
});
}

CrashHandler::~CrashHandler() { g_crashHandler = nullptr; }
void CrashHandler::SetAppName(const std::string &appName) { m_appName = appName; }

CrashHandler::~CrashHandler() {}

#ifdef _WIN32
BOOL CALLBACK MyMiniDumpCallback(PVOID pParam, const PMINIDUMP_CALLBACK_INPUT pInput, PMINIDUMP_CALLBACK_OUTPUT pOutput);
Expand Down Expand Up @@ -343,12 +340,21 @@ bool CrashHandler::GenerateCrashDump() const
}

#ifdef _WIN32
static auto g_crashDumpGenerated = false;
static std::mutex g_crashMutex;
LONG CrashHandler::TopLevelFilter(struct _EXCEPTION_POINTERS *pExceptionInfo)
{
if(!g_crashHandler)
// When a crash occurs, there's a good chance that other threads will also crash.
// This can cause the entire application to die before the crash dump has been fully generated.
// Since we probably only care about the first crash anyway, we'll simply make all other threads wait
// until the crash dump has been generated.
std::unique_lock<std::mutex> lock {g_crashMutex};
if(g_crashDumpGenerated)
return EXCEPTION_CONTINUE_SEARCH;
g_crashHandler->m_pExceptionInfo = pExceptionInfo;
g_crashHandler->GenerateCrashDump();

g_crashDumpGenerated = true;
g_crashHandler.m_pExceptionInfo = pExceptionInfo;
g_crashHandler.GenerateCrashDump();
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
2 changes: 2 additions & 0 deletions core/shared/src/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,8 @@ void Engine::DumpDebugInformation(uzip::ZIPFile &zip) const
fWriteConvars(GetServerNetworkState()->GetConVars(), "cvars_sv.txt");
fWriteLuaTraceback(GetServerNetworkState()->GetLuaState(), "sv");
}

const_cast<Engine *>(this)->CallCallbacks<void, std::reference_wrapper<uzip::ZIPFile>>("DumpDebugInformation", zip);
}

const long long &Engine::GetLastTick() const { return m_lastTick; }
Expand Down
Loading