Skip to content

Commit d3126b6

Browse files
committed
[Mac] Add a sigaction handler and set appRunning before worker starts
* set a sigaction handler to populate crash dumps with breadcrumbs * make "process list" one line
1 parent 62bd792 commit d3126b6

File tree

3 files changed

+62
-10
lines changed

3 files changed

+62
-10
lines changed

obs-studio-server/source/util-crashmanager.cpp

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
#include "psapi.h"
5454
#elif defined(__APPLE__)
5555
#include <libproc.h>
56+
#include <signal.h>
57+
#include <unistd.h>
5658
#endif
5759

5860
#include "nodeobs_api.h"
@@ -84,6 +86,10 @@ util::MetricsProvider metricsClient;
8486
LPTOP_LEVEL_EXCEPTION_FILTER crashpadInternalExceptionFilterMethod = nullptr;
8587
HANDLE memoryDumpEvent = INVALID_HANDLE_VALUE;
8688
std::filesystem::path memoryDumpFolder;
89+
#elif defined(__APPLE__)
90+
struct sigaction oldSegv = {};
91+
struct sigaction oldAbrt = {};
92+
struct sigaction oldBus = {};
8793
#endif
8894

8995
std::string appState = "starting"; // "starting","idle","encoding","shutdown"
@@ -281,7 +287,7 @@ nlohmann::json RequestProcessList()
281287

282288
return result;
283289
#else
284-
nlohmann::json result = nlohmann::json::array();
290+
nlohmann::json result = nlohmann::json::object();
285291

286292
int max_pids = 1024;
287293
std::vector<pid_t> pids(max_pids);
@@ -292,24 +298,32 @@ nlohmann::json RequestProcessList()
292298
return result;
293299
}
294300

301+
int skipped_processes_count = 0;
302+
int unprocessed_processes_count = 0;
303+
int total_processes_count = 0;
295304
int count = num_pids / sizeof(pid_t);
296305
for (int i = 0; i < count; ++i) {
297-
if (pids[i] == 0)
306+
if (pids[i] == 0) {
307+
skipped_processes_count++;
298308
continue;
309+
}
299310

300311
struct proc_bsdinfo procInfo;
301312
int ret = proc_pidinfo(pids[i], PROC_PIDTBSDINFO, 0, &procInfo, sizeof(proc_bsdinfo));
302-
if (ret <= 0)
313+
if (ret <= 0) {
314+
unprocessed_processes_count++;
303315
continue; // Skip if information can't be retrieved
316+
}
304317

305-
nlohmann::json procInfoJson;
306-
procInfoJson["PID"] = pids[i];
307-
procInfoJson["Name"] = std::string(procInfo.pbi_name);
308-
procInfoJson["UID"] = procInfo.pbi_uid;
309-
procInfoJson["GID"] = procInfo.pbi_gid;
310-
result.push_back(procInfoJson);
318+
std::ostringstream oss;
319+
oss << procInfo.pbi_name << " UID " << procInfo.pbi_uid << " GID " << procInfo.pbi_gid;
320+
result.push_back({std::to_string(pids[i]), oss.str()});
321+
total_processes_count++;
311322
}
312323

324+
std::ostringstream oss;
325+
oss << " Total " << total_processes_count << " proc_pidinfo failed " << unprocessed_processes_count << " skipped " << skipped_processes_count;
326+
result.push_back({std::to_string(0), oss.str()});
313327
return result;
314328

315329
#endif
@@ -487,6 +501,9 @@ bool util::CrashManager::Initialize(char *path, const std::string &appdata)
487501
if (!SetupCrashpad()) {
488502
return false;
489503
}
504+
#if defined(__APPLE__)
505+
InstallSigActionHandler();
506+
#endif
490507

491508
// Handler for obs errors (mainly for bcrash() calls)
492509
base_set_crash_handler(
@@ -1392,3 +1409,34 @@ void util::CrashManager::SaveToAppStateFile()
13921409
} catch (...) {
13931410
}
13941411
}
1412+
1413+
#if defined(__APPLE__)
1414+
void util::CrashManager::SignalActionHandler(int sig, siginfo_t *signalInfo, void *)
1415+
{
1416+
// Restore previous signal handler so it can handle our upcoming abort request
1417+
sigaction(SIGSEGV, &oldSegv, NULL);
1418+
sigaction(SIGABRT, &oldAbrt, NULL);
1419+
sigaction(SIGBUS, &oldBus, NULL);
1420+
1421+
std::ostringstream oss;
1422+
oss << "Fatal error sig: " << sig;
1423+
if (signalInfo) {
1424+
oss << " code: " << signalInfo->si_code;
1425+
oss << " addr: " << signalInfo->si_addr;
1426+
}
1427+
1428+
util::CrashManager::HandleCrash(oss.str());
1429+
}
1430+
1431+
void util::CrashManager::InstallSigActionHandler()
1432+
{
1433+
struct sigaction sa = {};
1434+
sa.sa_sigaction = SignalActionHandler;
1435+
sa.sa_flags = SA_SIGINFO;
1436+
sigemptyset(&sa.sa_mask);
1437+
1438+
sigaction(SIGSEGV, &sa, &oldSegv);
1439+
sigaction(SIGABRT, &sa, &oldAbrt);
1440+
sigaction(SIGBUS, &sa, &oldBus);
1441+
}
1442+
#endif

obs-studio-server/source/util-crashmanager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ class CrashManager {
9494
static void HandleCrash(const std::string &crashInfo, bool callAbort = true) noexcept;
9595
static void SaveBriefCrashInfoToFile();
9696
static void UpdateBriefCrashInfo();
97+
#if defined(__APPLE__)
98+
static void InstallSigActionHandler();
99+
static void SignalActionHandler(int sig, siginfo_t *, void *);
100+
#endif
97101
};
98102

99103
}; // namespace util

obs-studio-server/source/util-osx-impl.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ @implementation UtilImplObj
8686

8787
void UtilObjCInt::runApplication(void)
8888
{
89+
appRunning = true;
8990
worker = new std::thread(&UtilObjCInt::wait_terminate, this);
9091

9192
@autoreleasepool {
9293
NSApplication *app = [NSApplication sharedApplication];
93-
appRunning = true;
9494
[app run];
9595
}
9696
}

0 commit comments

Comments
 (0)