Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS app crashes on ptr.get() #627

Closed
mraiser opened this issue Dec 3, 2014 · 2 comments
Closed

iOS app crashes on ptr.get() #627

mraiser opened this issue Dec 3, 2014 · 2 comments

Comments

@mraiser
Copy link

mraiser commented Dec 3, 2014

After passing an AudioQueuePtr into AudioQueue.newInput, the iOS app crashes hard when I then call ptr.get(). There is no stack trace in the java console. I get the same error when attempting ptr.get() after passing an AudioFilePtr into AudioFile.createWithURL.

Main Class:

import java.lang.reflect.Method;

import org.robovm.apple.audiotoolbox.AudioQueue;
import org.robovm.apple.audiotoolbox.AudioQueueError;
import org.robovm.apple.audiotoolbox.AudioQueue.AudioQueuePtr;
import org.robovm.apple.audiotoolbox.AudioQueueBuffer.AudioQueueBufferPtr;
import org.robovm.apple.coreaudio.AudioFormat;
import org.robovm.apple.coreaudio.AudioStreamBasicDescription;
import org.robovm.apple.coreaudio.CoreAudio;
import org.robovm.apple.coreaudio.AudioStreamPacketDescription.AudioStreamPacketDescriptionPtr;
import org.robovm.apple.coreaudio.AudioTimeStamp.AudioTimeStampPtr;
import org.robovm.apple.corefoundation.CoreFoundation;
import org.robovm.apple.coregraphics.*;
import org.robovm.apple.foundation.*;
import org.robovm.apple.uikit.*;
import org.robovm.rt.bro.Bro;
import org.robovm.rt.bro.Struct;
import org.robovm.rt.bro.annotation.Callback;
import org.robovm.rt.bro.ptr.FunctionPtr;
import org.robovm.rt.bro.ptr.VoidPtr;

public class TestAudioQueueCrash extends UIApplicationDelegateAdapter
{
       private UIWindow window = null;
        private int clickCount = 0;

        @Override
        public boolean didFinishLaunching(UIApplication application, UIApplicationLaunchOptions launchOptions) 
        {

            final UIButton button = UIButton.create(UIButtonType.RoundedRect);
            button.setFrame(new CGRect(115.0f, 121.0f, 91.0f, 37.0f));
            button.setTitle("Click me!", UIControlState.Normal);

            button.addOnTouchUpInsideListener(new UIControl.OnTouchUpInsideListener() 
            {
                @Override
                public void onTouchUpInside(UIControl control, UIEvent event) 
                {
                    double mSampleRate = 44100;
                    AudioFormat mFormatID = AudioFormat.LinearPCM;
                    int mFormatFlags = CoreAudio.AudioFormatFlagIsBigEndian | CoreAudio.AudioFormatFlagIsPacked | CoreAudio.AudioFormatFlagIsSignedInteger;
                    int mBytesPerPacket = 2;
                    int mFramesPerPacket = 1;
                    int mBytesPerFrame = 2;
                    int mChannelsPerFrame = 1;
                    int mBitsPerChannel = 16;    

                    AudioStreamBasicDescription asbd = new AudioStreamBasicDescription(mSampleRate, mFormatID, mFormatFlags, mBytesPerPacket, mFramesPerPacket, mBytesPerFrame, mChannelsPerFrame, mBitsPerChannel, 0);
                    AudioQueuePtr mQueuePtr = new AudioQueuePtr();

                    int kNumberBuffers = 3;
                    AudioQueueBufferPtr mBuffers = Struct.allocate(AudioQueueBufferPtr.class, kNumberBuffers);
                    AQRecorderState aqData = new AQRecorderState(asbd, mQueuePtr, mBuffers , null, 1024, 0, false);
                    Method callbackMethod = null;
                    Method[] methods = TestAudioQueueCrash.class.getMethods();
                    int i = methods.length;
                    while (i-->0) if (methods[i].getName().equals("callbackMethod")) { callbackMethod = methods[i]; break; }
                    System.out.println(callbackMethod);
                    FunctionPtr fp = new FunctionPtr(callbackMethod );

                    AudioQueueError aqe = AudioQueue.newInput(asbd, fp, aqData.as(VoidPtr.class), null, CoreFoundation.RunLoopCommonModes().toString(), 0, mQueuePtr);
                    System.out.println(aqe.name());
                    System.out.println("wait for it...");
                    AudioQueue queue = mQueuePtr.get();
                    System.out.println("never gets here");

                    button.setTitle("Click #" + (++clickCount), UIControlState.Normal);
                }
            });

            window = new UIWindow(UIScreen.getMainScreen().getBounds());
            window.setBackgroundColor(UIColor.lightGray());
            window.addSubview(button);
            window.makeKeyAndVisible();

            return true;
        }

