Re: How EXC_BAD_ACCESS in objc_msgSend if receiver, parms OK?

2012-02-23 Thread Greg Parker
On Feb 20, 2012, at 10:16 AM, Matt Neuburg m...@tidbits.com wrote:
 On Fri, 17 Feb 2012 16:06:01 -0800, Greg Parker gpar...@apple.com said:
 No. objc_msgSend() also reads from the class's method cache and method list. 
 It's possible for the receiver object to be valid, but still crash because 
 of a memory smasher that hit the method cache or method list
 
 It's also possible for the receiver object to be valid but the wrong object. 
 I remember in my early Cocoa programming days I mismanaged the memory for an 
 NSString object and was mystified when *another NSString object took its 
 place*. I believe NSZombie would have tracked that down by occupying the slot 
 pointed to by the variable and not letting some other string slip into it. In 
 other words, believe in zombies, not in your intuitions about how everything 
 looks okay. :) m.

Having a prematurely-deallocated object replaced by a new object of the same 
type can lead to all sorts of exciting bugs, but a crash in objc_msgSend() 
itself is not one of them. (And yes, NSZombie is good at catching such cases. 
The dead object's address will not be re-used, at least not any time soon.)


-- 
Greg Parker gpar...@apple.com Runtime Wrangler



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How EXC_BAD_ACCESS in objc_msgSend if receiver, parms OK?

2012-02-22 Thread Matt Neuburg
On Fri, 17 Feb 2012 16:06:01 -0800, Greg Parker gpar...@apple.com said:
No. objc_msgSend() also reads from the class's method cache and method list. 
It's possible for the receiver object to be valid, but still crash because of 
a memory smasher that hit the method cache or method list

It's also possible for the receiver object to be valid but the wrong object. I 
remember in my early Cocoa programming days I mismanaged the memory for an 
NSString object and was mystified when *another NSString object took its 
place*. I believe NSZombie would have tracked that down by occupying the slot 
pointed to by the variable and not letting some other string slip into it. In 
other words, believe in zombies, not in your intuitions about how everything 
looks okay. :) m.

--
matt neuburg, phd = m...@tidbits.com, http://www.apeth.net/matt/
A fool + a tool + an autorelease pool = cool!
Programming iOS 5! http://shop.oreilly.com/product/0636920023562.do
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: How EXC_BAD_ACCESS in objc_msgSend if receiver, parms OK?

2012-02-22 Thread Sean McBride
On Fri, 17 Feb 2012 16:06:01 -0800, Greg Parker said:

Those of us who wrote objc_msgSend() can sometimes track down the
problem by finding which data structure was damaged and examining the
bad data. Everyone else should try Zombies, Guard Malloc, and Malloc Scribble.

And valgrind... if it works reasonably these days...

-- 

Sean McBride, B. Eng s...@rogue-research.com
Rogue Researchwww.rogue-research.com 
Mac Software Developer  Montréal, Québec, Canada



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

How EXC_BAD_ACCESS in objc_msgSend if receiver, parms OK?

2012-02-17 Thread Jerry Krinock
I got an EXC_BAD_ACCESS in objc_msgSend.  By probing registers in gdb, I am 
able to get the receiver, selector and the single parameter of the offending 
message.

(gdb) po *(int*)($ebp+8)
BkmslfWinCon: 0xcdbf570

(gdb) po NSStringFromSelector(*(int*)($ebp+12))
updateAgentActivityNow:

(gdb) po *(int*)($ebp+16)
__NSCFTimer: 0x9315960

So it's is a message from Cocoa's timer-firing mechanism, firing the selector 
of a timer.  Given where the program was, this message is expected.

Both the receiver (a window controller) and the method's parameter (a timer) 
both seem to be good, live, valid objects…

(gdb) po 0xcdbf570
BkmslfWinCon: 0xcdbf570
(gdb) po [0xcdbf570 window]
SSYHintableWindow: 0xcd8deb0
(gdb) po 0x9315960
__NSCFTimer: 0x9315960
(gdb) po [0x9315960 userInfo]
{
agentLabel = 6609802C6B47.000.001.doSoon.36665;
}

I manually sent most of the messages in the offending method, and got mostly 
expected results [1].  One message was too hairy to send manually.

So how could there have been EXC_BAD_ACCESS?  In my experience, I think that 
I've seen such inexplicable crashes caused by something *really* bad in the 
offending method, such as wrong parameters in a format string.  I think that 
sometimes gdb gets so upset that it can't show you the top of the call stack.  
Is that true?

If I try to manually send the crashed message using gdb's 'call' command, I 
also get EXC_BAD_ACCESS…

(gdb) call [0xcdbf570 updateAgentActivityNow:0x9315960]

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x63610002
0x9985cd4b in objc_msgSend ()
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use set unwindonsignal on
Evaluation of the expression containing the function (objc_msgSend) will be 
abandoned.

What could be going on here?

The crash occurs on the main thread.

I would like to discount this crash as an artifact of my using Xcode 3 under 
Mac OS 10.7, but unfortunately the offending method is one that I recently 
added to a large project.  Not a likely coincidence.

Thanks,

Jerry Krinock

Here is the call stack:

