[upstream_utils] Add std::is_debugger_present() shim (#7423)

This commit is contained in:
Tyler Veness
2024-11-22 09:17:23 -08:00
committed by GitHub
parent 1d58c5025e
commit b7eb9fb8f9
16 changed files with 425 additions and 3 deletions

View File

@@ -0,0 +1,29 @@
#ifndef IXM_BREAKPOINT_HPP
#define IXM_BREAKPOINT_HPP
#include <debugging/detail/psnip_debug_trap.h>
namespace wpi {
bool is_debugger_present() noexcept;
#if defined(__GNUC__) && !defined(__clang__)
[[gnu::flatten]]
#endif
inline void breakpoint() noexcept
{
psnip_trap();
}
#if defined(__GNUC__) && !defined(__clang__)
[[gnu::flatten]]
#endif
inline void breakpoint_if_debugging() noexcept
{
if (is_debugger_present()) breakpoint();
}
} // namespace wpi
#endif

View File

@@ -0,0 +1,83 @@
/* Debugging assertions and traps
* Portable Snippets - https://github.com/nemequ/portable-snippets
* Created by Evan Nemerson <evan@nemerson.com>
*
* To the extent possible under law, the authors have waived all
* copyright and related or neighboring rights to this code. For
* details, see the Creative Commons Zero 1.0 Universal license at
* https://creativecommons.org/publicdomain/zero/1.0/
*/
#if !defined(PSNIP_DEBUG_TRAP_H)
#define PSNIP_DEBUG_TRAP_H
#if !defined(PSNIP_NDEBUG) && defined(NDEBUG) && !defined(PSNIP_DEBUG)
# define PSNIP_NDEBUG 1
#endif
#if defined(__has_builtin) && !defined(__ibmxl__)
# if __has_builtin(__builtin_debugtrap)
# define psnip_trap() __builtin_debugtrap()
# elif __has_builtin(__debugbreak)
# define psnip_trap() __debugbreak()
# endif
#endif
#if !defined(psnip_trap)
# if defined(_MSC_VER) || defined(__INTEL_COMPILER)
# define psnip_trap() __debugbreak()
# elif defined(__ARMCC_VERSION)
# define psnip_trap() __breakpoint(42)
# elif defined(__ibmxl__) || defined(__xlC__)
# include <builtins.h>
# define psnip_trap() __trap(42)
# elif defined(__DMC__) && defined(_M_IX86)
static inline void psnip_trap(void) { __asm int 3h; }
# elif defined(__i386__) || defined(__x86_64__)
static inline void psnip_trap(void) { __asm__ __volatile__("int3"); }
# elif defined(__thumb__)
static inline void psnip_trap(void) { __asm__ __volatile__(".inst 0xde01"); }
# elif defined(__aarch64__)
static inline void psnip_trap(void) { __asm__ __volatile__(".inst 0xd4200000"); }
# elif defined(__arm__)
static inline void psnip_trap(void) { __asm__ __volatile__(".inst 0xe7f001f0"); }
# elif defined (__alpha__) && !defined(__osf__)
static inline void psnip_trap(void) { __asm__ __volatile__("bpt"); }
# elif defined(_54_)
static inline void psnip_trap(void) { __asm__ __volatile__("ESTOP"); }
# elif defined(_55_)
static inline void psnip_trap(void) { __asm__ __volatile__(";\n .if (.MNEMONIC)\n ESTOP_1\n .else\n ESTOP_1()\n .endif\n NOP"); }
# elif defined(_64P_)
static inline void psnip_trap(void) { __asm__ __volatile__("SWBP 0"); }
# elif defined(_6x_)
static inline void psnip_trap(void) { __asm__ __volatile__("NOP\n .word 0x10000000"); }
# elif defined(__STDC_HOSTED__) && (__STDC_HOSTED__ == 0) && defined(__GNUC__)
# define psnip_trap() __builtin_trap()
# else
# include <signal.h>
# if defined(SIGTRAP)
# define psnip_trap() raise(SIGTRAP)
# else
# define psnip_trap() raise(SIGABRT)
# endif
# endif
#endif
#if defined(HEDLEY_LIKELY)
# define PSNIP_DBG_LIKELY(expr) HEDLEY_LIKELY(expr)
#elif defined(__GNUC__) && (__GNUC__ >= 3)
# define PSNIP_DBG_LIKELY(expr) __builtin_expect(!!(expr), 1)
#else
# define PSNIP_DBG_LIKELY(expr) (!!(expr))
#endif
#if !defined(PSNIP_NDEBUG) || (PSNIP_NDEBUG == 0)
# define psnip_dbg_assert(expr) do { \
if (!PSNIP_DBG_LIKELY(expr)) { \
psnip_trap(); \
} \
} while (0)
#else
# define psnip_dbg_assert(expr)
#endif
#endif /* !defined(PSNIP_DEBUG_TRAP_H) */

View File

@@ -0,0 +1,25 @@
#if defined(linux) || defined(__linux) || defined(__linux__) \
|| defined(__gnu_linux__)
# include <debugging.hpp>
# include <atomic>
# include <fstream>
# include <string>
namespace wpi {
bool is_debugger_present() noexcept
{
std::ifstream proc_self_status_f("/proc/self/status");
if (!proc_self_status_f) return false;
std::string buffer(256, '\0');
proc_self_status_f.read(&buffer[0], 256);
auto index = buffer.find("TracerPid:\t");
if (index == buffer.npos) return false;
return buffer[index + 11] != '0';
}
} // namespace wpi
#endif

View File

@@ -0,0 +1,36 @@
#if defined(__APPLE__) && defined(__MACH__)
# include <debugging.hpp>
# include <algorithm>
# include <array>
# include <mach/mach_init.h>
# include <mach/task.h>
template <class T>
auto exc = std::array<T, EXC_TYPES_COUNT> { {} };
namespace wpi {
bool is_debugger_present() noexcept
{
mach_msg_type_number_t count {};
auto masks = exc<exception_mask_t>;
auto ports = exc<mach_port_t>;
auto behaviors = exc<exception_behavior_t>;
auto flavors = exc<thread_state_flavor_t>;
exception_mask_t mask
= EXC_MASK_ALL & ~(EXC_MASK_RESOURCE | EXC_MASK_GUARD);
kern_return_t result = task_get_exception_ports(mach_task_self(), mask,
masks.data(), &count, ports.data(), behaviors.data(), flavors.data());
if (result != KERN_SUCCESS) return false;
auto valid = [](auto port) { return MACH_PORT_VALID(port); };
auto begin = std::begin(ports);
auto end = begin + count;
return end != std::find_if(begin, end, valid);
}
} // namespace wpi
#endif

View File

@@ -0,0 +1,18 @@
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) \
|| defined(__TOS_WIN__) || defined(__WINDOWS__)
# include <debugging.hpp>
# define WIN32_LEAN_AND_MEAN
# include <Windows.h>
namespace wpi {
bool is_debugger_present() noexcept
{
return ::IsDebuggerPresent();
}
} // namespace wpi
#endif