        /*<bind>*/static { Bro.bind(TestAudioQueueCrash.class); }/*</bind>*/
        /*<constants>*//*</constants>*/
        /*<constructors>*//*</constructors>*/
        /*<properties>*//*</properties>*/
        /*<members>*//*</members>*/
        @Callback
        public static void callbackMethod(AQRecorderState.AQRecorderStatePtr aqDataPtr, AudioQueuePtr inAQ, AudioQueueBufferPtr inBuffer, AudioTimeStampPtr inStartTime, int inNumPackets, AudioStreamPacketDescriptionPtr inPacketDesc)
        {
            System.out.println("RECORDING YAY!");
        }

        public static void main(String[] args) 
        {
            try (NSAutoreleasePool pool = new NSAutoreleasePool()) 
            {
                UIApplication.main(args, null, TestAudioQueueCrash.class);
            }
        }

}

Support Struct class:

/*<imports>*/
import org.robovm.rt.bro.*;
import org.robovm.rt.bro.annotation.*;
import org.robovm.rt.bro.ptr.*;
import org.robovm.apple.audiotoolbox.AudioFile;
import org.robovm.apple.audiotoolbox.AudioQueue.AudioQueuePtr;
import org.robovm.apple.audiotoolbox.AudioQueueBuffer.AudioQueueBufferPtr;
import org.robovm.apple.coreaudio.*;
/*</imports>*/

/*<javadoc>*/

/*</javadoc>*/
/*<annotations>*//*</annotations>*/
/*<visibility>*/public/*</visibility>*/ class /*<name>*/AQRecorderState/*</name>*/ 
    extends /*<extends>*/Struct<AQRecorderState>/*</extends>*/ 
    /*<implements>*//*</implements>*/ {

    /*<ptr>*/public static class AQRecorderStatePtr extends Ptr<AQRecorderState, AQRecorderStatePtr> {}/*</ptr>*/
    /*<bind>*/
    /*</bind>*/
    /*<constants>*//*</constants>*/
    /*<constructors>*/
    public AQRecorderState() {}
    public AQRecorderState(AudioStreamBasicDescription mDataFormat, AudioQueuePtr mQueue, AudioQueueBufferPtr mBuffers, AudioFile mAudioFile, int bufferByteSize, long mCurrentPacket, boolean mIsRunning) {
        this.mDataFormat(mDataFormat);
        this.mQueue(mQueue);
        this.mBuffers(mBuffers);
        this.mAudioFile(mAudioFile);
        this.bufferByteSize(bufferByteSize);
        this.mCurrentPacket(mCurrentPacket);
        this.mIsRunning(mIsRunning);
    }
    /*</constructors>*/
    /*<properties>*//*</properties>*/
    /*<members>*/
    @StructMember(0) public native @ByVal AudioStreamBasicDescription mDataFormat();
    @StructMember(0) public native AQRecorderState mDataFormat(@ByVal AudioStreamBasicDescription mDataFormat);
    @StructMember(1) public native AudioQueuePtr mQueue();
    @StructMember(1) public native AQRecorderState mQueue(AudioQueuePtr mQueue);
    @StructMember(2) public native @Array({3}) AudioQueueBufferPtr mBuffers();
    @StructMember(2) public native AQRecorderState mBuffers(@Array({3}) AudioQueueBufferPtr mBuffers);
    @StructMember(3) public native AudioFile mAudioFile();
    @StructMember(3) public native AQRecorderState mAudioFile(AudioFile mAudioFile);
    @StructMember(4) public native int bufferByteSize();
    @StructMember(4) public native AQRecorderState bufferByteSize(int bufferByteSize);
    @StructMember(5) public native long mCurrentPacket();
    @StructMember(5) public native AQRecorderState mCurrentPacket(long mCurrentPacket);
    @StructMember(6) public native boolean mIsRunning();
    @StructMember(6) public native AQRecorderState mIsRunning(boolean mIsRunning);
    /*</members>*/
    /*<methods>*//*</methods>*/
}

