Git Product home page Git Product logo

Comments (13)

gorbster avatar gorbster commented on August 23, 2024

Seeing a similar thing when running the first test on OS X 10.6.8 / Xcode 4.0.2 / iOS 4.3 SDK. Here's the stack trace:

#0  0x0101f45c in GSEventGetLocationInWindow ()
#1  0x0008051e in -[UIScrollView(UIScrollViewInternal) _resetScrollingWithUIEvent:] ()
#2  0x0007ad4f in -[UIScrollView(UIScrollViewInternal) _beginTrackingWithEvent:] ()
#3  0x000a7346 in -[UITableView _beginTrackingWithEvent:] ()
#4  0x000776a8 in -[UIScrollView _gestureRecognizer:shouldReceiveTouch:] ()
#5  0x002c72ed in -[UIGestureRecognizer _delegateShouldReceiveTouch:] ()
#6  0x001b2d6d in -[UITouchesEvent _addGestureRecognizersForView:toTouch:] ()
#7  0x001b29c1 in -[UITouchesEvent _addTouch:forDelayedDelivery:] ()
#8  0x00012ec5 in -[UIView(KIFAdditions) _eventWithTouch:] (self=0x583de00, _cmd=0x18b46, touch=0x4e62060) at UIView-KIFAdditions.m:402
#9  0x000119cb in -[UIView(KIFAdditions) tapAtPoint:] (self=0x583de00, _cmd=0x188f9, point={x = 160, y = 22}) at UIView-KIFAdditions.m:257
#10 0x00009f26 in __+[KIFTestStep stepToTapViewWithAccessibilityLabel:value:traits:]_block_invoke_1 (.block_descriptor=0x4c16810, step=0x4c167c0, error=0xbfffdf08) at KIFTestStep.m:170
#11 0x0000ce98 in -[KIFTestStep executeAndReturnError:] (self=0x4c167c0, _cmd=0x1848a, error=0xbfffdf08) at KIFTestStep.m:381
#12 0x000040da in -[KIFTestController _performTestStep:] (self=0x4c14490, _cmd=0x16eba, step=0x4c167c0) at KIFTestController.m:222
#13 0x00004058 in -[KIFTestController _delayedScheduleCurrentTestStep] (self=0x4c14490, _cmd=0x16ecc) at KIFTestController.m:210

from kif.

kstenerud avatar kstenerud commented on August 23, 2024

I'm getting the same thing as gorbster (same OS and Xcode version).

The last executed line with accessible source code is:

[touchEvent _addTouch:touch forDelayedDelivery:NO];

(gdb) po touchEvent
<UITouchesEvent: 0x9200790> timestamp: 0 touches: {(
<UITouch: 0x4e0b140> phase: Began tap count: 1 window: <UIWindow: 0x6826950; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6826330>> view: <UITableViewCellContentView: 0x4e0b870; frame = (0 0; 320 43); layer = <CALayer: 0x4e0ba30>> location in window: {160, 86} previous location in window: {160, 86} location in view: {160, 22} previous location in view: {160, 22}
)}
(gdb) po touch
<UITouch: 0x4e0b140> phase: Began tap count: 1 window: <UIWindow: 0x6826950; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6826330>> view: <UITableViewCellContentView: 0x4e0b870; frame = (0 0; 320 43); layer = <CALayer: 0x4e0ba30>> location in window: {160, 86} previous location in window: {160, 86} location in view: {160, 22} previous location in view: {160, 22}

It fails in GSEventGetLocationInWindow:

0x01018455  <+0000>  push   %ebp
0x01018456  <+0001>  mov    %esp,%ebp
0x01018458  <+0003>  push   %ebx
0x01018459  <+0004>  mov    0x8(%ebp),%eax
0x0101845c  <+0007>  mov    0x18(%eax),%edx    ; Fails here with EXC_BAD_ACCESS
0x0101845f  <+0010>  mov    0x1c(%eax),%ebx
0x01018462  <+0013>  mov    %edx,%eax
0x01018464  <+0015>  mov    %ebx,%edx
0x01018466  <+0017>  pop    %ebx
0x01018467  <+0018>  leave  
0x01018468  <+0019>  ret    

eax is a null pointer:

(gdb) p/x $eax
$3 = 0x0

from kif.

gorbster avatar gorbster commented on August 23, 2024

I set a breakpoint in GSEventGetLocationInWindow(), ran the Testable scheme, and "manually" tapped the first cell. It looks like %eax is supposed to have a GSEvent:

(gdb) po $eax
<GSEvent 0x5885850>{type = 0, windowLoc = (1080287232, 0)}

As a second experiment, I created a new project testing a simple tapping scenario on a UIButton in a UIView. The event-flow did not invoke GSEventGetLocationInWindow(). The test ran without issue.