#0  0x9985cd47 in objc_msgSend
#1  0x003053cc in maxInt.32934
#2  0x9b850bdf in __NSFireTimer
#3  0x92511656 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__
#4  0x92510fe7 in __CFRunLoopDoTimer
#5  0x924eff70 in __CFRunLoopRun
#6  0x924ef47c in CFRunLoopRunSpecific
#7  0x924ef328 in CFRunLoopRunInMode
#8  0x91e5617f in RunCurrentEventLoopInMode
#9  0x91e5d4e7 in ReceiveNextEventCommon
#10 0x91e5d356 in BlockUntilNextEventMatchingListInMode
#11 0x9bb07a9c in _DPSNextEvent
#12 0x9bb07306 in -[NSApplication 
nextEventMatchingMask:untilDate:inMode:dequeue:]
#13 0x9bb03675 in -[NSApplication run]
#14 0x9bd97261 in NSApplicationMain
#15 0x1e15 in main at MainApp-Main.m:49


[1] Here is the offending method, with comments added to show the results of my 
manually running the lines.

- (void)updateAgentActivityNow:(NSTimer*)timer {
// I have subclassed NSApp so I can switch off dock bouncing.  See below 
[2].
[NSApp setBeQuiet:YES] ;
// When I tried to send the above message manually, I got an inexplicable 
result:
//(gdb) call [NSApp setBeQuiet:1]
//Value can't be converted to integer.
// I don't know what that means.

Bkmslf* bkmslf = (Bkmslf*)[self document] ;
// Sending the above message manually returns the live document as 
expected.
BkmxAgentActivity oldState = [self agentActivityFilteredState] ;
BkmxAgentActivity newState = [self agentActivityLastInputState] ;
[self setAgentActivityFilteredState:newState] ;
// Sending the above three messages manually works OK.
// I can even set and then get those two attributes.

if (oldState != BkmxAgentActivityNone) {
// Based on value of old state, this branch would have executed.
[self dismissAgentActivityAlertSheet] ;
// However I don't think there's any problem here.  See below [3].
}

NSString* irregularAgentLabel = [[timer userInfo] 
objectForKey:constKeyAgent] ;
// Sending the above message manually gives the expected result

if (newState == BkmxAgentActivityStaged) {
// Based on value of newState, this branch *would* be executed.
if ([self shouldPerformNow]) {
   // Based on value of shouldPerformNow, this branch *would* be 
executed.
Agent* agent ;
Trigger* trigger ;
// I didn't try to send this message since I don't know the values
// of the two return-by-reference parameters.
[self whyForAgentLabel:irregularAgentLabel
   agent_p:agent
 trigger_p:trigger] ;

// So then, I couldn't try this either…
[agent dropAndDoTrigger:trigger] 

Re: How EXC_BAD_ACCESS in objc_msgSend if receiver, parms OK?

2012-02-17 Thread Kyle Sluder
On Fri, Feb 17, 2012 at 8:53 AM, Jerry Krinock je...@ieee.org wrote:

 Both the receiver (a window controller) and the method's parameter (a timer) 
 both seem to be good, live, valid objects…

 (gdb) po 0xcdbf570
 BkmslfWinCon: 0xcdbf570
 (gdb) po [0xcdbf570 window]
 SSYHintableWindow: 0xcd8deb0
 (gdb) po 0x9315960
 __NSCFTimer: 0x9315960
 (gdb) po [0x9315960 userInfo]
 {
    agentLabel = 6609802C6B47.000.001.doSoon.36665;
 }

All that means is that the storage for the object hasn't been
overwritten yet. What does NSZombieEnabled say?

--Kyle Sluder

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: How EXC_BAD_ACCESS in objc_msgSend if receiver, parms OK?

2012-02-17 Thread Jerry Krinock

On 2012 Feb 17, at 09:54, Kyle Sluder wrote:

 All that means is that the storage for the object hasn't been overwritten yet.

Thank you, Kyle, and I see what you mean.  But also my tests show that the 
object is still able to respond to messages, which means that it shouldn't have 
crashed objc_msgSend.  No?

 What does NSZombieEnabled say?

Well, as usual, this crash happened when NSZombieEnabled was not active.  I've 
scripted Xcode and the crash conditions, and my script is now testing 
repeatedly with NSZombieEnabled and friends active.

As to my implied question: Can anything other than a deallocced receiver or 
deallocced parameter cause a crash in objc_msgSend?  I re-read Greg Parker's 
article on this topic…

http://www.sealiesoftware.com/blog/archive/2008/09/22/objc_explain_So_you_crashed_in_objc_msgSend.html

I would paraphrase Greg's answer as Usually it's due to a deallocced object, 
but not always, and in the latter case you're in deep doodoo.  I'm hoping to 
get another crash with zombies on, while I think about the code.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: How EXC_BAD_ACCESS in objc_msgSend if receiver, parms OK?

2012-02-17 Thread Greg Parker
On Feb 17, 2012, at 2:02 PM, Jerry Krinock wrote:
 On 2012 Feb 17, at 09:54, Kyle Sluder wrote:
 All that means is that the storage for the object hasn't been overwritten 
 yet.
 
 Thank you, Kyle, and I see what you mean.  But also my tests show that the 
 object is still able to respond to messages, which means that it shouldn't 
 have crashed objc_msgSend.  No?

No. objc_msgSend() also reads from the class's method cache and method list. 
It's possible for the receiver object to be valid, but still crash because of a 
memory smasher that hit the method cache or method list. If those data 
structures are damaged in the right way then some messages will succeed and 
other messages will crash, which is consistent with your ability to send other 
messages to the object.

Those of us who wrote objc_msgSend() can sometimes track down the problem by 
finding which data structure was damaged and examining the bad data. Everyone 
else should try Zombies, Guard Malloc, and Malloc Scribble.


-- 
Greg Parker gpar...@apple.com Runtime Wrangler



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com