Java Console:

2014-12-03 13:14:14.309 TestAudioQueueCrash[2172:60b] Application windows are expected to have a root view controller at the end of application launch
public static void TestAudioQueueCrash.callbackMethod(AQRecorderState$AQRecorderStatePtr,org.robovm.apple.audiotoolbox.AudioQueue$AudioQueuePtr,org.robovm.apple.audiotoolbox.AudioQueueBuffer$AudioQueueBufferPtr,org.robovm.apple.coreaudio.AudioTimeStamp$AudioTimeStampPtr,int,org.robovm.apple.coreaudio.AudioStreamPacketDescription$AudioStreamPacketDescriptionPtr)
WARN: Failed to call getClassTypeID() for the CFType subclass org.robovm.apple.audiotoolbox.AudioFileStream
WARN: Failed to call getClassTypeID() for the CFType subclass org.robovm.apple.audiotoolbox.AudioQueueTimeline
WARN: Failed to call getClassTypeID() for the CFType subclass org.robovm.apple.audiotoolbox.AudioFile
WARN: Failed to call getClassTypeID() for the CFType subclass org.robovm.apple.audiotoolbox.AudioQueue
No
wait for it...

RoboVM Console:

12/3/14 1:14:11 PM: [DEBUG] Launching app...
12/3/14 1:14:11 PM: [DEBUG] App Path: /private/var/mobile/Applications/73C91F8D-2C1C-46EA-A37B-2800780398A8/TestAudioQueueCrash.app
12/3/14 1:20:25 PM: [ERROR] AppLauncher failed with an exception:
12/3/14 1:20:25 PM: [ERROR] java.lang.RuntimeException: Unexpected response from debugserver: $X00#00
12/3/14 1:20:25 PM: [ERROR]     at org.robovm.libimobiledevice.util.AppLauncher.pipeStdOut(AppLauncher.java:761)
12/3/14 1:20:25 PM: [ERROR]     at org.robovm.libimobiledevice.util.AppLauncher.launchInternal(AppLauncher.java:691)
12/3/14 1:20:25 PM: [ERROR]     at org.robovm.libimobiledevice.util.AppLauncher.launch(AppLauncher.java:965)
12/3/14 1:20:25 PM: [ERROR]     at org.robovm.compiler.target.ios.AppLauncherProcess$1.run(AppLauncherProcess.java:67)

Symbolicated XCode Organizer Device Log:

Incident Identifier: 3C668457-06A5-4BA7-B2F7-26E85D0D3F0E
CrashReporter Key:   08d7c27d21cb15553295bbae1b2aa2040e94b517
Hardware Model:      iPhone3,1
Process:             TestAudioQueueCrash [2172]
Path:                /var/mobile/Applications/73C91F8D-2C1C-46EA-A37B-2800780398A8/TestAudioQueueCrash.app/TestAudioQueueCrash
Identifier:          TestAudioQueueCrash
Version:             1 (1.0)
Code Type:           ARM (Native)
Parent Process:      debugserver [2171]

Date/Time:           2014-12-03 13:20:25.752 -0500
OS Version:          iOS 7.1.2 (11D257)
Report Version:      104

Exception Type:  EXC_CRASH (SIGSEGV)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Triggered by Thread:  1