Then I moved the UIButton into a UIScrollView and tried again. This time GSEventGetLocationInWindow() was invoked and EXC_BAD_ACCESS occurred in the exact same spot kstenerud lists above.

Looks like the touch event gets dropped somewhere in the UIScrollView(UIScrollViewInternal) calls.

from kif.

kstenerud avatar kstenerud commented on August 23, 2024

Found the problem. It looks like Apple's code checks the event's class, and throws out anything that's not of type UIEvent when bridging to GSEvent.

When I changed "KIFTouchEvent: NSObject" to "UIEvent (KIFAdditionsPrivate)", it worked perfectly (all it was doing was exposing method names to stop the compiler from complaining, so I don't see this change causing any problems).

I'll send a pull request shortly.

from kif.

gorbster avatar gorbster commented on August 23, 2024

Interesting. I just noticed that if you first run a tap test scenario on a view whose superview is not a UIScrollView, and THEN run a test on a view whose superview is a UIScrollView, the test works fine. And GSEventGetLocationInWindow() is sent a valid KIFEventProxy instance:

(gdb) po $eax
<KIFEventProxy: 0x4c42e70>

I wonder why the code only works if it's not the first scenario ran.

from kif.

amrox avatar amrox commented on August 23, 2024

I'm seeing the same exact issue.

from kif.

kstenerud avatar kstenerud commented on August 23, 2024

Actually now that I think about it, my original explanation doesn't make sense. The code was simply casting to a class that had methods defined at the interface level (no implementation), so it was actually sending a UIEvent object, not modifying or proxying it.

I just noticed, however, that in my investigations I changed the order of operations such that it called _setGSEvent BEFORE calling _addTouch instead of after.

Either way, this fix feels a bit like voodoo :P

from kif.

kstenerud avatar kstenerud commented on August 23, 2024

I wonder why the code only works if it's not the first scenario ran.

That would make sense actually. Here's the code as it currently stands in the repo:

[touchEvent _addTouch:touch forDelayedDelivery:NO];
[touchEvent _setGSEvent:(struct __GSEvent *)eventProxy];

It's calling _addTouch before it had set the GSEvent, so the event starts out NULL. But something in the _addTouch call tree tries to look into the (nonexistent) GSEvent in certain cases. If you're dealing with a non-scrolling view, Apple's code doesn't call GSEventGetLocationInWindow(). So having a NULL GSEvent won't cause a crash in this case.

Next, you call another test that fires an event from a scroll view, and so the call tree determines that it needs to look inside the GSEvent. If the application is recycling touch events (and Apple does like to recycle data objects, so it's definitely a possibility), the recycled touch event could still have the GSEvent from the previous call, and so it wouldn't crash (but it would have bad data since it holds the information from the previous event, not the current event).

from kif.

gorbster avatar gorbster commented on August 23, 2024

@kstenerud yeah, the touchEvent is still a UITouchesEvent instance even though it's casted in code.

But I can also confirm that changing the order of _setGSEvent and _addTouch seems to "work".

This might be why the original code works when another non-UIScrollView-based event is successfully sent to the app before; a GSEvent (KIFEventProxy) is already set on the app's _touchesEvent from the previous event when _eventWithTouch is called again:

(gdb) po [touchEvent _gsEvent]
<KIFEventProxy: 0x4e88800>

GSEventGetLocationInWindow() gets a non-nil KIFEventProxy object and everybody is happy. So it would seem the app's UITouchesEvent/KIFTouchEvent needs a valid GSEvent/KIFEventProxy before the touch is added to it.

Another thing I discovered, a couple lines later, _addGestureRecognizersForView:toTouch: is called. However this is also called internally by the previous _addTouch:forDelayedDelivery:. Removing the explicit call doesn't seem to hurt anything, so I'm not sure it's necessary.

from kif.

gorbster avatar gorbster commented on August 23, 2024

Jinx! :)

Well, it sounds the voodoo solution of swapping the calls might be the best fix for the time being.

from kif.

kstenerud avatar kstenerud commented on August 23, 2024

Just tried it.

This crashes every time:

[event _addTouch:touch forDelayedDelivery:NO];
[event _setGSEvent:(struct __GSEvent *)eventProxy];
[event _addGestureRecognizersForView:touch.view toTouch:touch];

This runs without crashing:

[event _setGSEvent:(struct __GSEvent *)eventProxy];
[event _addGestureRecognizersForView:touch.view toTouch:touch];
[event _addTouch:touch forDelayedDelivery:NO];

I ran the tests multiple times, resetting the simulator and doing a clean build for each run.

from kif.

gorbster avatar gorbster commented on August 23, 2024

Confirmed here too.

from kif.

efirestone avatar efirestone commented on August 23, 2024

Karl's pull request has been merged and this should be working now. Closing.

from kif.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.