Fehler im Release-Build - Debug-Build läuft. :-/

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Fehler im Release-Build - Debug-Build läuft. :-/

    Hallo Leute,

    ich habe bei meinem aktuellen Projekt gerade einen Fehler, der mich in die Tischkante beißen lässt. Im Release-Build stürzt meine App mit einer Exception ab. ("*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil") Der Fehler ist auch absolut reproduzierbar. Immer die gleichen Schritte führen dazu. Das Blöde ist nur, dass im Debug-Build alles einwandfrei läuft, ohne Probleme. Dort tritt der Fehler nicht auf. Weder, wenn ich den Debug-Build außerhalb von Xcode starte, noch wenn ich in in Xcode mit aktivem Debugger starte. Es kommt keine Fehler, keine Warnung, kein dezenter Hinweis, kein Log-Eintrag - nichts, gar nichts. Und wenn ich die Sourcen meiner App nach "insertObject:" durchsuche, findet Xcode ebenfalls nichts. Wie soll man denn so einen Fehler finden? Ich bin gerade völlig ratlos... :(

    Hier ist der Back-Trace, denn der Release-Build meiner App ausspuckt. Habt ihr eine Idee?

    Quellcode

    1. ​0 CoreFoundation 0x00007fff8838064c __exceptionPreprocess + 172
    2. 1 libobjc.A.dylib 0x00007fff895086de objc_exception_throw + 43
    3. 2 CoreFoundation 0x00007fff8822cea9 -[__NSArrayM insertObject:atIndex:] + 1033
    4. 3 Keryx 0x00000001025ee1b6 Keryx + 78262
    5. 4 libsystem_trace.dylib 0x00007fff826d8cd7 _os_activity_initiate + 75
    6. 5 AppKit 0x00007fff84bb8497 -[NSApplication sendAction:to:from:] + 410
    7. 6 AppKit 0x00007fff84bb82c0 -[NSControl sendAction:to:] + 86
    8. 7 Keryx 0x00000001025f7058 Keryx + 114776
    9. 8 CoreFoundation 0x00007fff8833ccbc __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
    10. 9 CoreFoundation 0x00007fff8822e1b4 _CFXNotificationPost + 3140
    11. 10 Foundation 0x00007fff87d38ea1 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
    12. 11 AppKit 0x00007fff84af6557 -[NSTableView _sendSelectionChangedNotificationForRows:columns:] + 175
    13. 12 AppKit 0x00007fff84a4ece3 -[NSTableView _enableSelectionPostingAndPost] + 409
    14. 13 AppKit 0x00007fff84bb56cb -[NSTableView mouseDown:] + 5984
    15. 14 Keryx 0x00000001025ee6b5 Keryx + 79541
    16. 15 AppKit 0x00007fff85113f4f -[NSWindow _reallySendEvent:] + 12827
    17. 16 AppKit 0x00007fff84b9e50c -[NSWindow sendEvent:] + 368
    18. 17 AppKit 0x00007fff84b50096 -[NSApplication sendEvent:] + 2238
    19. 18 AppKit 0x00007fff849dce98 -[NSApplication run] + 711
    20. 19 AppKit 0x00007fff849c82d4 NSApplicationMain + 1832
    21. 20 libdyld.dylib 0x00007fff8cfac5c9 start + 1
    Alles anzeigen


    Gruß Marc
  • du versuchst anscheinend ein nil in ein array zu schieben
    dann step dich doch mal an das entsprechende Array ran und guck was da passiert

    bzw. nutzt du für debug und release unterschiedliche Datenquellen Test und Live Api oder so? und bei Release bekommst du halt Müll/nil sachen was du nicht abfängst?
    Ich weiß nicht immer wovon ich rede aber ich weiß das ich Recht habe. :saint:
  • Wenn ich wüsste, welches array das ist. Wie gesagt: im Debug-Build kommt die Exception nicht. Und ich beziehe auch keine Live-Daten, sondern eine Daten-Struktur aus CoreData, die für beide Builds die selbe ist (und angelegt wird, wenn sie nicht existiert, weswegen ich auch schon erfolglos probiert habe, die Daten zu löschen). Wie kann ich mich an ein Array anschleichen, wenn ich nicht wies, welches es ist bzw. im Debug-Bild alle zufrieden sind mit dem was sie bekommen? Abgefahren...

    Wird bei NSMutableArray addObject: auch insertObject:atIndex: aufgerufen? Also vom NSMutableArray selbst? Denn addObject: verwende ich an der ein oder anderen Stelle (auch wenn eingebaute NSLogs zeigen, dass auch im Release-Build anstandslos addObject: durchgeführt wird, ohne zu crash. Der kommt erst irgendwo später...).
  • Du wirst Doch die Zeilen 7 und 3 in Deinem Code lokalisieren können? Zeile 7 z.B. wird wohl die Methode "tableViewSelectionDidChange:" oder "tableViewSelectionWillChange:" eines NSTableViewDelegate-Objektes sein. Soviele von der Sorte wirst Du ja nicht haben und Du weißt ja auch in welche Tabelle Du klickst bevor es zum Absturz kommt. Dann siehst Du ja im Code was Du machst und was die Ursache sein könnte.

    ciao

    gandhi
  • Ok, nach vielen Probieren und einem hilfreichen Geistesblitz hab ich das Problem eingekreist und auch eine Lösung gefunden. Ich verstehe es aber immer noch nicht so ganz. Kurz zur Erläuterung: ich hab mit TableViews einen eigenen NSBrowser nachgebaut (hauptsächlich, um die Gruppen-Views wie in der Finder-Ansicht seit 10.7 nachzubauen). Meine Browser-Klasse hat auch eine getSelectedIndexPath Funktion. Diese stellt den Index-Path zusammen, in dem die Selected-Rows der TableViews pro Spalte in einem Array abgelegt werden. Damit wird dann ein NSIndexPath Object erstellt, welches im Release-Build aber eben nicht erstellt wird. Das heißt, im Release-Build liefert die Funktion nil zurück. Der Rückgabewert wird dann in einem Array abgelegt und schon hab ich den Salat. Ok, das zur Vorgeschichte.

    Folgender Code war das Problem:

    Quellcode

    1. // Array zum Ablegen der Indizies pro Tabelle...
    2. NSUInteger indexCount = column;
    3. NSUInteger *selectedRows = alloca(sizeof(NSUInteger) * indexCount);
    4. for (int i = 0; i < column + 1; i++)
    5. {
    6. selectedRows[i] = ((NSTableView *)_tableViews[i]).selectedRow;
    7. if ((NSInteger)selectedRows[i] == -1) // Spalten können sichtbar sein, ohne dass etwas darin selektiert ist!
    8. {
    9. indexCount--;
    10. break;
    11. }
    12. }
    13. return [NSIndexPath indexPathWithIndexes:selectedRows length:indexCount + 1];
    Alles anzeigen

    Im Release-Build ist indexCount am Ende = -2, warum auch immer. Aber dass dann nil zurück geliefert wird, ist klar. Wenn ich nun die Zeile

    Quellcode

    1. NSUInteger *selectedRows = alloca(sizeof(NSUInteger) * indexCount);
    durch

    Quellcode

    1. NSUInteger selectedRows[column];
    ersetze, läuft alles ohne Probleme.

    Was ich nun nicht verstehe ist folgendes:
    • Warum bitte schön macht mein originaler Code mit alloca hier Probleme? Hatte schonmal an anderer Stelle mit malloc / realloc gearbeitet, und irgendwie hat mir das ganze internen Speicher überschreiben. Das dynamische durch ein fixes array ausgetauscht und alles lief.
    • Und warum macht der Code nur im Release-Build ärger, nicht aber im Debug-Build?
    Ich scheine ja einen elementaren Fehler zu machen (klar, ein festes Array anzulegen ist eleganter, hätte ich auch früher drauf kommen können). Aber welchen? Ich würde es gerne verstehen, um in Zukunft solch ein Problem nicht mehr zu haben.

    Gruß Marc

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von SchodMC ()