Need help interpreting crash report

  1. 2 weeks ago

    Robert W

    Nov 29 Western Canada
    Edited 2 weeks ago

    Following is an excerpt from a crash report, when my application "quits unexpectedly" in debug mode. The IDE doesn't catch it. I've tried running under the 2016r3 IDE and the 2018r3 IDE's.

    XOJO 2018r3:

    Crashed Thread:        0  Dispatch queue: com.apple.main-thread
    
    Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
    Exception Codes:       KERN_INVALID_ADDRESS at 0x00005a0d16edbec0
    
    VM Regions Near 0x5a0d16edbec0:
        MALLOC_LARGE           000000011238d000-0000000119a8d000 [119.0M] rw-/rwx SM=PRV  
    --> 
        MALLOC_NANO            0000600000000000-0000600000200000 [ 2048K] rw-/rwx SM=COW  
    
    Application Specific Information:
    objc_msgSend() selector name: release
    
    
    Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
    0   libobjc.A.dylib               	0x00007fff8ce340dd objc_msgSend + 29
    1   com.apple.CoreFoundation      	0x00007fff92753fdd -[__NSDictionaryM dealloc] + 269
    2   libobjc.A.dylib               	0x00007fff8ce5489c objc_object::sidetable_release(bool) + 236
    3   libobjc.A.dylib               	0x00007fff8ce3ae8f (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 575
    4   com.apple.CoreFoundation      	0x00007fff927416f2 _CFAutoreleasePoolPop + 50
    5   com.apple.Foundation          	0x00007fff8664b832 -[NSAutoreleasePool drain] + 153
    6   com.apple.AppKit              	0x00007fff8dcfdbc1 -[NSApplication run] + 800
    7   com.xojo.XojoFramework        	0x00000001088f691d RuntimeRun + 42
    8   com.whatever.myExperiment     	0x00000001084ff2f3 REALbasic._RuntimeRun + 19
    9   com.whatever.myExperiment     	0x00000001085d4822 _Main + 402 (/#main:134)
    10  com.whatever.myExperiment     	0x00000001085d37c3 main + 19
    11  libdyld.dylib                 	0x00007fff8d0785c9 start + 1

    Here is an excerpt from the crash log when running in 2016r3:

    Crashed Thread:        0  Dispatch queue: com.apple.main-thread
    
    Exception Type:        EXC_CRASH (SIGABRT)
    Exception Codes:       0x0000000000000000, 0x0000000000000000
    
    Application Specific Information:
    abort() called
    *** error for object 0x2142b40: pointer being freed was not allocated
     
    
    Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
    0   libsystem_kernel.dylib        	0x9aa1969a __pthread_kill + 10
    1   libsystem_pthread.dylib       	0x90453634 pthread_kill + 101
    2   libsystem_c.dylib             	0x9416ade6 abort + 156
    3   libsystem_malloc.dylib        	0x9c31ad28 free + 428
    4   libobjc.A.dylib               	0x96e63003 _object_dispose(objc_object*) + 68
    5   com.apple.UIFoundation        	0x91a6e50f -[NSParagraphStyle dealloc] + 89
    6   com.apple.UIFoundation        	0x91a6e49f -[NSParagraphStyle release] + 301
    7   com.apple.CoreFoundation      	0x9779a0cd CFRelease + 989
    8   com.apple.CoreFoundation      	0x977d1f6c -[__NSDictionaryM dealloc] + 268
    9   libobjc.A.dylib               	0x96e6e650 objc_object::sidetable_release(bool) + 248
    10  libobjc.A.dylib               	0x96e5aa59 -[NSObject release] + 25
    11  libobjc.A.dylib               	0x96e5a1bc (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 566
    12  com.apple.CoreFoundation      	0x977bddaf _CFAutoreleasePoolPop + 47
    13  com.apple.Foundation          	0x9a2da30f -[NSAutoreleasePool drain] + 122
    14  com.apple.AppKit              	0x9902fb27 -[NSApplication run] + 790
    15  com.xojo.XojoFramework        	0x00364bba 0x1b6000 + 1764282
    16  com.xojo.XojoFramework        	0x00362d94 RuntimeRun + 49
    17  com.whatever.myExperiment     	0x0009d6f5 REALbasic._RuntimeRun + 34
    18  com.whatever.myExperiment     	0x001633f9 _Main + 295
    19  com.whatever.myExperiment     	0x001625b7 main + 36
    20  com.whatever.myExperiment     	0x00163842 start + 53

    <<Edit>>
    Additional info:
    OS Version: Mac OS X 10.10.5 (14F2009)
    <<End Edit>>

    A brief explanation of what the program is doing at the time of crash: It's running a recursive routine searching a small data set for a certain pattern. With most data sets, the routine successfully executes in less than 20 seconds. But with certain data sets, it runs for tens of minutes and then crashes.

    I'm trying to figure out what is happening, and why the IDE doesn't catch it.

  2. Sam R

    Nov 29 Pre-Release Testers, Xojo Pro Hengchun, Pingtung, Taiwan

    The IDE won't catch this kind of crash, because it's not something that the Xojo Framework can check for. It's a CFObject or NSObject that's already been released, is getting sent the "Release" message.

    NSObjects & CFObjects are the underlying elemental objects of macOS, Xojo uses them, as do declares and plugins. So one of those 3 possibilities is not correctly managing the object.

    If you use any plugins or declares, strip those from your project first. Once this is pure Xojo code, you can contact Xojo about it. Otherwise if it's a plugin, then the plugin vendor.

  3. Robert W

    Nov 29 Western Canada

    Thanks. I didn't know which things the IDE can catch and which it can't.

    This program is not using any declares or plug-ins.

    I suspect it may be runaway recursion in my program exceeding available memory. Would the IDE be able to detect that situation?

  4. Kem T

    Nov 29 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    Post the method or methods?

  5. Robert W

    Nov 29 Western Canada
    Edited 2 weeks ago

    You may regret this. :)
    Here is the code. See below for explanatory notes.

    Public Function SolveAllBranches(currentLevel As Integer) as Integer
      'Recursively solve puzzle
      'return values:
      '  0 = Solved
      '  1 = Exhausted all strategies
      '  2 = Encountered contradiction
      '  3 = Exceeded maximum allowable recursion depth
      '
      'If maxRecursionLevel is zero, then recursion depth is unlimited
      'Otherwise, if the current level exceeds maxRecursionLevel, this routine
      'exits with resultcode = 3.
      '
      'Track deepest recursion in this run
      deepestLevel=max(deepestLevel,currentLevel)
      'Abort if maxRecursionLevel is exceeded
      if maxRecursionLevel<>0 and currentLevel>maxRecursionLevel then
        return 3
      end if
      'Call non-recursive logic based solver 
      dim resultCode As Integer = SolveAllRules
      if resultCode <> 1 then
        'Puzzle solved, or Contradiction, or max depth exceeded
        return resultCode
      Else
        'resultCode = 1 - Logic strategies were exhausted
        'So find empty cells & do trial & error
        trialError=True 'This is used in the notes to indicate T&E was required.
        'Subsequent recursive calls will modify the a(),px(),elimCount properties
        'So they are saved here, so that they can be restored later.
        dim r,c,rTry,cTry,ct As Integer
        dim savePX(8,8) As uint64
        dim saveA(8,8) As Integer
        dim saveClr(8,8) As Color
        dim saveElimCount As Integer = elimCount
        dim cndRow(),cndCol(),cndCount() As Integer 'Empty cell list
        'Save the properties which will be changed
        for r = 0 to 8
          for c= 0 to 8
            savePX(r,c)=px(r,c)
            saveA(r,c)=a(r,c)
            saveClr(r,c)=grid(r,c).TextColor
            'If current cell is empty, add it to the empty cell list
            ct=CountCandidates(r,c)
            if ct>1  then
              'Cell is empty, so add to list
              cndRow.Append(r)
              cndCol.Append(c)
              cndCount.Append(ct)
            end if
          next
        next
        'Sort list so that cells with fewest candidates will be tested first
        cndCount.SortWith(cndRow,cndCol)
        if currentLevel=0 then
          'MsgBox str(UBound(cndRow)+1)+" trial cells."
          NotesOut "## All Logic Strategies exhausted at top level. Starting new branch level "+str(currentLevel+1)+"."+EndOfLine
        Else
          NotesOut "## All Logic Strategies exhausted at level "+str(currentLevel)+". Starting new branch level "+str(currentLevel+1)+"."+EndOfLine
        end if
        'Save the output notes here so that deadend branch notes will be pruned.
        dim saveShortlist As String = shortList
        dim saveLonglist As String = app.solveNotes
        'If maximum recursion depth is unlimited, then there is no need
        'to do more than a single iteration of the emptyCell loop.
        dim LpEnd As Integer = if(maxRecursionLevel=0,0,UBound(cndRow))
        'Try each empty cell in the list
        for emptyCell as Integer = 0 to LpEnd
          rTry=cndRow(emptyCell)
          cTry=cndCol(emptyCell)
          'if currentLevel=0 then
          'MsgBox " Trying cell: "+ CellID(rTry,cTry)+": ["+CandidateLlist(rTry,cTry)+"]"
          'end if
          NotesOut "## Choosing cells starting with those having fewest candidates: "+_
          CellID(rTry,cTry)+": ["+CandidateLlist(rTry,cTry)+"]"+EndOfLine
          '
          'Try each possible candidate for the currently selected cell
          for iCnd as integer = 0 to cndCount(emptyCell)-1
            dim candidate As Integer = NthCandidate(px(rTry,cTry),iCnd)
            saveLonglist = app.solveNotes+"## Level "+str(currentLevel+1)+", trying "+CellID(rTry,cTry)+"="+str(candidate)+": "
            SetCell(rTry,cTry,candidate)
            shortList=""
            app.solveNotes=""
            'Recursive call to solve puzzle with current trial cell value
            resultCode = SolveAllBranches(currentLevel+1)
            'Take appropriate action depending on resultCode
            select case resultCode
            case 0 'Solution found
              saveShortlist=saveShortlist+"*"+CellID(rTry,cTry)+"="+str(candidate)+", "
              'Restore output notes
              shortList=saveShortlist+shortList
              app.solveNotes=saveLonglist+" Leads to solution."+EndOfLine+"* Cell "+CellID(rTry,cTry)+"="+str(candidate)+_
              " by trial & error"+EndOfLine+app.solveNotes
              return resultCode
            case 1 'Exhausted possibilities
              'Restore output notes
              shortList=saveShortlist+shortList
              app.solveNotes=saveLonglist+app.solveNotes
              return resultCode
            case 2 'Contradiction found
              'Branch terminated in Contradiction
              saveLonglist=saveLonglist+" Leads to contradiction. Backtracking..."+EndOfLine
            case 3 'Exhausted all unfilled cells
              saveLonglist=saveLonglist+" Exceeded allowable search depth. Backtracking..."+EndOfLine
            end select
            'Result Codes 2&3 end up here.
            'Restore saved properties and try next candidate
            'Restore puzzle grid to current level
            for r=0 to 8
              for c=0 to 8
                a(r,c)=saveA(r,c)
                grid(r,c).TextColor=saveClr(r,c)
                px(r,c)=savePX(r,c)
                shortList = saveShortlist
                app.solveNotes=saveLonglist
                elimCount=saveElimCount
              next
            next
          next
          'Loop exits here if all candidates in current empty cell have been tried and have failed
          saveLonglist=saveLonglist+ "## Exhausted all candidates for cell "+CellID(rTry,cTry)+" at level "+str(currentLevel+1)+EndOfLine
          'Try next empty cell
        next
        'Loop exits here if all empty cells have been tried and failed to return a solution
        NotesOut "## Exhausted all unfilled cells at level "+str(currentLevel+1)+EndOfLine
        shortList=saveShortlist+shortList
        app.solveNotes=saveLonglist+app.solveNotes
        return resultCode 
      end if
    End Function

    This is part of my Sudoku puzzle solver. It calls another routine "SolveAllRules" which applies pure logic based rules to solve the puzzle, and returns a result code:
    0 = puzzle solved,
    1 = unable to solve puzzle using existing rules,
    2 = encountered contradiction. Puzzle has no solution.

    The routine posted here calls SolveAllRules, and if it returns result code 1 (meaning that the puzzle probably has a solution, but the logic rules were insufficient to find it), then it will successively try different values in currently empty cells, and then call itself recursively until the puzzle is solved.

    There are two modes of operation depending on the value of integer property maxRecursionLevel. If its value is zero, then the routine executes with unlimited recursion depth. If maxRecursionLevel>0 then the routine will exit when the recursion depth exceeds the value of maxRecursionLevel.

    The unlimited depth mode of operation will typically run 11 levels deep at some point, but always returns a solution. However, that means that the program must correctly guess the values of more cells than necessary in order to get a solution. Typically, the most difficult puzzles can be solved by pure logic after finding only two cell values. That is the reason for the second mode. By setting maxRecursionLevel to 2, it will exit the current level if more than two guesses are needed, and then move on to the next trial.

    Strangely, it's not the unlimited depth mode that causes the problem. That always works (usually no more than 1 second to find a solution). It's the limited depth mode that fails. The limited depth mode works in most cases (taking about 20 seconds to find a solution with maxRecursionLevel=2). But with certain puzzle data, it will run for 10-20 minutes and then crash. And this is consistent; the same puzzle always causes a crash.

  6. Kem T

    Nov 29 Pre-Release Testers, Xojo Pro, XDC Speakers New York

    Have you tried breaking into the code after, say, 30 seconds or a minute to see where it is and why it's not exiting properly?

    I think you're right, the recursion is running wild.

  7. last week

    Robert W

    Nov 29 Western Canada

    Yes, I tried breaking into the code after several minutes. It didn't appear to be doing anything that it shouldn't.

    While runaway recursion seems seems plausible on the surface, it's hard to see how it could happen here, because the second line in the routine checks the recursion depth and aborts if it's greater than the set value which is normally 2. So, I think it's more likely a loop that's not terminating. I'm going to add in a bunch of system.debug lines so I can see what it's doing when it crashes. I suspect that in the tens of minutes that it's running, the solvenotes string is growing enormously, and may be what finally causes the crash.

    I did learn something interesting. I commented out the array sort line, and then it ran fine with the troublesome data set. However, another data set that had previously worked now causes a crash. So, it seems to have something to do with the order in which cells are processed.

or Sign Up to reply!