File: crash_handler_host_linux.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (187 lines) | stat: -rw-r--r-- 6,033 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_HANDLER_HOST_LINUX_H_
#define COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_HANDLER_HOST_LINUX_H_

#include <sys/types.h>

#include <memory>
#include <set>
#include <string>

#include "base/containers/heap_array.h"
#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/memory/raw_ptr.h"
#include "base/message_loop/message_pump_for_io.h"
#include "base/process/process_handle.h"
#include "base/synchronization/atomic_flag.h"
#include "base/synchronization/lock.h"
#include "base/task/current_thread.h"
#include "build/build_config.h"

#if !BUILDFLAG(IS_ANDROID)
#include "components/crash/core/app/breakpad_linux_impl.h"
#endif

namespace base {
class SequencedTaskRunner;
class Thread;
}

#if !BUILDFLAG(IS_ANDROID)

namespace breakpad {

struct BreakpadInfo;

// This is the host for processes which run breakpad inside the sandbox on
// Linux or Android. We perform the crash dump from the browser because it
// allows us to be outside the sandbox.
//
// Processes signal that they need to be dumped by sending a datagram over a
// UNIX domain socket. All processes of the same type share the client end of
// this socket which is installed in their descriptor table before exec.
class CrashHandlerHostLinux : public base::MessagePumpForIO::FdWatcher,
                              public base::CurrentThread::DestructionObserver {
 public:
  CrashHandlerHostLinux(const std::string& process_type,
                        const base::FilePath& dumps_path,
                        bool upload);

  CrashHandlerHostLinux(const CrashHandlerHostLinux&) = delete;
  CrashHandlerHostLinux& operator=(const CrashHandlerHostLinux&) = delete;

  ~CrashHandlerHostLinux() override;

  // Starts the uploader thread. Must be called immediately after creating the
  // class.
  void StartUploaderThread();

  // Get the file descriptor which processes should be given in order to signal
  // crashes to the browser.
  int GetDeathSignalSocket() const {
    return process_socket_;
  }

  // MessagePumbLibevent::Watcher impl:
  void OnFileCanWriteWithoutBlocking(int fd) override;
  void OnFileCanReadWithoutBlocking(int fd) override;

  // CurrentThread::DestructionObserver impl:
  void WillDestroyCurrentMessageLoop() override;

  // Whether we are shutting down or not.
  bool IsShuttingDown() const;

 private:
  void Init();

  // Do work on |blocking_task_runner_| for OnFileCanReadWithoutBlocking().
  void WriteDumpFile(BreakpadInfo* info,
                     base::HeapArray<char> crash_context,
                     pid_t crashing_pid);

  // Continue OnFileCanReadWithoutBlocking()'s work on the IO thread.
  void QueueCrashDumpTask(std::unique_ptr<BreakpadInfo> info, int signal_fd);

  // Find crashing thread (may delay and retry) and dump on IPC thread.
  void FindCrashingThreadAndDump(
      pid_t crashing_pid,
      const std::string& expected_syscall_data,
      base::HeapArray<char> crash_context,
      std::unique_ptr<crash_reporter::internal::TransitionalCrashKeyStorage>
          crash_keys,
#if defined(ADDRESS_SANITIZER)
      base::HeapArray<char> asan_report,
#endif
      uint64_t uptime,
      size_t oom_size,
      int signal_fd,
      int attempt);

  const std::string process_type_;
  const base::FilePath dumps_path_;
#if !BUILDFLAG(IS_ANDROID)
  const bool upload_;
#endif

  int process_socket_;
  int browser_socket_;

  base::MessagePumpForIO::FdWatchController fd_watch_controller_;
  std::unique_ptr<base::Thread> uploader_thread_;
  base::AtomicFlag shutting_down_;

  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
};

}  // namespace breakpad

#endif  // !BUILDFLAG(IS_ANDROID)

#if !BUILDFLAG(IS_CHROMEOS)

namespace crashpad {

class CrashHandlerHost : public base::MessagePumpForIO::FdWatcher,
                         public base::CurrentThread::DestructionObserver {
 public:
  // An interface for observers to be notified when a child process is crashing.
  class Observer {
   public:
    // Called when a child process is crashing. pid is the child's process ID in
    // the CrashHandlerHost's PID namespace. signo is the signal the child
    // received. Observers are notified synchronously while the child process
    // is blocked in its signal handler. Observers may not call AddObserver()
    // or RemoveObserver() in this method.
    virtual void ChildReceivedCrashSignal(base::ProcessId pid, int signo) = 0;
  };

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Return a pointer to the global CrashHandlerHost instance, which is created
  // by the first call to this method.
  static CrashHandlerHost* Get();

  CrashHandlerHost(const CrashHandlerHost&) = delete;
  CrashHandlerHost& operator=(const CrashHandlerHost&) = delete;

  // Get the file descriptor which processes should be given in order to signal
  // crashes to the browser.
  int GetDeathSignalSocket();

 protected:
  ~CrashHandlerHost() override;

 private:
  CrashHandlerHost();

  void Init();
  bool ReceiveClientMessage(int client_fd,
                            base::ScopedFD* handler_fd,
                            bool* write_minidump_to_database);
  void NotifyCrashSignalObservers(base::ProcessId pid, int signo);

  // MessagePumbLibevent::Watcher impl:
  void OnFileCanWriteWithoutBlocking(int fd) override;
  void OnFileCanReadWithoutBlocking(int fd) override;

  // CurrentThread::DestructionObserver impl:
  void WillDestroyCurrentMessageLoop() override;

  base::Lock observers_lock_;
  std::set<raw_ptr<Observer, SetExperimental>> observers_;
  base::MessagePumpForIO::FdWatchController fd_watch_controller_;
  base::ScopedFD process_socket_;
  base::ScopedFD browser_socket_;
};

}  // namespace crashpad

#endif  // !BUILDFLAG(IS_CHROMEOS)

#endif  // COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_HANDLER_HOST_LINUX_H_