GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/monitor.h
Date: 2026-04-05 02:35:23
Exec Total Coverage
Lines: 0 10 0.0%
Branches: 0 0 -%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_MONITOR_H_
6 #define CVMFS_MONITOR_H_
7
8 #include <pthread.h>
9 #include <signal.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12
13 #include <map>
14 #include <string>
15
16 #include "util/pipe.h"
17 #include "util/platform.h"
18 #include "util/pointer.h"
19 #include "util/single_copy.h"
20
21
22 /**
23 * Information for the FUSE module to communicate with the watchdog process
24 * that needs to be preserved through reloads.
25 */
26 class WatchdogState {
27 friend class Watchdog;
28 public:
29 WatchdogState() :
30 version(0),
31 watchdog_write_fd(-1),
32 listener_read_fd(-1),
33 spawned(false),
34 pid(0)
35 { }
36 private:
37 unsigned version;
38 int watchdog_write_fd;
39 int listener_read_fd;
40 bool spawned;
41 pid_t pid;
42 };
43
44
45 /**
46 * This class can fork a watchdog process that listens on a pipe and prints a
47 * stackstrace into syslog, when cvmfs fails. The crash dump is also appended
48 * to the crash dump file, if the path is not empty. Singleton.
49 *
50 * The watchdog process if forked on Create and put on hold. Spawn() will start
51 * the supervision and set the crash dump path. It should be called from the
52 * final supervisee pid (after daemon etc.) but preferably before any threads
53 * are started.
54 *
55 * Note: logging should be set up before calling Create()
56 */
57 class Watchdog : SingleCopy {
58 public:
59 /**
60 * Crash cleanup handler signature.
61 */
62 typedef void (*FnOnExit)(const bool crashed);
63
64 static Watchdog *Create(FnOnExit on_exit,
65 bool needs_read_environ,
66 WatchdogState *saved_state = 0);
67 static pid_t GetPid();
68 ~Watchdog();
69 void Spawn(const std::string &crash_dump_path);
70 void ClearOnExitFn() { on_exit_ = NULL; }
71 void EnterMaintenanceMode() { maintenance_mode_ = true; }
72 void SaveState(WatchdogState *state);
73
74 /**
75 * Signals that watchdog should not receive. If it does, report and exit.
76 */
77 static int g_suppressed_signals[13];
78 /**
79 * Signals used by crash signal handler. If received, create a stack trace.
80 */
81 static int g_crash_signals[8];
82
83 private:
84 typedef std::map<int, struct sigaction> SigactionMap;
85
86 struct CrashData {
87 int signal;
88 int sys_errno;
89 pid_t pid;
90 };
91
92 struct ControlFlow {
93 enum Flags {
94 kProduceStacktrace = 0,
95 kQuit,
96 kQuitWithExit,
97 kSupervise,
98 kUnknown,
99 };
100 };
101
102 /**
103 * Preallocated memory block to make sure that signal handler don't run into
104 * stack overflows.
105 */
106 static const unsigned kSignalHandlerStacksize = 2 * 1024 * 1024; // 2 MB
107 /**
108 * If the GDB/LLDB method of generating a stack trace fails, fall back to
109 * libc's backtrace with a maximum depth.
110 */
111 static const unsigned kMaxBacktrace = 64;
112
113 static Watchdog *instance_;
114 static Watchdog *Me() { return instance_; }
115
116 static void *MainWatchdogListener(void *data);
117
118 static void ReportSignalAndContinue(int sig, siginfo_t *siginfo,
119 void *context);
120 static void SendTrace(int sig, siginfo_t *siginfo, void *context);
121
122 explicit Watchdog(FnOnExit on_exit);
123 void Fork(bool needs_read_environ);
124 void RestoreState(WatchdogState *saved_state);
125 bool WaitForSupervisee();
126 SigactionMap SetSignalHandlers(const SigactionMap &signal_handlers);
127 void Supervise();
128 void LogEmergency(std::string msg);
129 std::string ReportStacktrace();
130 std::string GenerateStackTrace(pid_t pid);
131 std::string ReadUntilGdbPrompt(int fd_pipe);
132
133 bool spawned_;
134 bool maintenance_mode_;
135 std::string crash_dump_path_;
136 std::string exe_path_;
137 pid_t watchdog_pid_;
138 UniquePtr<Pipe<kPipeWatchdog> > pipe_watchdog_;
139 /// The supervisee makes sure its watchdog does not die
140 UniquePtr<Pipe<kPipeWatchdogSupervisor> > pipe_listener_;
141 /// Send the terminate signal to the listener
142 UniquePtr<Pipe<kPipeThreadTerminator> > pipe_terminate_;
143 pthread_t thread_listener_;
144 FnOnExit on_exit_;
145 platform_spinlock lock_handler_;
146 stack_t sighandler_stack_;
147 SigactionMap old_signal_handlers_;
148 };
149
150 #endif // CVMFS_MONITOR_H_
151