14

Been trying to debug a crash for the past 10 hours and finally, I simplified it to this code:

NSError *error = nil;
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"payload" ofType:@"txt"]];
id obj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

With NSZombieEnabled, this crashes the app at the third line (where the parsing happens) and it logs:

*** -[CFString retain]: message sent to deallocated instance 0x758afa0

The contents of payload.txt are:

[
   {
      "created_at":"2013-02-15T23:46:02-05:00",
      "description":"Take out the Big Gun sounded simple enough, except the Strogg were waiting. You, and a few marines like you, are the lucky ones. You've made it down in one piece and are still able to contact the fleet. The Gravity Well, the Strogg's newest weapon in its arsenal against mankind, is operational. With the fleet around Stroggos, 5% of ground forces surviving, and that number dwindling by the second, your orders have changed: free your comrades. Destroy the Gravity Well.Minimum: A 100% Windows XP/Vista-compatible computer system",
      "developer":"id Software",
      "external_id":"2340",
      "id":745,
      "image":"http://cdn.steampowered.com/v/gfx/apps/2340/header_292x136.jpg",
      "is_subscribed":0,
      "link":"http://store.steampowered.com/app/2340/",
      "price":"4.99",
      "seller_id":2,
      "thumb":"http://media.steampowered.com/steamcommunity/public/images/apps/2340/5bd6e22ffdf72fdfb5ce2092fa50150de5fbb56f.jpg",
      "title":"Quake II: Ground Zero",
      "updated_at":"2013-02-15T23:46:02-05:00",
      "is_subscribed":0
   },
   {
      "created_at":"2013-02-15T23:45:59-05:00",
      "description":"Rage through 32 single player levels and 6 deathmatch levels of sheer terror and fully immersive sound and lighting. Arm yourself against the cannibalistic Ogre, fiendish Vore and indestructible Schambler using lethal nails, fierce Thunderbolts and abominable Rocket and Grenade Launchers.Minimum: A 100% Windows XP/Vista-compatible computer system",
      "developer":"id Software",
      "external_id":"2310",
      "id":742,
      "image":"http://cdn.steampowered.com/v/gfx/apps/2310/header_292x136.jpg",
      "is_subscribed":0,
      "link":"http://store.steampowered.com/app/2310/",
      "price":"9.99",
      "seller_id":2,
      "thumb":"http://media.steampowered.com/steamcommunity/public/images/apps/2310/e5bdf8dc7759c573fe525d45b69011f6a173a984.jpg",
      "title":"Quake",
      "updated_at":"2013-02-15T23:45:59-05:00",
      "is_subscribed":0
   }
]

It's just an array of 2 dictionaries. I am not sure what's causing this crash/what's wrong with this JSON.

UPDATE Removing "is_subscribed":0 in the first object in the array gets rid of the crash.

