1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/debug/debugger.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <errno.h>
8*6777b538SAndroid Build Coastguard Worker #include <fcntl.h>
9*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
10*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
11*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
12*6777b538SAndroid Build Coastguard Worker #include <sys/param.h>
13*6777b538SAndroid Build Coastguard Worker #include <sys/stat.h>
14*6777b538SAndroid Build Coastguard Worker #include <sys/types.h>
15*6777b538SAndroid Build Coastguard Worker #include <unistd.h>
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker #include <memory>
18*6777b538SAndroid Build Coastguard Worker #include <string_view>
19*6777b538SAndroid Build Coastguard Worker
20*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/notimplemented.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
25*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker #if defined(__GLIBCXX__)
28*6777b538SAndroid Build Coastguard Worker #include <cxxabi.h>
29*6777b538SAndroid Build Coastguard Worker #endif
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
32*6777b538SAndroid Build Coastguard Worker #include <AvailabilityMacros.h>
33*6777b538SAndroid Build Coastguard Worker #endif
34*6777b538SAndroid Build Coastguard Worker
35*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_BSD)
36*6777b538SAndroid Build Coastguard Worker #include <sys/sysctl.h>
37*6777b538SAndroid Build Coastguard Worker #endif
38*6777b538SAndroid Build Coastguard Worker
39*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FREEBSD)
40*6777b538SAndroid Build Coastguard Worker #include <sys/user.h>
41*6777b538SAndroid Build Coastguard Worker #endif
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker #include <ostream>
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
46*6777b538SAndroid Build Coastguard Worker #include "base/debug/alias.h"
47*6777b538SAndroid Build Coastguard Worker #include "base/debug/debugging_buildflags.h"
48*6777b538SAndroid Build Coastguard Worker #include "base/environment.h"
49*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
50*6777b538SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
51*6777b538SAndroid Build Coastguard Worker #include "base/process/process.h"
52*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
53*6777b538SAndroid Build Coastguard Worker
54*6777b538SAndroid Build Coastguard Worker #if defined(USE_SYMBOLIZE)
55*6777b538SAndroid Build Coastguard Worker #include "base/third_party/symbolize/symbolize.h" // nogncheck
56*6777b538SAndroid Build Coastguard Worker #endif
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker namespace base {
59*6777b538SAndroid Build Coastguard Worker namespace debug {
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_BSD)
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker // Based on Apple's recommended method as described in
64*6777b538SAndroid Build Coastguard Worker // http://developer.apple.com/qa/qa2004/qa1361.html
BeingDebugged()65*6777b538SAndroid Build Coastguard Worker bool BeingDebugged() {
66*6777b538SAndroid Build Coastguard Worker // NOTE: This code MUST be async-signal safe (it's used by in-process
67*6777b538SAndroid Build Coastguard Worker // stack dumping signal handler). NO malloc or stdio is allowed here.
68*6777b538SAndroid Build Coastguard Worker //
69*6777b538SAndroid Build Coastguard Worker // While some code used below may be async-signal unsafe, note how
70*6777b538SAndroid Build Coastguard Worker // the result is cached (see |is_set| and |being_debugged| static variables
71*6777b538SAndroid Build Coastguard Worker // right below). If this code is properly warmed-up early
72*6777b538SAndroid Build Coastguard Worker // in the start-up process, it should be safe to use later.
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker // If the process is sandboxed then we can't use the sysctl, so cache the
75*6777b538SAndroid Build Coastguard Worker // value.
76*6777b538SAndroid Build Coastguard Worker static bool is_set = false;
77*6777b538SAndroid Build Coastguard Worker static bool being_debugged = false;
78*6777b538SAndroid Build Coastguard Worker
79*6777b538SAndroid Build Coastguard Worker if (is_set)
80*6777b538SAndroid Build Coastguard Worker return being_debugged;
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker // Initialize mib, which tells sysctl what info we want. In this case,
83*6777b538SAndroid Build Coastguard Worker // we're looking for information about a specific process ID.
84*6777b538SAndroid Build Coastguard Worker int mib[] = {
85*6777b538SAndroid Build Coastguard Worker CTL_KERN,
86*6777b538SAndroid Build Coastguard Worker KERN_PROC,
87*6777b538SAndroid Build Coastguard Worker KERN_PROC_PID,
88*6777b538SAndroid Build Coastguard Worker getpid()
89*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_OPENBSD)
90*6777b538SAndroid Build Coastguard Worker ,
91*6777b538SAndroid Build Coastguard Worker sizeof(struct kinfo_proc),
92*6777b538SAndroid Build Coastguard Worker 0
93*6777b538SAndroid Build Coastguard Worker #endif
94*6777b538SAndroid Build Coastguard Worker };
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker // Caution: struct kinfo_proc is marked __APPLE_API_UNSTABLE. The source and
97*6777b538SAndroid Build Coastguard Worker // binary interfaces may change.
98*6777b538SAndroid Build Coastguard Worker struct kinfo_proc info;
99*6777b538SAndroid Build Coastguard Worker size_t info_size = sizeof(info);
100*6777b538SAndroid Build Coastguard Worker
101*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_OPENBSD)
102*6777b538SAndroid Build Coastguard Worker if (sysctl(mib, std::size(mib), NULL, &info_size, NULL, 0) < 0)
103*6777b538SAndroid Build Coastguard Worker return -1;
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker mib[5] = (info_size / sizeof(struct kinfo_proc));
106*6777b538SAndroid Build Coastguard Worker #endif
107*6777b538SAndroid Build Coastguard Worker
108*6777b538SAndroid Build Coastguard Worker int sysctl_result = sysctl(mib, std::size(mib), &info, &info_size, NULL, 0);
109*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(sysctl_result, 0);
110*6777b538SAndroid Build Coastguard Worker if (sysctl_result != 0) {
111*6777b538SAndroid Build Coastguard Worker is_set = true;
112*6777b538SAndroid Build Coastguard Worker being_debugged = false;
113*6777b538SAndroid Build Coastguard Worker return being_debugged;
114*6777b538SAndroid Build Coastguard Worker }
115*6777b538SAndroid Build Coastguard Worker
116*6777b538SAndroid Build Coastguard Worker // This process is being debugged if the P_TRACED flag is set.
117*6777b538SAndroid Build Coastguard Worker is_set = true;
118*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FREEBSD)
119*6777b538SAndroid Build Coastguard Worker being_debugged = (info.ki_flag & P_TRACED) != 0;
120*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_BSD)
121*6777b538SAndroid Build Coastguard Worker being_debugged = (info.p_flag & P_TRACED) != 0;
122*6777b538SAndroid Build Coastguard Worker #else
123*6777b538SAndroid Build Coastguard Worker being_debugged = (info.kp_proc.p_flag & P_TRACED) != 0;
124*6777b538SAndroid Build Coastguard Worker #endif
125*6777b538SAndroid Build Coastguard Worker return being_debugged;
126*6777b538SAndroid Build Coastguard Worker }
127*6777b538SAndroid Build Coastguard Worker
VerifyDebugger()128*6777b538SAndroid Build Coastguard Worker void VerifyDebugger() {
129*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_LLDBINIT_WARNING)
130*6777b538SAndroid Build Coastguard Worker if (Environment::Create()->HasVar("CHROMIUM_LLDBINIT_SOURCED"))
131*6777b538SAndroid Build Coastguard Worker return;
132*6777b538SAndroid Build Coastguard Worker if (!BeingDebugged())
133*6777b538SAndroid Build Coastguard Worker return;
134*6777b538SAndroid Build Coastguard Worker DCHECK(false)
135*6777b538SAndroid Build Coastguard Worker << "Detected lldb without sourcing //tools/lldb/lldbinit.py. lldb may "
136*6777b538SAndroid Build Coastguard Worker "not be able to find debug symbols. Please see debug instructions for "
137*6777b538SAndroid Build Coastguard Worker "using //tools/lldb/lldbinit.py:\n"
138*6777b538SAndroid Build Coastguard Worker "https://chromium.googlesource.com/chromium/src/+/main/docs/"
139*6777b538SAndroid Build Coastguard Worker "lldbinit.md\n"
140*6777b538SAndroid Build Coastguard Worker "To continue anyway, type 'continue' in lldb. To always skip this "
141*6777b538SAndroid Build Coastguard Worker "check, define an environment variable CHROMIUM_LLDBINIT_SOURCED=1";
142*6777b538SAndroid Build Coastguard Worker #endif
143*6777b538SAndroid Build Coastguard Worker }
144*6777b538SAndroid Build Coastguard Worker
145*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
146*6777b538SAndroid Build Coastguard Worker BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX)
147*6777b538SAndroid Build Coastguard Worker
148*6777b538SAndroid Build Coastguard Worker // We can look in /proc/self/status for TracerPid. We are likely used in crash
149*6777b538SAndroid Build Coastguard Worker // handling, so we are careful not to use the heap or have side effects.
150*6777b538SAndroid Build Coastguard Worker // Another option that is common is to try to ptrace yourself, but then we
151*6777b538SAndroid Build Coastguard Worker // can't detach without forking(), and that's not so great.
152*6777b538SAndroid Build Coastguard Worker // static
153*6777b538SAndroid Build Coastguard Worker Process GetDebuggerProcess() {
154*6777b538SAndroid Build Coastguard Worker // NOTE: This code MUST be async-signal safe (it's used by in-process
155*6777b538SAndroid Build Coastguard Worker // stack dumping signal handler). NO malloc or stdio is allowed here.
156*6777b538SAndroid Build Coastguard Worker
157*6777b538SAndroid Build Coastguard Worker int status_fd = open("/proc/self/status", O_RDONLY);
158*6777b538SAndroid Build Coastguard Worker if (status_fd == -1)
159*6777b538SAndroid Build Coastguard Worker return Process();
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker // We assume our line will be in the first 1024 characters and that we can
162*6777b538SAndroid Build Coastguard Worker // read this much all at once. In practice this will generally be true.
163*6777b538SAndroid Build Coastguard Worker // This simplifies and speeds up things considerably.
164*6777b538SAndroid Build Coastguard Worker char buf[1024];
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard Worker ssize_t num_read = HANDLE_EINTR(read(status_fd, buf, sizeof(buf)));
167*6777b538SAndroid Build Coastguard Worker if (IGNORE_EINTR(close(status_fd)) < 0)
168*6777b538SAndroid Build Coastguard Worker return Process();
169*6777b538SAndroid Build Coastguard Worker
170*6777b538SAndroid Build Coastguard Worker if (num_read <= 0)
171*6777b538SAndroid Build Coastguard Worker return Process();
172*6777b538SAndroid Build Coastguard Worker
173*6777b538SAndroid Build Coastguard Worker std::string_view status(buf, static_cast<size_t>(num_read));
174*6777b538SAndroid Build Coastguard Worker std::string_view tracer("TracerPid:\t");
175*6777b538SAndroid Build Coastguard Worker
176*6777b538SAndroid Build Coastguard Worker StringPiece::size_type pid_index = status.find(tracer);
177*6777b538SAndroid Build Coastguard Worker if (pid_index == StringPiece::npos)
178*6777b538SAndroid Build Coastguard Worker return Process();
179*6777b538SAndroid Build Coastguard Worker pid_index += tracer.size();
180*6777b538SAndroid Build Coastguard Worker StringPiece::size_type pid_end_index = status.find('\n', pid_index);
181*6777b538SAndroid Build Coastguard Worker if (pid_end_index == StringPiece::npos)
182*6777b538SAndroid Build Coastguard Worker return Process();
183*6777b538SAndroid Build Coastguard Worker
184*6777b538SAndroid Build Coastguard Worker std::string_view pid_str(buf + pid_index, pid_end_index - pid_index);
185*6777b538SAndroid Build Coastguard Worker int pid = 0;
186*6777b538SAndroid Build Coastguard Worker if (!StringToInt(pid_str, &pid))
187*6777b538SAndroid Build Coastguard Worker return Process();
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Worker return Process(pid);
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker
192*6777b538SAndroid Build Coastguard Worker bool BeingDebugged() {
193*6777b538SAndroid Build Coastguard Worker return GetDebuggerProcess().IsValid();
194*6777b538SAndroid Build Coastguard Worker }
195*6777b538SAndroid Build Coastguard Worker
196*6777b538SAndroid Build Coastguard Worker void VerifyDebugger() {
197*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_GDBINIT_WARNING)
198*6777b538SAndroid Build Coastguard Worker // Quick check before potentially slower GetDebuggerProcess().
199*6777b538SAndroid Build Coastguard Worker if (Environment::Create()->HasVar("CHROMIUM_GDBINIT_SOURCED"))
200*6777b538SAndroid Build Coastguard Worker return;
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard Worker Process proc = GetDebuggerProcess();
203*6777b538SAndroid Build Coastguard Worker if (!proc.IsValid())
204*6777b538SAndroid Build Coastguard Worker return;
205*6777b538SAndroid Build Coastguard Worker
206*6777b538SAndroid Build Coastguard Worker FilePath cmdline_file =
207*6777b538SAndroid Build Coastguard Worker FilePath("/proc").Append(NumberToString(proc.Handle())).Append("cmdline");
208*6777b538SAndroid Build Coastguard Worker std::string cmdline;
209*6777b538SAndroid Build Coastguard Worker if (!ReadFileToString(cmdline_file, &cmdline))
210*6777b538SAndroid Build Coastguard Worker return;
211*6777b538SAndroid Build Coastguard Worker
212*6777b538SAndroid Build Coastguard Worker // /proc/*/cmdline separates arguments with null bytes, but we only care about
213*6777b538SAndroid Build Coastguard Worker // the executable name, so interpret |cmdline| as a null-terminated C string
214*6777b538SAndroid Build Coastguard Worker // to extract the exe portion.
215*6777b538SAndroid Build Coastguard Worker std::string_view exe(cmdline.c_str());
216*6777b538SAndroid Build Coastguard Worker
217*6777b538SAndroid Build Coastguard Worker DCHECK(ToLowerASCII(exe).find("gdb") == std::string::npos)
218*6777b538SAndroid Build Coastguard Worker << "Detected gdb without sourcing //tools/gdb/gdbinit. gdb may not be "
219*6777b538SAndroid Build Coastguard Worker "able to find debug symbols, and pretty-printing of STL types may not "
220*6777b538SAndroid Build Coastguard Worker "work. Please see debug instructions for using //tools/gdb/gdbinit:\n"
221*6777b538SAndroid Build Coastguard Worker "https://chromium.googlesource.com/chromium/src/+/main/docs/"
222*6777b538SAndroid Build Coastguard Worker "gdbinit.md\n"
223*6777b538SAndroid Build Coastguard Worker "To continue anyway, type 'continue' in gdb. To always skip this "
224*6777b538SAndroid Build Coastguard Worker "check, define an environment variable CHROMIUM_GDBINIT_SOURCED=1";
225*6777b538SAndroid Build Coastguard Worker #endif
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard Worker #else
229*6777b538SAndroid Build Coastguard Worker
230*6777b538SAndroid Build Coastguard Worker bool BeingDebugged() {
231*6777b538SAndroid Build Coastguard Worker NOTIMPLEMENTED();
232*6777b538SAndroid Build Coastguard Worker return false;
233*6777b538SAndroid Build Coastguard Worker }
234*6777b538SAndroid Build Coastguard Worker
235*6777b538SAndroid Build Coastguard Worker void VerifyDebugger() {}
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker #endif
238*6777b538SAndroid Build Coastguard Worker
239*6777b538SAndroid Build Coastguard Worker // We want to break into the debugger in Debug mode, and cause a crash dump in
240*6777b538SAndroid Build Coastguard Worker // Release mode. Breakpad behaves as follows:
241*6777b538SAndroid Build Coastguard Worker //
242*6777b538SAndroid Build Coastguard Worker // +-------+-----------------+-----------------+
243*6777b538SAndroid Build Coastguard Worker // | OS | Dump on SIGTRAP | Dump on SIGABRT |
244*6777b538SAndroid Build Coastguard Worker // +-------+-----------------+-----------------+
245*6777b538SAndroid Build Coastguard Worker // | Linux | N | Y |
246*6777b538SAndroid Build Coastguard Worker // | Mac | Y | N |
247*6777b538SAndroid Build Coastguard Worker // +-------+-----------------+-----------------+
248*6777b538SAndroid Build Coastguard Worker //
249*6777b538SAndroid Build Coastguard Worker // Thus we do the following:
250*6777b538SAndroid Build Coastguard Worker // Linux: Debug mode if a debugger is attached, send SIGTRAP; otherwise send
251*6777b538SAndroid Build Coastguard Worker // SIGABRT
252*6777b538SAndroid Build Coastguard Worker // Mac: Always send SIGTRAP.
253*6777b538SAndroid Build Coastguard Worker
254*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_ARMEL)
255*6777b538SAndroid Build Coastguard Worker #define DEBUG_BREAK_ASM() asm("bkpt 0")
256*6777b538SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_ARM64)
257*6777b538SAndroid Build Coastguard Worker #define DEBUG_BREAK_ASM() asm("brk 0")
258*6777b538SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_MIPS_FAMILY)
259*6777b538SAndroid Build Coastguard Worker #define DEBUG_BREAK_ASM() asm("break 2")
260*6777b538SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_X86_FAMILY)
261*6777b538SAndroid Build Coastguard Worker #define DEBUG_BREAK_ASM() asm("int3")
262*6777b538SAndroid Build Coastguard Worker #endif
263*6777b538SAndroid Build Coastguard Worker
264*6777b538SAndroid Build Coastguard Worker #if defined(NDEBUG) && !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_ANDROID)
265*6777b538SAndroid Build Coastguard Worker #define DEBUG_BREAK() abort()
266*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_NACL)
267*6777b538SAndroid Build Coastguard Worker // The NaCl verifier doesn't let use use int3. For now, we call abort(). We
268*6777b538SAndroid Build Coastguard Worker // should ask for advice from some NaCl experts about the optimum thing here.
269*6777b538SAndroid Build Coastguard Worker // http://code.google.com/p/nativeclient/issues/detail?id=645
270*6777b538SAndroid Build Coastguard Worker #define DEBUG_BREAK() abort()
271*6777b538SAndroid Build Coastguard Worker #elif !BUILDFLAG(IS_APPLE)
272*6777b538SAndroid Build Coastguard Worker // Though Android has a "helpful" process called debuggerd to catch native
273*6777b538SAndroid Build Coastguard Worker // signals on the general assumption that they are fatal errors. If no debugger
274*6777b538SAndroid Build Coastguard Worker // is attached, we call abort since Breakpad needs SIGABRT to create a dump.
275*6777b538SAndroid Build Coastguard Worker // When debugger is attached, for ARM platform the bkpt instruction appears
276*6777b538SAndroid Build Coastguard Worker // to cause SIGBUS which is trapped by debuggerd, and we've had great
277*6777b538SAndroid Build Coastguard Worker // difficulty continuing in a debugger once we stop from SIG triggered by native
278*6777b538SAndroid Build Coastguard Worker // code, use GDB to set |go| to 1 to resume execution; for X86 platform, use
279*6777b538SAndroid Build Coastguard Worker // "int3" to setup breakpiont and raise SIGTRAP.
280*6777b538SAndroid Build Coastguard Worker //
281*6777b538SAndroid Build Coastguard Worker // On other POSIX architectures, except Mac OS X, we use the same logic to
282*6777b538SAndroid Build Coastguard Worker // ensure that breakpad creates a dump on crashes while it is still possible to
283*6777b538SAndroid Build Coastguard Worker // use a debugger.
284*6777b538SAndroid Build Coastguard Worker namespace {
DebugBreak()285*6777b538SAndroid Build Coastguard Worker void DebugBreak() {
286*6777b538SAndroid Build Coastguard Worker if (!BeingDebugged()) {
287*6777b538SAndroid Build Coastguard Worker abort();
288*6777b538SAndroid Build Coastguard Worker } else {
289*6777b538SAndroid Build Coastguard Worker #if defined(DEBUG_BREAK_ASM)
290*6777b538SAndroid Build Coastguard Worker DEBUG_BREAK_ASM();
291*6777b538SAndroid Build Coastguard Worker #else
292*6777b538SAndroid Build Coastguard Worker volatile int go = 0;
293*6777b538SAndroid Build Coastguard Worker while (!go)
294*6777b538SAndroid Build Coastguard Worker PlatformThread::Sleep(Milliseconds(100));
295*6777b538SAndroid Build Coastguard Worker #endif
296*6777b538SAndroid Build Coastguard Worker }
297*6777b538SAndroid Build Coastguard Worker }
298*6777b538SAndroid Build Coastguard Worker } // namespace
299*6777b538SAndroid Build Coastguard Worker #define DEBUG_BREAK() DebugBreak()
300*6777b538SAndroid Build Coastguard Worker #elif defined(DEBUG_BREAK_ASM)
301*6777b538SAndroid Build Coastguard Worker #define DEBUG_BREAK() DEBUG_BREAK_ASM()
302*6777b538SAndroid Build Coastguard Worker #else
303*6777b538SAndroid Build Coastguard Worker #error "Don't know how to debug break on this architecture/OS"
304*6777b538SAndroid Build Coastguard Worker #endif
305*6777b538SAndroid Build Coastguard Worker
BreakDebuggerAsyncSafe()306*6777b538SAndroid Build Coastguard Worker void BreakDebuggerAsyncSafe() {
307*6777b538SAndroid Build Coastguard Worker // NOTE: This code MUST be async-signal safe (it's used by in-process
308*6777b538SAndroid Build Coastguard Worker // stack dumping signal handler). NO malloc or stdio is allowed here.
309*6777b538SAndroid Build Coastguard Worker
310*6777b538SAndroid Build Coastguard Worker // Linker's ICF feature may merge this function with other functions with the
311*6777b538SAndroid Build Coastguard Worker // same definition (e.g. any function whose sole job is to call abort()) and
312*6777b538SAndroid Build Coastguard Worker // it may confuse the crash report processing system. http://crbug.com/508489
313*6777b538SAndroid Build Coastguard Worker static int static_variable_to_make_this_function_unique = 0;
314*6777b538SAndroid Build Coastguard Worker Alias(&static_variable_to_make_this_function_unique);
315*6777b538SAndroid Build Coastguard Worker
316*6777b538SAndroid Build Coastguard Worker DEBUG_BREAK();
317*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID) && !defined(OFFICIAL_BUILD)
318*6777b538SAndroid Build Coastguard Worker // For Android development we always build release (debug builds are
319*6777b538SAndroid Build Coastguard Worker // unmanageably large), so the unofficial build is used for debugging. It is
320*6777b538SAndroid Build Coastguard Worker // helpful to be able to insert BreakDebugger() statements in the source,
321*6777b538SAndroid Build Coastguard Worker // attach the debugger, inspect the state of the program and then resume it by
322*6777b538SAndroid Build Coastguard Worker // setting the 'go' variable above.
323*6777b538SAndroid Build Coastguard Worker #elif defined(NDEBUG)
324*6777b538SAndroid Build Coastguard Worker // Terminate the program after signaling the debug break.
325*6777b538SAndroid Build Coastguard Worker // When DEBUG_BREAK() expands to abort(), this is unreachable code. Rather
326*6777b538SAndroid Build Coastguard Worker // than carefully tracking in which cases DEBUG_BREAK()s is noreturn, just
327*6777b538SAndroid Build Coastguard Worker // disable the unreachable code warning here.
328*6777b538SAndroid Build Coastguard Worker #pragma GCC diagnostic push
329*6777b538SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wunreachable-code"
330*6777b538SAndroid Build Coastguard Worker _exit(1);
331*6777b538SAndroid Build Coastguard Worker #pragma GCC diagnostic pop
332*6777b538SAndroid Build Coastguard Worker #endif
333*6777b538SAndroid Build Coastguard Worker }
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Worker } // namespace debug
336*6777b538SAndroid Build Coastguard Worker } // namespace base
337