Checking if Reduced Motion is enabled on iOS 7

Posted: May 20th, 2014 | Author: | Filed under: Debugging, iOS, Programming | Tags: , , , | No Comments »

Apple introduced in iOS 7.0.3 a setting to reduce motion ( http://support.apple.com/kb/HT5595 ) :
Settings -> General -> Accessibility -> Reduce Motion


Reduced Motion Setting

Sadly there is no public API to know if the user enabled “Reduce motion”.
Here is how to get the value of this setting using a private API. Note that you should not use this code for applications submitted to the App Store.


#include <dlfcn.h>

+ (BOOL) reduceMotionEnabled
{
	BOOL (*_UIAccessibilityReduceMotionFunction)(void) = (BOOL (*)(void)) dlsym(RTLD_DEFAULT, "_UIAccessibilityReduceMotion");
	if(_UIAccessibilityReduceMotionFunction != NULL)
	{
		return _UIAccessibilityReduceMotionFunction();
	}
	else
	{
		NSLog(@"Unsupported: _UIAccessibilityReduceMotion does not exist on this iOS version");
		return NO;
	}
}

Edit: Apple added a public API on iOS 8:

// Returns whether the system preference for reduce motion is enabled
UIKIT_EXTERN BOOL UIAccessibilityIsReduceMotionEnabled() NS_AVAILABLE_IOS(8_0);


Breakpoint conditions with GDB

Posted: August 8th, 2008 | Author: | Filed under: Debugging | Tags: , , , | 2 Comments »

When debugging your application, you use breakpoints. The program will return control to GDB every time it reaches a breakpoint you set. This may not be desirable if you have breakpoint on a method that is called many times and you want to break only with certain values passed to that method. GDB provides several ways to do conditional breakpoints that I’ll try to explain.

 

1- The problem

Let take a really simple application which calls 10 times a function.

#import <Foundation/Foundation.h>

void myFunction()
{
   // Initialize the counter to 0
   static int sFunctionCounter = 0;

   // Each time we enter the function,
   // increment the counter
   sFunctionCounter++;

   NSLog(@"function called: %d", sFunctionCounter);
}

int main (int argc, const char * argv[])
{
   NSAutoreleasePool * pool =[[NSAutoreleasePool alloc] init];
   int i;

   // Call 10 times myFunction.
   for(i = 0 ; i < 10 ; i++)
        myFunction();

   [pool release];
   return 0;
}

Now imagine that you want to break in myFunction, but only the 4th time you enter that function. One easy solution would be to modify the function by adding a if statement and setting a breakpoint accordingly.

myFunction

This method works fine in that case but you need to modify your function, you need to rebuild, you can’t do it if you don’t have the sources…

2- Conditional breakpoints

GDB can let you add breakpoints to stop whenever a certain point in the program is reached. The problem is that if you set a breakpoint to the function myFunction, you will break 10 times and will need to continue until you get the right occurrence.
Hopefully you can specify a condition (boolean expression) on your breakpoint so that your program stops only if the condition is true.

Let’s take the sample of the previously detailed program.
We will use the Console in Xcode but you can use directly GDB in command line if you prefer.

Here is what to do:
– First we set a breakpoint at the entry of the main function of the program.
– Set a breakpoint to stop on myFunction: break myFunction.
– Finally tell the debugger to only break if sFunctionCounter is equal to 4: condition 9 sFunctionCounter == 4
The program will run and will stop at the 4th call of the function myFunction as you can see on this screenshot:

Console

3- Breakpoints commands

Conditional breakpoints are useful but not really flexible. GDB provides another solution: the breakpoint commands.
You can give any breakpoint a series of commands to execute when your program stops due to that breakpoint. For example, you can display the values of certain expressions or enable/disable some breakpoints.
We will take another simple example. Our new program call 10 times 2 methods with detachNewThreadSelector. The calls to method1: and method2: are asynchronous so that we can’t tell if method1: will be executed before method2:.

#import <Foundation/Foundation.h>

@interface Test : NSObject
{
}

-(void)method1:(id)sender;
-(void)method2:(id)sender;

@end

@implementation Test

-(void)method1:(id)sender
{
   // Do something
}

-(void)method2:(id)sender
{
   // Do something
}

@end

int main (int argc, const char * argv[])
{
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   int i;
   Test *myTest = [[Test alloc] init];

   // Call 10 times the methods method1: and method2:.
   // The calls are asynchronous so that we can't tell if method1:
   // will be executed before method2:.
   
   for(i = 0 ; i < 10 ; i++)
   {
      NSLog(@"iteration: %d", i);

      // Call method1: asynchronously
      [NSThread detachNewThreadSelector:@selector(method1:) toTarget:myTest withObject:nil];
   
      // Call method2: asynchronously
      [NSThread detachNewThreadSelector:@selector(method2:) toTarget:myTest withObject:nil];

      // Wait before continuing to loop
      [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
   }

   [myTest release];

   [pool release];
   return 0;
}

What we would like to do, is to break in method2: only if method2: is called before method1:.
This is not trivial to do with conditional breakpoints, and not easy to do by modifying the source code.

Let’s talk bout the powerful breakpoint commands, which can solve this. You will need to write a little txt file. This file contains the commands to execute after a breakpoint is reached.


# Define two integers which will be incremented
# each time you enter the corresponding method.
set $method1_Counter = 0
set $method2_Counter = 0

# We create a breakpoint using "future break"
# If we break due to this breakpoint, the command
#following will be executed.
fb method1:
command
   set $method1_Counter = $method1_Counter + 1
   printf "method1 calledn"
   continue
end

# We create the second breakpoint and
# the coressponding command.
fb method2:
command
   set $method2_Counter = $method2_Counter + 1
   printf "method2 calledn"

   if($method1_Counter < $method2_Counter)
      printf "method2 was called before method1!n"
   else
      continue
   end
end

As you can see, this little txt file is really simple. We define 2 breakpoints, one in method1: and one in method2:. For each breakpoint defined, we define a command (kind of a small program) which will be executed.

The command related to the breakpoint method1: prints “method1 called” and we tell the debugger to continue the execution of the program.
The command related to the breakpoint method2: prints “method2 called” and we only tell GDB to continue the program if method1_Counter < method2_Counter (the number of calls to method2: is greater than the number of calls to method1:). If method1: was called before method2:, we continue the execution of the program.

Now that we have our txt file, we can start our application, load the txt file using the source command and see that indeed we only break if method2: is called before method1:

Console


libMallocDebug

Posted: July 19th, 2008 | Author: | Filed under: Debugging | Tags: , , , | No Comments »

Here is a little description on how to use libMallocDebug for developers and QA people. It seems not many people know about it.
libMallocDebug is really useful in the case you have a crash sometimes when doing something but it is hard to reproduce.

What is libMallocDebug?

libMallocDebug is a debugging malloc library that can track down memory related bugs and can be turned on and off at runtime. If you use this library, it will replace the malloc functions with a debug version of these functions. It contains several interesting options but only 3 are really useful.

MallocGuardEdges: This option adds guard pages to detect buffer overflows. Buffer overflows are not easy to find because it might crash randomly depending on what you write and where.

MallocScribble: This option detects writes to a freed block by setting its contents to 0x55 when deallocated. This can detect bugs like double frees, or using freed memory. Dereferencing a pointer in cleared freed memory will cause the program to reference the memory at 0x55555555, which usually is unallocated and will cause an immediate crash if the pointer is dereferenced for reading or writing.

MallocPreScribble: This option detects reads of uninitialized memory (also known as uninitialized variables) by setting its contents to 0xAA when allocated. Reading an uninitialized pointer from that memory will cause the program to reference the memory at 0xAAAAAAAA, which is usually unallocated and will cause an immediate crash if the pointer is dereferenced for reading or writing.
Using libMallocDebug (without sources) for beta testers:

You can run any application with the libMallocDebug library. To do that, open a terminal window (bash) and type:

export DYLD_INSERT_LIBRARIES=/usr/lib/libMallocDebug.A.dylib
export MallocGuardEdges=YES
export MallocScribble=YES
export MallocPreScribble=YES
/Applications/MyAppDBG.app/Contents/MacOS/MyAppDBG

This will run MyApp using libMallocDebug. You will see in the Terminal window some printf made by libMallocDebug. To see if libMallocDebug is used, the first line should be:
“libMallocDebug[MyAppDBG-10714]: initializing libMallocDebug on thread 10b”. Here is an example:

Alex:~ leopard$ export DYLD_INSERT_LIBRARIES=/usr/lib/libMallocDebug.A.dylib
Alex:~ leopard$ export MallocGuardEdges=YES
Alex:~ leopard$ export MallocScribble=YES
Alex:~ leopard$ export MallocPreScribble=YES
Alex:~ leopard$ /Applications/MyAppDBG.app/Contents/MacOS/MyAppDBG 
libMallocDebug[MyAppDBG-4388]: initializing libMallocDebug on thread 10b
task_set_exception_ports (os/kern) invalid argument
libMallocDebug[MyAppDBG-4388]: target application recently wrote to freed malloc’d memory at: 0x32b03c0, suggesting it didn’t realize the memory had been freed

Using libMallocDebug (with sources) for developers:

Select the Executable in the Project and add the 4 environment variables as shown on the following picture:

Setting environment variables in Xcode.

This will help to reproduce crashes. You can also use gdb and libMallocDebug at the same time.

Limitations and issues:

  • This tool helps to find memory bugs but it might not find all of them. 
  • It checks memory at runtime and thus only detects bugs in the features you try.
  • This library affects performances. So don’t use it while doing performance comparisons.
  • For developers: don’t forget to uncheck the environment variables in the Executable once you are done.
  • For developers: You can use gdb and libmallocDebug at the same time to reproduce and debug issues. But there is a bug on Leopard with Intel machines (rdar://5611207). You can’t use gdb in Xcode and libMallocDebug at the same time. There are several workarounds: Boot on Tiger with your intel machine, use a PowerPC machine with Leopard, or use gdb from the command line on Leopard with an intel machine.

[Update]: Thomas Clement pointed out several things.

  • MallocGuardEdges, MallocScribble and MallocPreScribble are available in the default memory allocator as mentioned in Mac OS X Debugging Magic Tech Note. That means you can use them without having to use LibMallocDebug. Of course when you use LibMallocDebug I recommend you to always enable these environment variables to detect more possible issues.
  • The application MallocDebug (available in the CHUD tools) uses LibMallocDebug. If you don’t like to set environment variables, you can use that application which is really nice.
  • There is another allocation debugging library called libgmalloc which seems to be more aggressive than LibMallocDebug. This library can be enabled through Xcode with the menu item “Enable Guard Malloc” in the menu “Run”. You can get more information about this library in the man page (man libgmalloc).