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;
8486LPTOP_LEVEL_EXCEPTION_FILTER crashpadInternalExceptionFilterMethod = nullptr ;
8587HANDLE memoryDumpEvent = INVALID_HANDLE_VALUE;
8688std::filesystem::path memoryDumpFolder;
89+ #elif defined(__APPLE__)
90+ struct sigaction oldSegv = {};
91+ struct sigaction oldAbrt = {};
92+ struct sigaction oldBus = {};
8793#endif
8894
8995std::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
0 commit comments