0xSina
  • 20,973
  • 34
  • 136
  • 253
  • If you try to use SBJSON library than this is easy. – Dilip Manek Feb 16 '13 at 10:37
  • 1
    @Dilip I don't want to use SBJSON. I want to know why NSJSONSerialization is crashing and/or what's wrong with my JSON. – 0xSina Feb 16 '13 at 10:39
  • 5
    @Dilip Don't give bad pieces of advice, please. –  Feb 16 '13 at 10:40
  • 1
    Maybe you have a defective payload.txt file (some characters are malformed). I tried to recreate the issue on my machine and created the payload.txt file with content pasted from the text box above, and It works. (iOS 6.1 simulator) – gardenofwine Feb 16 '13 at 10:55
  • @gardenofwine I thought about that, and did exactly what you did. Copy/pasted the JSON from my this SO post just like you and still get the crash so it can't be defective payload.txt. Do you have NSZombieEnabled? I only get that crash with NSZonbieEnabled or if I disable NSZombieEnabled then after a relatively long period of time (randomly). – 0xSina Feb 16 '13 at 10:58
  • What memory management model are you using? Manual retain/release? ARC? Garbage Collected? Which one did @gardenofwine use, and on what platform? Also iOS 6.1 simulator? Maybe it's only broken for one of these? And what Xcode version / MacOS version are you compiling/running under? Might be a compiler bug, particularly with ARC. – uliwitness Feb 16 '13 at 11:02
  • @uliwitness Using ARC, iOS 6.0 simulator. Getting crash on both simulator and device. XCode 4.5.2 and Mac OS X 10.7.5 – 0xSina Feb 16 '13 at 11:06
  • Maybe it's because you have "is_subscribed":0 twice in your dictionary? :) – Boris Prohaska Feb 16 '13 at 11:11
  • I can confirm the crash (with and without ARC). It happens only if "is_subscribed" occurs twice in *both dictionaries*. It does not happen if "is_subscribed" is renamed to a different key. - Without Zombies enabled, is does not crash, but the "is_subscribed" entry is missing in the second dictionary. - That looks like a bug in NSJSONSerialization. – Martin R Feb 16 '13 at 11:16
  • Moreover, payload like `[ { "key":0, "key":0 } ]` not causing this issue – anticyclope Feb 16 '13 at 11:27
  • @uliwitness I ran the code with ARC and without. I managed to reduce the problematic JSON to this: '[ { "is_subscribed":0, "a": "2013-02-15T23:46:02-05:00", "is_subscribed":2 }, { "is_subscribed":1, "a": "2013-02-15T23:46:02-05:00" } ]' (sorry it is not formatted in the comment). – gardenofwine Feb 16 '13 at 11:43
  • Slightly smaller: `[{"is_subscribed":0,"a":"2013-02-15T23:46:02-05:00","is_subscribed":0},{"is_subscribed":0,}]` also crashes. The strange thing is: if I modify the date string slightly, it does not crash anymore. - If you don't enable Zombies, it does not crash, but `NSLog(@"%@", obj)` does not return, it hangs somewhere in very deep recursion. – Martin R Feb 16 '13 at 11:49
  • It's time to upvote the question, since nobody found an obvious error in the code so far! – Martin R Feb 16 '13 at 11:57
  • The duplicate "is_subscribed" key was a mistake by me on the server side, which I fixed and it has fixed the issue. But I am still curious about the crash .@anticyclope raises a good point, it's not just a duplicate key, but specifically "is_subscribed". Moreover, there are versions of this payload with duplicate "is_subscribed" key that do not cause the crash. Also, the order of the two objects in array matters. If you switch them around, it does not crash. – 0xSina Feb 16 '13 at 13:00
  • @0xSina: Yes, strange indeed. Even if you change the date strings in the first dictionary, it does not crash anymore! – Martin R Feb 16 '13 at 13:26
  • possible duplicate of [NSJSONSerialization results in EXC\_BAD\_ACCESS](http://stackoverflow.com/questions/12842481/nsjsonserialization-results-in-exc-bad-access) – Max MacLeod Mar 13 '13 at 14:45
  • We had the same problem with duplicate keys, ex: {"objectType":"Product","id":"52a90f0207a7ec58949bb603","productId":436490635,"imageId":"958b773a3e64fb3a79c24994e977a50b","objectType":"Product","objectId":"436490635"} note that crash was only on iOS 6, not iOS 7. – Seth Spitzer Apr 24 '14 at 22:22

2 Answers2

3

It looks like Apple did a bad work in error handling of such cases within their class, since your getting crash instead of normal nil result and error variable populated. Your json data and minimalistic code is what Apple usually require for a proper bug report. Report the bug by following link - https://developer.apple.com/bugreporter/ do not forget to attach project in zip as a proof that it crashes.

Nikita Leonov
  • 5,684
  • 31
  • 37
  • Could you clarify btw what is the logic behind this duplicated vars? Not sure how you planned to process them. – Nikita Leonov Feb 16 '13 at 23:17
  • The problem isn't merely any duplicated keys, but rather specifically "is_subscribed" string key. In fact, if you swap the order if the two dictionary around in the main array, it no longer crashes...so it is more than just duplicated keys. Read the discussion under main post for more. `[ { "key":0, "key":0 } ]` does not cause this issue. If you read the discussion on the main post, you will find the logic behind duplicated keys in dictionary...it was a mistake on my part on server side. – 0xSina Feb 17 '13 at 06:22
  • 1
    You are right. I went through the series of test and it seems that there is only one odd behavior. I think you have a good case for bug report. It is not expected behavior, such classes should not crash in any setups. You may go and submit report by following link - https://developer.apple.com/bugreporter/ – Nikita Leonov Feb 17 '13 at 17:09
2

I had this issue and for me, the issue was a duplicate key in the JSON. My key was named differently - not "is_subscribed" like in your case, but "food_nutrients". I'm willing to bet that iOS 6 crashes on any duplicate keys where there's another key in between - not just an "is_subscribed" key as some of the comments suggest.

I've confirmed that duplicate keys of any name are the issue. Related: https://stackoverflow.com/a/21148319/2030

Community
  • 1
  • 1
Josh Brown
  • 52,385
  • 10
  • 54
  • 80