GCC Code Coverage Report


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