Thread 0:
0   libobjc.A.dylib                 0x39292626 objc_msgSend + 6
1   TestAudioQueueCrash             0x00407740 [J]org.robovm.apple.corefoundation.CFType.getTypeID(J)J + 92
2   TestAudioQueueCrash             0x00408294 [J]org.robovm.apple.corefoundation.CFType.access$000(J)J + 28
3   TestAudioQueueCrash             0x004082ce [j]org.robovm.apple.corefoundation.CFType.access$000(J)J[clinit] + 42
4   TestAudioQueueCrash             0x00408732 [J]org.robovm.apple.corefoundation.CFType$Marshaler.toObject(Ljava/lang/Class;JJZ)Lorg/robovm/apple/corefoundation/CFType; + 86
5   TestAudioQueueCrash             0x00408684 [J]org.robovm.apple.corefoundation.CFType$Marshaler.toObject(Ljava/lang/Class;JJ)Lorg/robovm/apple/corefoundation/CFType; + 60
6   TestAudioQueueCrash             0x00742118 _call0 + 44
7   TestAudioQueueCrash             0x0073b33a callObjectMethod + 98
8   TestAudioQueueCrash             0x0073ce0a rvmCallObjectClassMethodA + 178
9   TestAudioQueueCrash             0x000e26c6 Java_java_lang_reflect_Method_internalInvoke + 250
10  TestAudioQueueCrash             0x00274bb4 [J]java.lang.reflect.Method.internalInvoke(J[Ljava/lang/Class;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; + 76
11  TestAudioQueueCrash             0x00274948 [J]java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; + 260
12  TestAudioQueueCrash             0x007219c0 [J]org.robovm.rt.bro.MarshalerLookup.toObject(Ljava/lang/Class;J)Lorg/robovm/rt/bro/NativeObject; + 216
13  TestAudioQueueCrash             0x00721a42 [j]org.robovm.rt.bro.MarshalerLookup.toObject(Ljava/lang/Class;J)Lorg/robovm/rt/bro/NativeObject;[clinit] + 50
14  TestAudioQueueCrash             0x0072ca90 [J]org.robovm.rt.bro.ptr.Ptr.toObject(J)Lorg/robovm/rt/bro/NativeObject; + 176
15  TestAudioQueueCrash             0x0072c852 [J]org.robovm.rt.bro.ptr.Ptr.get()Lorg/robovm/rt/bro/NativeObject; + 74
16  TestAudioQueueCrash             0x0072cb74 [j]org.robovm.rt.bro.ptr.Ptr.get()Lorg/robovm/rt/bro/NativeObject;[lookup] + 40
17  TestAudioQueueCrash             0x00206c7c [J]TestAudioQueueCrash$1.onTouchUpInside(Lorg/robovm/apple/uikit/UIControl;Lorg/robovm/apple/uikit/UIEvent;)V + 536
18  TestAudioQueueCrash             0x005d9910 [j]org.robovm.apple.uikit.UIControl$OnTouchUpInsideListener.onTouchUpInside(Lorg/robovm/apple/uikit/UIControl;Lorg/robovm/apple/uikit/UIEvent;)V[lookup] + 76
19  TestAudioQueueCrash             0x005d9050 [J]org.robovm.apple.uikit.UIControl$ListenerWrapper.handleTouchEvent(Lorg/robovm/apple/uikit/UIControl;Lorg/robovm/apple/uikit/UIEvent;)V + 296
20  TestAudioQueueCrash             0x005d931c [J]org.robovm.apple.uikit.UIControl$ListenerWrapper.$cb$handleTouchEvent(Lorg/robovm/apple/uikit/UIControl$ListenerWrapper;Lorg/robovm/objc/Selector;Lorg/robovm/apple/uikit/UIControl;Lorg/robovm/apple/uikit/UIEvent;)V + 32
21  TestAudioQueueCrash             0x005d93d8 [j]org.robovm.apple.uikit.UIControl$ListenerWrapper.$cb$handleTouchEvent(Lorg/robovm/apple/uikit/UIControl$ListenerWrapper;Lorg/robovm/objc/Selector;Lorg/robovm/apple/uikit/UIControl;Lorg/robovm/apple/uikit/UIEvent;)V[callback] + 180
22  UIKit                           0x3132a032 -[UIApplication sendAction:to:from:forEvent:] + 86
23  UIKit                           0x31329fd2 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 26
24  UIKit                           0x31329fac -[UIControl sendAction:to:forEvent:] + 40
25  UIKit                           0x31315712 -[UIControl _sendActionsForEvents:withEvent:] + 370
26  UIKit                           0x31329a2a -[UIControl touchesEnded:withEvent:] + 586
27  UIKit                           0x313296fc -[UIWindow _sendTouchesForEvent:] + 524
28  UIKit                           0x313246c6 -[UIWindow sendEvent:] + 754
29  UIKit                           0x312f98c8 -[UIApplication sendEvent:] + 192
30  UIKit                           0x312f7f72 _UIApplicationHandleEventQueue + 7098
31  CoreFoundation                  0x2eaa3208 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
32  CoreFoundation                  0x2eaa26d6 __CFRunLoopDoSources0 + 202
33  CoreFoundation                  0x2eaa0eca __CFRunLoopRun + 618
34  CoreFoundation                  0x2ea0beba CFRunLoopRunSpecific + 518
35  CoreFoundation                  0x2ea0bc9e CFRunLoopRunInMode + 102
36  GraphicsServices                0x3391165e GSEventRunModal + 134
37  UIKit                           0x31358148 UIApplicationMain + 1132
38  TestAudioQueueCrash             0x005992ae [J]org.robovm.apple.uikit.UIApplication.main(ILorg/robovm/rt/bro/ptr/BytePtr$BytePtrPtr;Ljava/lang/String;Ljava/lang/String;)I + 166
39  TestAudioQueueCrash             0x00598842 [J]org.robovm.apple.uikit.UIApplication.main([Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V + 234
40  TestAudioQueueCrash             0x00598882 [j]org.robovm.apple.uikit.UIApplication.main([Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V[clinit] + 50
41  TestAudioQueueCrash             0x002068e6 [J]TestAudioQueueCrash.main([Ljava/lang/String;)V + 166
42  TestAudioQueueCrash             0x00742118 _call0 + 44
43  TestAudioQueueCrash             0x0073b072 callVoidMethod + 98
44  TestAudioQueueCrash             0x0073ccee rvmCallVoidClassMethodA + 174
45  TestAudioQueueCrash             0x0073cd48 rvmCallVoidClassMethod + 16
46  TestAudioQueueCrash             0x0073715e rvmRun + 402
47  TestAudioQueueCrash             0x0072fc26 main + 290
48  TestAudioQueueCrash             0x001f7b2c start + 36

Thread 1 Crashed:
0   libsystem_kernel.dylib          0x39838a58 mach_msg_trap + 20
1   libsystem_kernel.dylib          0x39838854 mach_msg + 44
2   libsystem_kernel.dylib          0x39847f62 mach_msg_server + 402
3   TestAudioQueueCrash             0x007315ce exceptionHandlerEntryPoint + 34
4   TestAudioQueueCrash             0x00751832 GC_inner_start_routine + 82
5   TestAudioQueueCrash             0x0074f36c GC_call_with_stack_base + 28
6   TestAudioQueueCrash             0x00752910 GC_start_routine + 28
7   libsystem_pthread.dylib         0x398b4916 _pthread_body + 138
8   libsystem_pthread.dylib         0x398b4886 _pthread_start + 98
9   libsystem_pthread.dylib         0x398b2aa0 thread_start + 4
@ntherning
Copy link
Contributor

Thanks for the detailed bug report! I've looked into this and it seems like we have a bug in our bindings.

@BlueRiverInteractive: The AudioFile should not extend from CFType but rather be a NativeObject. It's defined like this in the AudioFile.h header:

typedef struct OpaqueAudioFileID    *AudioFileID;

So nothing that indicates that it's a CFType "subclass". Better look through other classes in that framework as well and make sure they don't extend from CFType unless needed.

@mraiser
Copy link
Author

mraiser commented Dec 5, 2014

I can confirm that the replacing the org.robovm.apple.audiotoolbox package with the one in the latest version of robovm-1.0.0-beta-01 fixes both crashes. Many, many thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants