Figuring Out Memory Leaks without Clang - iphone

I'm trying to see if I can find some leaks myself in Apple's TopSongs app. Can someone help me out in at least one and how to identify what is in the Leaks reports and how I can get an idea on finding them?
ie: I got one like this:
# Category Event Type Timestamp Address Size Responsible Library Responsible Caller
0 GeneralBlock-448 Malloc 00:02.185 0x3f41220 448 libxml2.2.dylib xmlNewParserCtxt
From what I can tell, the method xmlNewParserCtxt is the problem, and it's not releasing an object, hence Malloc. The responsible library tells me it's the libxml2.2.dylib library with the problem, which I can't edit.
Am I heading in the right direction? If so, half the leaks are in that library and well, i can't edit that.
'
UPDATE:
Check out the answer to this question.

Perhaps a xmlNewParserCtxt was created (malloc'd)
xmlParserCtxt* context;
context = xmlNewParserCtxt();
and then not freed?
xmlFreeParserCtxt(context);

Finally got Snow Leopard and Xcode 3.2 installed with the built-in Clang. Anyways, it seems like Apple's code has it's own leaks inside their libraries. I decided not to use Apple's TopSongs code.

Related

Three20 app store rejection (UITouch) - removed offending code, Release build but exists in binary

I know that there are a lot of posts in about Three20 app store rejections due to private UITouch variables and I've read them all but I still haven't been able to solve the problem:
The non-public APIs that are included in your application are the
following undocumented private UITouch instance variables:
UITouch._locationInWindow
UITouch._phase
UITouch._previousLocationInWindow
UITouch._tapCount
UITouch._timestamp
UITouch._touchFlags
UITouch._view
UITouch._window
Steps I've taken:
1. Removed offending code from Three20UI.xcodeproj
2. Release build
However, when I do a simple grep _phase libThree20UI.a (the resulting binary) I still get the result "libThree20UI.a matches". Any suggestions would be greatly appreciated.
There is a rather long thread about this over here. That seems to be from nearly 2 years ago. Has Three20 not been updated in the interim to remove the offending symbol use?
Make sure you build totally from clean; nuke your objects, if you need.
As far as I know, this rejection is caused by either uploading a Debug version of your app or by having a variable called DEBUG in your code. If you are using the latest version of three20 all the private calls have been removed for quite some time now

EXC_BAD_ACCESS when sending messages to blocks on 4.0 -> 3.2

I've been using http://code.google.com/p/plblocks/ for a while now to get blocks support in our 3.2 iPad app. It was recently pointed out to me that you can set xcode to use the 4.0 SDK, then set the OS Deployment target to 3.2.
If I do, the following code works.
void (^world)() = ^ {
NSLog(#"Hello World");
};
NSLog(#"Hello?");
world();
However, any time I sent a message to a block I get an EXC_BAD_ACCESS. For example, if I add the following line:
void (^acopy)() = [world copy];
This is a problem, since you have to copy blocks in order for them to keep their scope around later. Any idea why blocks would work, but the messages wouldn't? Am I missing some setting or something? Am I mistaken about the need to copy?
It seems you can still use Block_copy(). I don't know why PLBlocks would be able to use the Objective-C and the built-in compilers can't.
Here's an intro article:
http://developer.apple.com/mac/articles/cocoa/introblocksgcd.html
It says:
Importantly, block objects are laid
out in such a way that they are also
Objective-C objects if that runtime is
present.
I can't really see how you could be developing an iPad app without the Objective-C runtime present. As a sanity check you could make sure the C version (Block_copy()) works.

What causes “EXC_BAD_ACCESS” error when getting wifi information?

I'm getting the following error
Program received signal: “EXC_BAD_ACCESS”.
warning: check_safe_call: could not restore current frame
warning: Unable to restore previously selected frame.
warning: Unable to restore previously selected frame.
My app is to get wifi information
libHandle = dlopen("/System/Library/PrivateFrameworks/ MobileWiFi.framework/MobileWiFi",RTLD_LAZY);
open = dlsym(libHandle, "Apple80211Open");
bind = dlsym(libHandle, "Apple80211BindToInterface");
close = dlsym(libHandle, "Apple80211Close");
scan = dlsym(libHandle, "Apple80211Scan");
open(&airportHandle);
bind(airportHandle, #"en0");
When the code reaches open(&airportHandle), I receive the error but I'm not sure because at this line it stops.
How can I resolve this?
For any EXC_BAD_ACCESS errors, you are usually trying to send a message to a released object. The BEST way to track these down is use NSZombieEnabled.
This works by never actually releasing an object, but by wrapping it up as a "zombie" and setting a flag inside it that says it normally would have been released. This way, if you try to access it again, it still know what it was before you made the error, and with this little bit of information, you can usually backtrack to see what the issue was.
It especially helps in background threads when the Debugger sometimes craps out on any useful information.
VERY IMPORTANT TO NOTE however, is that you need to 100% make sure this is only in your debug code and not your distribution code. Because nothing is ever released, your app will leak and leak and leak. To remind me to do this, I put this log in my appdelegate:
if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
NSLog(#"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");
If you need help finding the exact line, Do a Build-and-Debug (CMD-Y) instead of a Build-and-Run (CMD-R). When the app crashes, the debugger will show you exactly which line and in combination with NSZombieEnabled, you should be able to find out exactly why.
EXC_BAD_ACCESS always occurs when accessing memory you already have released. In your sample code, I can't see where airportHandle is initialized, or wheter it is initialized at all for that matter.
If it has been initialized but you just forgot to post that code, you should try checking if you released the handle somewhere.
To debug such an access violation, it is often useful to set the NSZombieEnabled Environment flag to YES. This will cause the Obj-C runtime to log access to released memory to the console. You can find a full tutorial on how to use that information together with Instruments to find your problem.
You can do it EASILY with Instruments: See this really great post:
http://www.corbinstreehouse.com/blog/2007/10/instruments-on-leopard-how-to-debug-those-random-crashes-in-your-cocoa-app/comment-page-1/#comment-43762
EXC_BAD_ACCESS. is mainly found when u released any object which you have further needed in future.it is unable to find but there is solution to find out u must have to be in a DEBUG mode . then follow these links
http://www.codza.com/how-to-debug-exc_bad_access-on-iphone
it really works
I'm working on the same thing, and I get the same issue. If you enter in debug mode, you can see that when we use open = dlsym(libHandle, "Apple80211Open"); the function still equals to 0.
So in my opinion you are looking for the Apple80211Open in a framework which did not contain this function.
Apple80211Open is in the Apple80211 private framework which is outdated in >iOS 2.x SDK. The equivalent in the MobileWifi framework, which is for the 3.x and 4.x SDK, is /System/Library/SystemConfiguration/WiFiManager.bundle/WiFiManager instead of /System/Library/PrivateFrameworks/MobileWiFi.framework/MobileWiFi

Three20's UIKit extensions don't seem to be being "included" properly

So, we have a project using the Three20 Library from Facebook (http://github.com/facebook/three20), and we're trying to compile against the latest version (HEAD from Github).
Previously it's worked fine, but something has now changed :)
The error I'm getting is an unrecognized selector on TTTableViewController:
[TTViewControllerSubClass popupViewController]: unrecognized selector sent to instance
(There's another question about this here)
I checked TTViewController, and it turns out we don't actually need to call popupSubView, so I commented that out. I then get this error:
-[UIImageView removeAllSubviews]: unrecognized selector sent to instance
So, I checked the locations of both these methods in Three20, and they are in UIViewControllerAdditions.m and UIViewAdditions.m, respectively. So this makes me think that Three20 is adding some methods to the basic UIKit classes, and these methods aren't actually getting included the way they should be.
Problem is, I get stuck there :) I've got no clue how to make UIKit include these classes, or "fix" Three20 (if it is indeed a Three20 problem) to make it work.
So I'm hoping some kind soul here will slog through my incredibly long problem description and point me in the right direction!
Thanks in advance :)
Looks like upgrading Three20 and following the instructions at http://three20.info/setup/existing I managed to get this working!

Accessing & Using the MobileWiFi.framework

For a personal project of mine, I'm trying to retrieve iPhone WiFi signal strength. I'm fully aware that this in the land of undocumented goodness, so please refrain from the "No Appstore" answers. :)
Anywho, I've been reading up on previous WiFi Network Scanner Apps (WiFi Stumbler), but I'm afraid most (if not all) reflect outdated SDK documentation. Hopefully, this question will also provide some centralized / insightful material with the most recent iPhone SDK 3.1.2.
Here's my incomplete/not-working code:
.h
void *libHandle;
void *airportHandle;
int (*open)(void *);
int (*bind)(void *, NSString *);
int (*close)(void *);
int (*scan)(void *, NSArray **, void *);
.m
libHandle = dlopen("/System/Library/PrivateFrameworks/MobileWiFi.framework/MobileWiFi",RTLD_LAZY);
open = dlsym(libHandle, "Apple80211Open");
bind = dlsym(libHandle, "Apple80211BindToInterface");
close = dlsym(libHandle, "Apple80211Close");
scan = dlsym(libHandle, "Apple80211Scan");
open(&airportHandle);
bind(airportHandle, #"en0");
NSLog(#"Result %#",libHandle);
When executed on the device, it'll produce my ever-so-favorite...
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
I'm thinking the dynamic loading call, isn't loading anything. The directory: /System/Library/PrivateFrameworks/ only lists a Info.plist file with no binaries or aliases.
Probably doing something terribly wrong (wrong directory?)... appreciate any help!
Also, as a follow up. To extract the WiFi information, it might be done by:
GetInfoCopy = dlsym(libHandle, "Apple80211GetInfoCopy");
And my questions are 1) Has anybody had any luck with this? 2) How do you get a header dump like I would using with class-dump on Objective-C libraries (because MobileWifi is in C)?
For anybody who stumbles upon this question, here's my library to access 802.11 networks. Although Apple claims to deny any applications that use private frameworks, there are several closed-sourced WiFi applications on the AppStore. Use at your own risk.
This library works with iPhone SDK 3.1.2.
SOLStumbler.h
SOLStumbler.m
Use:
SOLStumbler *networksManager = [[SOLStumbler alloc] init];
[networksManager scanNetworks];
Result:
An networks NSDictionary of a info NSDictionary.
Use CFShow to explore the returned pointer containing information. Or call the description method for sample output.
Update as of July 2012 (iOS 5.0)
The code you're trying to use is pretty old. This stuff (e.g. WiFiManager or MobileWiFi) is in a private framework. That means Apple can, and often will, change it or move if from OS version to version.
I ran nm on the MobileWifi framework, and didn't see any of those function names. So, I think that's why your code fails.
$ pwd
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/PrivateFrameworks/MobileWiFi.framework
$ nm MobileWiFi | grep 80211
$
I suppose it might be necessary to run nm on the actual device framework, but I didn't waste my time, after looking at this:
Discussion of this framework, and follow-ons.
It looks like you can now find equivalent (?) functions in the IPConfiguration framework. Try this code:
libHandle = dlopen("/System/Library/SystemConfiguration/IPConfiguration.bundle/IPConfiguration", RTLD_LAZY);
I ran it on a jailbroken iOS 5.0.1 phone and it worked (loaded the dylib and found a few of the Apple80211 functions). From that thread I linked to, it looks like you may need to have this installed in /Applications on a jailbroken phone, in order to work fully. Or, possibly have to mess around with adding some entitlements to your sandboxed app.
These Apple80211xxx functions do not exist in MobileWiFi.framework (you can check using the `nm' tool against the SDK binaries).
(Also, it's impossible to dump a C header from binaries because all type information are removed during compilation. You need to reverse engineer it yourself or wait for someone to do so.)
I'm not sure if this would be a problem, but open/close/bind are names that are already in-use (standard C library).
The binary doesn't exist, as it is stored in the dyld shared_cache (dlopen will succeed because the library is technically 'loaded.'); however, I note that you're not checking that any of libHandle, open, close, bind or scan are valid when you retrieve them from the dl* functions.