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
26namespace flutter {
27namespace testing {
28
29DebuggerStatus 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