1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #include "flutter/testing/debugger_detection.h" |
6 | |
7 | #include "flutter/fml/build_config.h" |
8 | #include "flutter/fml/logging.h" |
9 | |
10 | #if OS_MACOSX |
11 | |
12 | #include <assert.h> |
13 | #include <stdbool.h> |
14 | #include <sys/sysctl.h> |
15 | #include <sys/types.h> |
16 | #include <unistd.h> |
17 | |
18 | #endif // OS_MACOSX |
19 | |
20 | #if OS_WIN |
21 | |
22 | #include <windows.h> |
23 | |
24 | #endif // OS_WIN |
25 | |
26 | namespace flutter { |
27 | namespace testing { |
28 | |
29 | DebuggerStatus GetDebuggerStatus() { |
30 | #if OS_MACOSX |
31 | // From Technical Q&A QA1361 Detecting the Debugger |
32 | // https://developer.apple.com/library/archive/qa/qa1361/_index.html |
33 | int management_info_base[4]; |
34 | struct kinfo_proc info; |
35 | size_t size; |
36 | |
37 | // Initialize the flags so that, if sysctl fails for some bizarre |
38 | // reason, we get a predictable result. |
39 | info.kp_proc.p_flag = 0; |
40 | |
41 | // Initialize management_info_base, which tells sysctl the info we want, in |
42 | // this case we're looking for information about a specific process ID. |
43 | management_info_base[0] = CTL_KERN; |
44 | management_info_base[1] = KERN_PROC; |
45 | management_info_base[2] = KERN_PROC_PID; |
46 | management_info_base[3] = getpid(); |
47 | |
48 | // Call sysctl. |
49 | |
50 | size = sizeof(info); |
51 | auto status = |
52 | ::sysctl(management_info_base, |
53 | sizeof(management_info_base) / sizeof(*management_info_base), |
54 | &info, &size, NULL, 0); |
55 | FML_CHECK(status == 0); |
56 | |
57 | // We're being debugged if the P_TRACED flag is set. |
58 | return ((info.kp_proc.p_flag & P_TRACED) != 0) ? DebuggerStatus::kAttached |
59 | : DebuggerStatus::kDontKnow; |
60 | |
61 | #elif OS_WIN |
62 | return ::IsDebuggerPresent() ? DebuggerStatus::kAttached |
63 | : DebuggerStatus::kDontKnow; |
64 | |
65 | #else |
66 | return DebuggerStatus::kDontKnow; |
67 | #endif |
68 | } // namespace testing |
69 | |
70 | } // namespace testing |
71 | } // namespace flutter |
72 | |