blob: daea74636d20f9cd6e5214adaccabcda2a76bcc2 [file] [log] [blame] [edit]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/testing/debugger_detection.h"
#include "flutter/fml/build_config.h"
#include "flutter/fml/logging.h"
#if FML_OS_MACOSX
#include <assert.h>
#include <stdbool.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <unistd.h>
#endif // FML_OS_MACOSX
#if FML_OS_WIN
#include <windows.h>
#endif // FML_OS_WIN
namespace flutter {
namespace testing {
DebuggerStatus GetDebuggerStatus() {
#if FML_OS_MACOSX
// From Technical Q&A QA1361 Detecting the Debugger
// https://developer.apple.com/library/archive/qa/qa1361/_index.html
int management_info_base[4];
struct kinfo_proc info;
size_t size;
// Initialize the flags so that, if sysctl fails for some bizarre
// reason, we get a predictable result.
info.kp_proc.p_flag = 0;
// Initialize management_info_base, which tells sysctl the info we want, in
// this case we're looking for information about a specific process ID.
management_info_base[0] = CTL_KERN;
management_info_base[1] = KERN_PROC;
management_info_base[2] = KERN_PROC_PID;
management_info_base[3] = getpid();
// Call sysctl.
size = sizeof(info);
auto status =
::sysctl(management_info_base,
sizeof(management_info_base) / sizeof(*management_info_base),
&info, &size, NULL, 0);
FML_CHECK(status == 0);
// We're being debugged if the P_TRACED flag is set.
return ((info.kp_proc.p_flag & P_TRACED) != 0) ? DebuggerStatus::kAttached
: DebuggerStatus::kDontKnow;
#elif FML_OS_WIN
return ::IsDebuggerPresent() ? DebuggerStatus::kAttached
: DebuggerStatus::kDontKnow;
#else
return DebuggerStatus::kDontKnow;
#endif
} // namespace testing
} // namespace testing
} // namespace flutter