Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting if iOS app is run in debugger

I set up my application to either send debugging output to console or a log file. Now, I'd like to decide with in the code whether

  • it is run in the debugger (or simulator) and have thus a console window where I would like to read the output directly or if
  • there is no console window and thus, the output should be redirected to a file.

Is there a way to determine if the app runs in the debugger?

like image 623
Axel Avatar asked Jan 20 '11 08:01

Axel


People also ask

How do I run a debug app in iOS?

When your app is installed either on a device/simulator but not running. In the Xcode Menu, select Debug -> Attach to Process by PID or Name. In the popup, enter the PID or the application name. When debugger will attach when the app will run in the future.

Can I debug iOS app?

Can You Debug iOS Apps On An iPhone? You can debug iOS apps directly on an iPhone. You just need to connect the iPhone to your Mac with Xcode installed, and configure all of the permissions to run the app on a real device instead of on a simulator.

What is debug mode in iOS?

Debug mode enables you to see logs of various Tapjoy actions (sessions, placements, purchases, custom events, etc. ). These will appear in the Tapjoy Developer Console. This setting also enables logging to the Xcode console.

Is Xcode a debugger?

The Xcode debugger provides several methods to step through your code and inspect variables. You can precisely control execution of your code from a breakpoint, stepping into and out of called functions as necessary to determine where your bug occurs.


2 Answers

There's a function from Apple to detect whether a program is being debugged in the Technical Q&A 1361 (entry in Mac library and entry in iOS library; they are identical).

Code from the Technical Q&A:

#include <assert.h> #include <stdbool.h> #include <sys/types.h> #include <unistd.h> #include <sys/sysctl.h>  static bool AmIBeingDebugged(void)     // Returns true if the current process is being debugged (either      // running under the debugger or has a debugger attached post facto). {     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 ); } 

Also pay attention to this note at the end of the Q&A:

Important: Because the definition of the kinfo_proc structure (in <sys/sysctl.h>) is conditionalized by __APPLE_API_UNSTABLE, you should restrict use of the above code to the debug build of your program.

like image 108
DarkDust Avatar answered Sep 28 '22 04:09

DarkDust


It is possible to instruct the debugger to set environment variables when it launches a process it is about to debug. This can be done in Xcode by going to the menu item Product->Edit Scheme. Then under the Debug scheme's Arguments tab add a new environment variable. The variable should be named "debugger" with the value "true". Then the following code snippet can be used to determine if the debugger launched your process:

NSDictionary* env = [NSProcessInfo processInfo].environment;  if ([env[@"debugger"] isEqual:@"true"]) {     NSLog(@"debugger yes"); } else {     NSLog(@"debugger no"); } 
like image 30
Evan Avatar answered Sep 28 '22 04:09

Evan