1 Reply Latest reply on May 8, 2016 12:52 PM by Rob Roberts

    RhoContact.find crashes app on device

    Rob Roberts

      Hello,

       

      I have an app that uses Rho::RhoContact.find(:all) to get all of the contacts from the iPhone. This used to work fine, but is now broken. (I'm not sure when it quit working, but it was at least a few Rhodes versions ago.) It still works right in the simulator, but on the device it immediately crashes the app. This is with Rhodes 5.4.0 and iOS 9.3.1, tested on both an iPhone 6S and iPad Air 2. It also happened on an iPhone 5S with iOS 8, and with Rhodes 5.1.1.

       

      Checking the logs in Xcode shows this error:

       

      Exception Type: EXC_BAD_ACCESS (SIGABRT)

      Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000

      Triggered by Thread: 8

       

      Thread 8 Crashed:

      0 libsystem_kernel.dylib 0x00000001817c811c __pthread_kill + 8

      1 libsystem_pthread.dylib 0x0000000181894ef8 pthread_kill + 112

      2 libsystem_c.dylib 0x0000000181739dac abort + 140

      3 rhorunner 0x00000001003c5acc report_bug (error.c:227)

      4 rhorunner 0x000000010042ea78 sigpipe (signal.c:621)

      5 libsystem_platform.dylib 0x000000018188d94c _sigtramp + 68

      6 rhorunner 0x00000001002ae604 _getRecord (phonebook.m:182)

      7 rhorunner 0x00000001002ae604 _getRecord (phonebook.m:182)

      8 rhorunner 0x00000001002adfb0 getPhonebookRecords (phonebook.m:489)

      9 rhorunner 0x0000000100491440 _wrap_getRecords (phonebook_wrap.c:2087)

      10 rhorunner 0x000000010047c1b4 vm_call_cfunc (vm_insnhelper.c:402)

      11 rhorunner 0x000000010047b398 vm_call_method (vm_insnhelper.c:524)

      12 rhorunner 0x0000000100471fb4 vm_exec_core (insns.def:1006)

      13 rhorunner 0x0000000100477074 vm_exec (vm.c:1155)

      14 rhorunner 0x0000000100476050 vm_call0 (vm_eval.c:68)

      15 rhorunner 0x00000001004755c4 rb_funcall (vm_eval.c:640)

      16 rhorunner 0x0000000100493bac callFramework (rhoruby.c:1039)

      17 rhorunner 0x00000001002de210 rho::net::CHttpServer::decide(std::string const&, std::string const&, std::string const&, rho::Vector<rho::net::HttpHeader> const&, std::string const&) (HttpServer.cpp:1418)

      18 rhorunner 0x00000001002dc5dc rho::net::CHttpServer::process(int) (HttpServer.cpp:885)

      19 rhorunner 0x00000001002dc2dc rho::net::CHttpServer::run() (HttpServer.cpp:572)

      20 rhorunner 0x000000010037e774 rho::common::CRhodesApp::run() (RhodesApp.cpp:556)

      21 rhorunner 0x00000001002d1834 rho::common::CRhoThread::runObject() (RhoThread.h:62)

      22 rhorunner 0x00000001002dac5c rho::common::runProc(void*) (PosixThreadImpl.cpp:66)

      23 libsystem_pthread.dylib 0x0000000181893b28 _pthread_body + 156

      24 libsystem_pthread.dylib 0x0000000181893a8c _pthread_body + 0

      25 libsystem_pthread.dylib 0x0000000181891028 thread_start + 4

       

       

      It happens on this call: Rho::RhoContact.find(:all)

       

      Is anyone else having this problem? Anyone have any ideas?

       

      Thanks in advance,

      Rob Roberts

        • Re: RhoContact.find crashes app on device
          Rob Roberts

          I figured out what was causing the EXC_BAD_ACCESS exception that was causing the app to crash when accessing contacts on the device. It was because of passing a nil value to the CFStringCompare method, as in this line from the _addPhonesToHash method in phonebook.m, where it turns out that label can sometimes be nil:

           

          if(CFStringCompare(label,kABWorkLabel,0)==kCFCompareEqualTo) {

           

          With the contact data that I have on the devices I was testing with, this was happening in two places, the _addPhonesToHash and _addUrlToHash methods. I ended up adding this line above the CFStringCompare calls:

           

          if (label == nil) continue;

           

          as in this example from _addUrlToHash:

           

          static void _addUrlToHash(VALUE hash,ABRecordRef ref) {

              ABMultiValueRef urls = ABRecordCopyValue(ref,kABPersonURLProperty);

              if (urls) {

                  int num_urls = ABMultiValueGetCount(urls);

                  for (int n = 0; n < num_urls; n++) {

                      CFStringRef label = ABMultiValueCopyLabelAtIndex(urls,n);

                if (label == nil) continue;

          if(CFStringCompare(label,kABPersonHomePageLabel,0)==kCFCompareEqualTo) {

                          _addPropertyToHash(hash,RUBY_PB_HOME_PAGE,

                                             ABMultiValueCopyValueAtIndex(urls,n));

                      }

                      CFRelease(label);

                  }

                  CFRelease(urls);

              }   

          }

           

          I added the same line to all places in the contacts code that could be passing a nil value to CFStringCompare, which was these methods:

           

          _addPhonesToHash

          _addEmailToHash

          _addUrlToHash

          _addRelatedNamesToHash

          _addDatesToHash

           

          This fixed the problem. No more app crash when calling Rho::RhoContact.find(:all).

           

          Rob Roberts