diff --git a/Zend/zend_gdb.c b/Zend/zend_gdb.c index 0fff7420486ff..727a2bec227a8 100644 --- a/Zend/zend_gdb.c +++ b/Zend/zend_gdb.c @@ -22,6 +22,11 @@ #include #include +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#include +#include +#include +#endif #include #include @@ -105,6 +110,7 @@ ZEND_API void zend_gdb_unregister_all(void) ZEND_API int zend_gdb_present(void) { int ret = 0; +#if defined(__linux__) int fd = open("/proc/self/status", O_RDONLY); if (fd > 0) { @@ -136,6 +142,54 @@ ZEND_API int zend_gdb_present(void) close(fd); } +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#if defined(__APPLE__) +#define KINFO_MIB int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; +#define KINFO_PROC_FLAG (cproc->kp_proc.p_flag) +#define KINFO_PROC_PPID (cproc->kp_proc.p_oppid) +#define KINFO_PROC_COMM (pcproc->kp_proc.p_comm) +#elif defined(__FreeBSD__) +#define KINFO_MIB int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; +#define KINFO_PROC_FLAG (cproc->ki_flag) +#define KINFO_PROC_PPID (cproc->ki_ppid) +#define KINFO_PROC_COMM (pcproc->ki_comm) +#elif defined(__OpenBSD__) +#define P_TRACED PS_TRACED +#define KINFO_MIB int mib[6] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid(), sizeof(struct kinfo_proc), 1}; +#define KINFO_PROC_FLAG (cproc->p_psflags) +#define KINFO_PROC_PPID (cproc->p_ppid) +#define KINFO_PROC_COMM (pcproc->p_comm) +#elif defined(__NetBSD__) +#define kinfo_proc kinfo_proc2 +#define KINFO_MIB int mib[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_PID, getpid(), sizeof(struct kinfo_proc2), 1}; +#define KINFO_PROC_FLAG (cproc->p_flag) +#define KINFO_PROC_PPID (cproc->p_ppid) +#define KINFO_PROC_COMM (pcproc->p_comm) +#endif + struct kinfo_proc *cproc; + size_t cproclen = 0; + KINFO_MIB + const size_t miblen = sizeof(mib)/sizeof(mib[0]); + if (sysctl(mib, miblen, NULL, &cproclen, NULL, 0) != 0) { + return 0; + } + cproc = (struct kinfo_proc *)malloc(cproclen); + if (sysctl(mib, 4, cproc, &cproclen, NULL, 0) == 0) { + if ((KINFO_PROC_FLAG & P_TRACED) != 0) { + pid_t ppid = KINFO_PROC_PPID; + mib[3] = ppid; + struct kinfo_proc *pcproc = (struct kinfo_proc *)malloc(cproclen); + if (sysctl(mib, miblen, pcproc, &cproclen, NULL, 0) == 0) { + // Could be prefixed with package systems e.g. egdb + if (strstr(KINFO_PROC_COMM, "gdb")) { + ret = 1; + } + } + free(pcproc); + } + } + free(cproc); +#endif return ret; }