Since iOS5 hit the streets I have begun I have been receiving many (so many) crash reports like:
...
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x0
Crashed Thread: 0
Thread 0 Crashed:
0 libsystem_c.dylib 0x35ec4b3c memset$VARIANT$CortexA8 + 116
1 FooApp 0x0005ba25 -[FooViewController prepareShapes] (FooViewController.m:808)
...
Relevant details:
XCode 4.2
LLVM 3.0
'armv6 armv7' architectures
iOS 5 base SDK
targeting iOS 4.0
crashes under iOS5 only (all iOS5 iPhone models. No iPad crashes but app isn't universal)
Can't reproduce the crash on any of my devices (of course)
Now [FooViewController prepareShapes] doesn't call memset directly, instead passes a struct (representing a shape) to a class method that attempts to realloc it. The fact that the stack trace skips over the class method is a bit weird but no doubt it's yet more compiler magic I don't understand. Within the class method, the block that invokes memset is as follows:
// class method invoked by [FooViewController prepareShapes]:808 (shape is coloured2DShape instance)
shape->maxVertexCount = maxVertexes;
if (shape->maxVertexBytes != 0)
{
free(shape->vertices);
}
shape->maxVertexBytes = sizeof(vertex_2D_4byteColour) * shape->maxVertexCount;
shape->vertices = (vertex_2D_4byteColour *)malloc(shape->maxVertexBytes);
memset(shape->vertices, 0, shape->maxVertexBytes);
And here's the struct being manipulated
// coloured2DShape struct
typedef struct coloured2DShape
{
vertex_2D_4byteColour* vertices;
GLushort* indices;
uint maxVertexBytes;
uint maxIndexBytes;
int vertexCount;
int indexCount;
int maxVertexCount;
int maxIndexCount;
} coloured2DShape;
I recognise that this isn't anywhere close to the recommended way to do OpenGL, however the thing that really bamboozles me (and I am well and truly bamboozled here) is that memset is only blowing up under iOS5 (I'm using QuincyKit to collect crash reports and HockeyApp to aggregate them). This exact code had been cruising along under iOS4 (compiled with GCC) for months.
I hope this isn't interpreted as a 'do my homework' thing. I have spent months researching, tweaking (I've released several updates addressing this issue) and hair-pulling with no progress. I'm all out of ideas.
I'd think that memset is working fine, but the call to malloc failed for some reason, returning 0.
I'm gonna publish the soution of similar crash I found after hour of debugging, maybe it would be useful for somebody...
The reason was in so stupid thing.
I had two placeholders in NSLog and only one real variable.
NSLog(#"lastItemDate = %# unixtime = %#", lastItemDate);
Related
I have problem with Thread 1: EXC_BAD_ACCESS (code=1, address=0xf00000c) and I don't know how to resolve it.
It appeared when I change some object in core date and save it and I try to pop this controller to parent.
This error is in main() with retVal.
here is some code
int retVal;
#try {
retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
*/\ error is here**
}
#catch (NSException *exception) {
NSLog(#"%#", [exception callStackSymbols]);
#throw exception;
}
return retVal;
After re-runing app all my changes are in core data. What is more this problem is only on iOS 7. iOS 6.1 is ok.
Does someone have idea how to resolve it?
As a comment said this error is likely to be deep in your code. If the culprit is a zombie, the easiest way to find it is to run it (preferably in the latest Xcode, currently Xcode 5, as it has been improved) in profiler and choose "Zombies". When it fails, you can see the history of everything that has happened to the object.
Also, set an exception breakpoint. You may get a break when the error happens instead of in main, where the exception gets passed up.
I just had the exact same problem.
Looked here and found nothing so I started backtracking until I thought, maybe I should try Clean Build Folderš¤
I was glad it was as easy as CLEAN BUILD FOLDER!!!
Product- Clean Build Folder(ā§ ā K)
š
I resolved this problem with "Zombies" and the problem was with
[UIScrollView(UIScrollViewInternal) _notifyDidScroll]
I added
- (void)dealloc {
self.tableView.delegate = nil;
}
This problem was only in iOS 7.
Thanks for help!
I have resolve this issue only by debugging the source code and re-analyze my logic.
Below are some reference that help me lot.
EXC_BAD_ACCESS means that message was sent to a point in the memory where thereās no instance of a class to execute it. Thus ābad accessā.
You will get EXC_BAD_ACCESS in 3 cases:
An object is not initialized
An object is already released
Something else that is not very likely to happen
Thatās already a good starting point. Start using the debugger, if you recently added a new object to the class youāre working on, put a breakpoint at the line before the freshly added object is used for the first time and check the values in the debugger.
Whatās happening most though is that you will be sending a message to an overreleased object ā i.e. object that is gone from the call stack. In this cases everything (and indeed everything) you will get in the console will be just :EXC_BAD_ACCESS
This is because the object is gone, there is no information what class was it, or what source file or anything else.
Please try to avoid using zombies for this.
EXC_BAD_ACCESS means there is no instance of a class to execute it.
There are 2 or more possibilities:
An object is not initialized
An object is already released
Please debug application carefully and analyze each object carefully. That might solve your issue.
I solved the same problem by finding out that the name of one of my NSString variables had the same name as one of the frameworks' class variables. Took seconds to change the name a little and problem disappeared.
With such a huge number of class variables in frameworks, it is very likely that once in a while, every programmer just by coincidence names some variable in his class exactly the same as one used somewhere in framework classes.
So it doesn't have to be Xcode bug in most cases.
In my case, I was using third-party library and I forgot to set custom-class name in Storyboard Identity Inspector
And there may be another issue which I faced today:
I had a mutable dictionary with a non-object entry try. There was a code snippet with adding a BOOL value to the dictionary. So no wonder that I got this error =).
In my case it was trying to log an Int32 with %s in print statement
in my view this is the equivalent of every other language NullPointerException,
but unlike other languages there are no hellping pointers (class name / method or line of the occurrence / god forbid a Stacktrace),
so the only thing i could do to solve it fast is to start printing main functions and views, (a very primitive solution),
create a swift: Debug.swift
add this function into Debug.swift:
public func trace(_ message: String = "", file: String = #file, function: String = #function, line: Int = #line)
{
print("**** \(file).\(function)[\(line)]: \(message)")
}
then you can use it like this:
trace("initializing")
to use it inside a var do this:
let _ = trace("initializing")
this should print something similar to this:
**** /path/to/my/file/MyFile.swift.someFunc()[18]: initializing
this is how i started adding debug lines to gain some flow record, so next time i have a EXC_BAD_ACCESS i will have a clue where the problem leis
don't forget to disable the prints during production deployment
I want to test my app's crash reporting out in the field by deliberately having it crash when the user performs a particular action that a real user is unlikely to do accidentally.
But what's a good reliable way of making the app crash that doesn't create a warning at compile time?
Edit: Note that many seemingly obvious answers to this question result in exceptions that get caught by Cocoa and thus don't result in the app crashing.
in Objective-C use C directly to cause a bad access
strcpy(0, "bla");
Note: while this works on any system I know -- in a future version of the C runtime OR the compiler this might not lead to a crash anymore. see Is null pointer dereference undefined behavior in Objective-C?)
(in swift you would have to bridge to objC to do this)
My current favourite:
assert(! "crashing on purpose to test <insert your reason here>");
A classic:
kill( getpid(), SIGABRT );
And some pr0n:
*(long*)0 = 0xB16B00B5;
All of them generate crashes captured by my crash reporting tool.
Since we all use Clang for iOS, this is fairly reliable:
__builtin_trap();
This has the benefit that it's designed for exactly this purpose, so it shouldn't generate any compiler warnings or errors.
How about a good old stack overflow :)
- (void)stackOverflow
{
[self stackOverflow];
}
abort(); causes abnormal terminationā¦ That is a crash.
Most popular one - unrecognised selector crash:
NSObject *object = [[NSObject alloc] init];
[object performSelector:#selector(asfd)];
Make sure you don't have -asdf method implemented in that class haha
Or index beyond bound exception:
NSArray * array = [NSArray array];
[array objectAtIndex:5];
And of course
kill( getpid(), SIGABRT );
I think in Swift you could easily throw a fatal error:
func foo() {
fatalError("crash!")
}
It is actually even intended to use this feature in case something goes wrong in order to make the app crash.
To avoid an if statement in a special case, you could use precondition, too. It's similar to assert, makes thus the intention (if wanted) pretty clear and is not removed in the final release as assert. It is used like precondition(myBoolean, "This is a helpful error message for debugging.").
Send a message to a deallocated object
exit(0);
(must... type... 30 characters)
You can also raise an exception:
[NSException raise:NSInternalInconsistencyException
format:#"I want to test app crashes!."];
Add a gesture recognizer to a view that recognizes a 10 finger tap (5 fingers for iPhone as 10 can get a bit crowded). The GR has a method attached to it that executes anyone of the previously mentioned surefire ways to get your app to crash. Most users are not going to lay 10 fingers down on your app, so you're safe from the general user accidentally causing the crash.
However you should be able to use something like Testflight or just deploying it to personal devices and test in the wild before ever submitting it to Apple. Having a forced crash could get your app rejected by Apple.
could try something like
NSArray* crashingArray = [NSArray arrayWithCapacity:1];
[crashingArray release];
should crash on an EXC_BAD_ACCESS (might need to release it a second time but normaly it should crash like this already)
I will go with:int raise(int sig);
To get more info >man raise
I would just kill the process normally:
kill(getpid(), SIGKILL);
So if you install a handler with signal you can also handle the crash, finishing to write opened files and these things.
I use
[self doesNotRecognizeSelector:_cmd];
When working with RubyMotion I use this:
n=Pointer.new ('c', 1)
n[1000] ='h'
Try this:
- (IBAction)Button:(id)sender
{
NSArray *array = [NSArray new];
NSLog(#"%#",[array objectAtIndex:8]);
}
a wrong NSLog statement will do it
NSLog(#"%#",1);
I have a code with two targets that uses functions specific to iOS 4 and others compatible with 3.0+.
I would like to make a final revision on the code to see if everything is fine. In other words, to see if there's no function meant for iOS4 being called when compiling for iOS 3.x target.
Is there a way to list, during compilation, any functions being called that doesn't belong to the desired version for the target?
thanks in advance.
1) turn the compiler warnings all the way up
2) treat warnings as errors
3) change the base/target SDK to the earliest version you will support
4) clean
5) build
things such as implicit functions and undeclared selectors should now generate errors.
to avoid errors going forward, create a shim static library for the functions or objc methods you will need. this shim will implement two variations of the code, and will ultimately build against the latest headers. it will contain conditional runtime checks. for the objc class methods you can fake, use categories and use the category implementation where any warning is generated.
to illustrate using two versions of the code:
/*
illustration:
- sortByCoordinates: was added in OS 4, but we need to implement or approximate it for our projects targeting OS 3 (or throw out an alert in some cases)
- as long as you have to support OS 3 and build against the SDKs from time to time, the compiler will produce errors or warnings when a selector has not been declared, or if an object may not respond to a selector (assuming you have directed the compiler to inform you of this)
- so we put our conditionals/runtime checks in a library here, and update our calls from sortByCoordinates: to mon_sortByCoordinates:
*/
- (void)mon_sortByCoordinates:(EECoordinate*)coordinates
{
/* MONLib_OSVersion_4_0 implies some constant, indicating OS 4 */
/* MONLibGetCurrentRuntimeVersion() is a call we make at runtime which returns the OS version, such as MONLib_OSVersion_4_0 or MONLib_OSVersion_3_2 */
if (MONLib_OSVersion_4_0 <= MONLibGetCurrentRuntimeVersion()) {
/* they are using OS 4 (or greater) - call the OS version */
[self sortByCoordinates:coordinates];
}
else {
/*
%%%%%% < else implement our approximation here >
*/
}
}
finally, the compiler can't catch everything for you, due to objc's dynamic nature and the way objc programs are often written. sometimes it helps to be more verbose. simple example:
#interface MONBox
/* added in version 4 */
- (NSUInteger)count;
#end
NSUInteger beispiel() {
if (0) {
/* less safe -- the compiler will not flag this */
/* if [myNSArrayInstace objectAtIndex:0] is a MONBox then this will go undetected since the selector count may be matched to -[NSArray count] */
return [[myNSArrayInstaceOfMONBoxObjects objectAtIndex:0] count];
}
else {
/* more safe -- the compiler will flag this */
MONBox * box = [myNSArrayInstaceOfMONBoxObjects objectAtIndex:0];
return [box count];
}
}
I don't think there's an automated way to do this, as far as I know. I keep an old first-gen iPhone around for this purpose -- I'll run the app on the device and see what crashes. Not ideal but it works OK for smaller apps.
I have a program using CoreData and a navigation controller. If I add a entity that is connected to my main entity through a relationship than back out to the table view of all entries and the back into the same, recently edited, entry my program crashes. My code is very similar, and for the CoreData part the same, to Apples sample code iPhoneCoreDataRecipes.
The code will crash the first time I attempt to access the entity that I just changed with a "EXC_BAD_ACCESS".
If I pause the program before that occurs and try and access my CoreData object I get the following in the console.
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xec0470f2
0x937eeedb in objc_msgSend ()
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off"
Evaluation of the expression containing the function (_NSPrintForDebugger) will be abandoned.
NSMutableArray *tempEventsArray = [[NSMutableArray alloc] initWithArray:[journalEntry.event allObjects]];
self.eventsArray = tempEventsArray;
[tempEventsArray release];
Apple's iPhoneCoreDataRecipes has the same problem so I will submit a bug report but did not know if I was missing some thing. My iPone development target 3.1 and base SDK is also 3.1.
How is eventsArray declared? From your usage, it should be a retained property. It it's only assign, then you're crashing due to over-releasing the array.
I have an app that appears to run without problems in normal use. The Clang Static Analyzer reports no problems either. When I try to run it in Instruments, it fails with an unrecognized selector exception.
The offending line is a simple property setter of the form:
self.bar = baz;
To figure out what's going on, I added an NSLog() call immediately above it:
NSLog(#"class = %# responds = %d", [self class], [self respondsToSelector:#selector(setBar:)]);
self.bar = baz;
On the emulator (without Instruments) and on a device, this shows exactly what I'd expect:
class = Foo responds = 1
When running under Instruments, I get:
class = Foo responds = 0
I'm stumped as to what could cause this. Perhaps a different memory location is getting tromped on when it's in the Instruments environment? Can anyone suggest how I might debug this?
If bar belongs to self, can't you do bar=baz; ?
Check your properties.
Perhaps to you need a cast on baz?
There's not enough information here to know what's going on, but then, if you knew what information to provide you'd probably have already fixed it. So. A few things to check:
Is the "self" pointer being swizzled in any way? Try printing out the value of self at various points just for sanity's sake
When your code runs in Instruments, is it running in a different mode? (32-bit vs. 64-bit, Garbage collected vs. Retain-Release, etc.) I'm not sure why any of those would have an effect, but if it's running in a different mode, that's something to look into.
Are you synthesizing the setter correctly? Or is it being provided dynamically (via Core Data, etc.)? If you manually specify a setBar: method, do you still get the error?