Skip to content

Instantly share code, notes, and snippets.

@mkhl
Created June 9, 2010 11:00
Show Gist options
  • Save mkhl/431325 to your computer and use it in GitHub Desktop.
Save mkhl/431325 to your computer and use it in GitHub Desktop.
//
// DebuggingUtilities.h
// BreakingIntoGDB
//
// Created by Alexandre Colucci on 23/08/08.
// Source: http://blog.timac.org/?p=190
//
#import <Foundation/Foundation.h>
#import <ApplicationServices/ApplicationServices.h>
#include <assert.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
// From Technical Q&A QA1361
// Returns true if the current process
// is being debugged (either running
// under the debugger or has a debugger
// attached post facto).
static bool AmIBeingDebugged(void)
{
int junk;
int mib[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 mib, which tells sysctl the info
// we want, in this case we're looking for
// information about a specific process ID.
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = getpid();
// Call sysctl.
size = sizeof(info);
junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
assert(junk == 0);
// We're being debugged if the P_TRACED
// flag is set.
return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
}
static void BreakIntoGDB()
{
if(AmIBeingDebugged())
{
// GDB is already attached to the application.
// We simply break using the Debugger function.
Debugger();
}
else
{
// GDB is not running. We open a
// Terminal window and attach the
// current application.
ProcessSerialNumber psn = {0,kCurrentProcess};
pid_t thePID;
OSStatus err = GetProcessPID(&psn, &thePID);
if(err == noErr)
{
NSString *scriptSource =
[NSString stringWithFormat:@"tell application \"Terminal\" ndo script \"gdb attach \" & %d nend tell", thePID];
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:scriptSource];
if(appleScript != nil)
{
NSDictionary *errorDict;
// Don't check the returned value
[appleScript executeAndReturnError:&errorDict];
}
sleep(2);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment