GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/monitor.h
Date: 2026-03-15 02:35:27
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, WatchdogState *saved_state = 0);
65 static pid_t GetPid();
66 ~Watchdog();
67 void Spawn(const std::string &crash_dump_path);
68 void ClearOnExitFn() { on_exit_ = NULL; }
69 void EnterMaintenanceMode() { maintenance_mode_ = true; }
70 void SaveState(WatchdogState *state);
71
72 /**
73 * Signals that watchdog should not receive. If it does, report and exit.
74 */
75 static int g_suppressed_signals[13];
76 /**
77 * Signals used by crash signal handler. If received, create a stack trace.
78 */
79 static int g_crash_signals[8];
80
81 private:
82 typedef std::map<int, struct sigaction> SigactionMap;
83
84 struct CrashData {
85 int signal;
86 int sys_errno;
87 pid_t pid;
88 };
89
90 struct ControlFlow {
91 enum Flags {
92 kProduceStacktrace = 0,
93 kQuit,
94 kQuitWithExit,
95 kSupervise,
96 kUnknown,
97 };
98 };
99
100 /**
101 * Preallocated memory block to make sure that signal handler don't run into
102 * stack overflows.
103 */
104 static const unsigned kSignalHandlerStacksize = 2 * 1024 * 1024; // 2 MB
105 /**
106 * If the GDB/LLDB method of generating a stack trace fails, fall back to
107 * libc's backtrace with a maximum depth.
108 */
109 static const unsigned kMaxBacktrace = 64;
110
111 static Watchdog *instance_;
112 static Watchdog *Me() { return instance_; }
113
114 static void *MainWatchdogListener(void *data);
115
116 static void ReportSignalAndContinue(int sig, siginfo_t *siginfo,
117 void *context);
118 static void SendTrace(int sig, siginfo_t *siginfo, void *context);
119
120 explicit Watchdog(FnOnExit on_exit);
121 void Fork();
122 void RestoreState(WatchdogState *saved_state);
123 bool WaitForSupervisee();
124 SigactionMap SetSignalHandlers(const SigactionMap &signal_handlers);
125 void Supervise();
126 void LogEmergency(std::string msg);
127 std::string ReportStacktrace();
128 std::string GenerateStackTrace(pid_t pid);
129 std::string ReadUntilGdbPrompt(int fd_pipe);
130
131 bool spawned_;
132 bool maintenance_mode_;
133 std::string crash_dump_path_;
134 std::string exe_path_;
135 pid_t watchdog_pid_;
136 UniquePtr<Pipe<kPipeWatchdog> > pipe_watchdog_;
137 /// The supervisee makes sure its watchdog does not die
138 UniquePtr<Pipe<kPipeWatchdogSupervisor> > pipe_listener_;
139 /// Send the terminate signal to the listener
140 UniquePtr<Pipe<kPipeThreadTerminator> > pipe_terminate_;
141 pthread_t thread_listener_;
142 FnOnExit on_exit_;
143 platform_spinlock lock_handler_;
144 stack_t sighandler_stack_;
145 SigactionMap old_signal_handlers_;
146 };
147
148 #endif // CVMFS_MONITOR_H_
149