diff -r 6efae6456f14 -r 213e436320fe GDBThread.st --- a/GDBThread.st Sat Sep 01 00:16:15 2018 +0100 +++ b/GDBThread.st Sat Sep 01 00:24:11 2018 +0100 @@ -96,77 +96,84 @@ self ensureIsStopped. stack isNil ifTrue:[ stack := GDBTransientDataHolder debugger: debugger factory:[ :old | - | result depth new oldFrameIndex oldFrame newFrameIndex newFrame | - result := debugger send: (GDBMI_stack_info_depth new arguments: (Array with: '--thread' with: id with: 100)). - depth := result propertyAt: #depth. - result := debugger send: (GDBMI_stack_list_frames new arguments: (Array with: '--thread' with: id with: 0 with: depth - 1 )). - new := result propertyAt: #stack. + [ + | result depth new oldFrameIndex oldFrame newFrameIndex newFrame | + + result := debugger send: (GDBMI_stack_info_depth new arguments: (Array with: '--thread' with: id with: 100)). + depth := result propertyAt: #depth. + result := debugger send: (GDBMI_stack_list_frames new arguments: (Array with: '--thread' with: id with: 0 with: depth - 1 )). + new := result propertyAt: #stack. - "/ Now, walk from the bottom of the stack (the least recent frame) and - "/ ipdate `new` array with frames from `old` array to preserve the - "/ identity. - newFrameIndex := new size. - oldFrameIndex := old size. - [ newFrameIndex > 0 and:[ oldFrameIndex > 0 ] ] whileTrue:[ - newFrame := new at: newFrameIndex. - oldFrame := old at: oldFrameIndex. - "/ If frame addrs matches, both frames really represent the same thing so - "/ just replace the 'new' frame with the 'old'. - newFrame addr = oldFrame addr ifTrue:[ - "/ OK, the two frames are really the same thing - oldFrame setLevel: newFrame level. "/ Update level - new at: newFrameIndex put: (old at: oldFrameIndex). + "/ Now, walk from the bottom of the stack (the least recent frame) and + "/ ipdate `new` array with frames from `old` array to preserve the + "/ identity. + newFrameIndex := new size. + oldFrameIndex := old size. + [ newFrameIndex > 0 and:[ oldFrameIndex > 0 ] ] whileTrue:[ + newFrame := new at: newFrameIndex. + oldFrame := old at: oldFrameIndex. + "/ If frame addrs matches, both frames really represent the same thing so + "/ just replace the 'new' frame with the 'old'. + newFrame addr = oldFrame addr ifTrue:[ + "/ OK, the two frames are really the same thing + oldFrame setLevel: newFrame level. "/ Update level + new at: newFrameIndex put: (old at: oldFrameIndex). + newFrameIndex := newFrameIndex - 1. + oldFrameIndex := oldFrameIndex - 1. + ] ifFalse:[ + "/ No, frame pc differs. This is the first time they differ so + "/ it could be the same frame just on different PC (since PC of + "/ caller did not change). Subsequent frames could also be "same" + "/ if they're inlined into caller - in this case, the PC (#addr) of + "/ the caller frame and inlined callee are the same. + "/ + "/ So, we update subsequent frames as long as + "/ a) function names are the same AND + "/ b) PC is the same as PC of its caller + "/ + "/ Complicated, isn't it? + | oldAddr newAddr | + oldAddr := oldFrame addr. + newAddr := newFrame addr. + [ newFrameIndex > 0 and:[ oldFrameIndex > 0 ] ] whileTrue:[ + newFrame := new at: newFrameIndex. + oldFrame := old at: oldFrameIndex. + ("a)"oldFrame func = newFrame func and: ["b)"oldFrame addr = oldAddr and:[newFrame addr = newAddr]]) ifTrue:[ + "/ Update the frame... + oldFrame setAddr: newFrame addr. + oldFrame setLine: newFrame line. + oldFrame setLevel: newFrame level. + new at: newFrameIndex put: (old at: oldFrameIndex). + newFrameIndex := newFrameIndex - 1. + oldFrameIndex := oldFrameIndex - 1. + ] ifFalse:[ + "/ Terminate the loop, see the condition above. + oldFrameIndex := 0. + ]. + ] + ]. + ]. + "/ For the remaining really new frames, set the debugger + "/ and the thread. + [ newFrameIndex > 0 ] whileTrue:[ + newFrame := new at: newFrameIndex. + newFrame setDebugger: debugger. + newFrame setThread: self. newFrameIndex := newFrameIndex - 1. - oldFrameIndex := oldFrameIndex - 1. - ] ifFalse:[ - "/ No, frame pc differs. This is the first time they differ so - "/ it could be the same frame just on different PC (since PC of - "/ caller did not change). Subsequent frames could also be "same" - "/ if they're inlined into caller - in this case, the PC (#addr) of - "/ the caller frame and inlined callee are the same. - "/ - "/ So, we update subsequent frames as long as - "/ a) function names are the same AND - "/ b) PC is the same as PC of its caller - "/ - "/ Complicated, isn't it? - | oldAddr newAddr | - oldAddr := oldFrame addr. - newAddr := newFrame addr. - [ newFrameIndex > 0 and:[ oldFrameIndex > 0 ] ] whileTrue:[ - newFrame := new at: newFrameIndex. - oldFrame := old at: oldFrameIndex. - ("a)"oldFrame func = newFrame func and: ["b)"oldFrame addr = oldAddr and:[newFrame addr = newAddr]]) ifTrue:[ - "/ Update the frame... - oldFrame setAddr: newFrame addr. - oldFrame setLine: newFrame line. - oldFrame setLevel: newFrame level. - new at: newFrameIndex put: (old at: oldFrameIndex). - newFrameIndex := newFrameIndex - 1. - oldFrameIndex := oldFrameIndex - 1. - ] ifFalse:[ - "/ Terminate the loop, see the condition above. - oldFrameIndex := 0. - ]. - ] ]. + new + ] on: GDBError do:[ :ex | + self isRunning ifFalse:[ + ex pass. + ]. + old. ]. - "/ For the remaining really new frames, set the debugger - "/ and the thread. - [ newFrameIndex > 0 ] whileTrue:[ - newFrame := new at: newFrameIndex. - newFrame setDebugger: debugger. - newFrame setThread: self. - newFrameIndex := newFrameIndex - 1. - ]. - new ]. ]. ^ stack value "Created: / 09-09-2014 / 00:02:45 / Jan Vrany " - "Modified: / 06-08-2018 / 15:57:10 / Jan Vrany " - "Modified (comment): / 07-08-2018 / 08:44:37 / Jan Vrany " + "Modified: / 01-09-2018 / 00:11:19 / Jan Vrany " ! status