From: SourceForge.net <no...@so...> - 2010-05-29 12:07:27
|
Bugs item #3008307, was opened at 2010-05-28 13:11 Message generated for change (Comment added) made by coldstore You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=3008307&group_id=10894 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: 60. NRE and coroutines Group: None Status: Open Resolution: None Priority: 9 Private: No Submitted By: Colin McCormack (coldstore) Assigned to: miguel sofer (msofer) Summary: stack corruption Initial Comment: The following code introduces stack corruption: proc bottomp {y} { after 0 top 1 yield } proc topp {x} { coroutine bottom bottomp 2 after 0 bottom 3 yield } coroutine top topp 1 set done 0 vwait done As follows: PUSH : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 TclGetNamespaceForQualName: PUSH : 0x8821058 0x881ae48 TclGetNamespaceForQualName: DELETING 0x8821058 POP : 0x881ae48 NamespaceEvalCmd: PUSH : 0x8821318 0x881ae48 NsEval_Callback: DELETING 0x8821318 POP : 0x881ae48 NamespaceEvalCmd: PUSH : 0x8821318 0x881ae48 NsEval_Callback: DELETING 0x8821318 POP : 0x881ae48 NamespaceEvalCmd: PUSH : 0x8821318 0x881ae48 NsEval_Callback: DELETING 0x8821318 POP : 0x881ae48 TclProcCompileProc: PUSH : 0x8821318 0x881ae48 TclProcCompileProc: DELETING 0x8821318 POP : 0x881ae48 PushProcCallFrame: PUSH : 0x8821318 0x881ae48 NamespaceEvalCmd: PUSH : 0x88214d8 0x8821318 0x881ae48 NamespaceEvalCmd: PUSH : 0x8821580 0x88214d8 0x8821318 0x881ae48 NsEval_Callback: DELETING 0x8821580 POP : 0x88214d8 0x8821318 0x881ae48 NsEval_Callback: DELETING 0x88214d8 POP : 0x8821318 0x881ae48 NamespaceEvalCmd: PUSH : 0x8821540 0x8821318 0x881ae48 NsEval_Callback: DELETING 0x8821540 POP : 0x8821318 0x881ae48 InterpProcNR2: POP : 0x881ae48 InterpProcNR2: DELETING 0x8821318 TclNRCoroutineObjCmd save caller: 0x883def8 SAVE : 0x881ae48 TclProcCompileProc: PUSH : 0x8840470 0x881ae48 TclProcCompileProc: DELETING 0x8840470 POP : 0x881ae48 PushProcCallFrame: PUSH : 0x8840470 0x881ae48 TclNRCoroutineObjCmd save caller: 0x8848e90 SAVE : 0x8840470 0x881ae48 TclProcCompileProc: PUSH : 0x883fc70 0x8840470 0x881ae48 TclProcCompileProc: DELETING 0x883fc70 POP : 0x8840470 0x881ae48 PushProcCallFrame: PUSH : 0x883fc70 0x8840470 0x881ae48 NRCoroutineCallerCallback save running: 0x8848e90 SAVE : 0x883fc70 0x8840470 0x881ae48 NRCoroutineCallerCallback restore caller: 0x8848e90 RESTORE : 0x8840470 0x881ae48 NRCoroutineCallerCallback save running: 0x883def8 SAVE : 0x8840470 0x881ae48 NRCoroutineCallerCallback restore caller: 0x883def8 RESTORE : 0x881ae48 NRInterpCoroutine save caller: 0x883def8 SAVE : 0x881ae48 NRInterpCoroutine restore running: 0x883def8 RESTORE : 0x8840470 0x881ae48 InterpProcNR2: POP : 0x881ae48 InterpProcNR2: DELETING 0x8840470 NRCoroutineExitCallback restore caller 0x883def8 RESTORE : 0x881ae48 NRInterpCoroutine save caller: 0x8848e90 SAVE : 0x881ae48 NRInterpCoroutine restore running: 0x8848e90 RESTORE : 0x883fc70 0x8840470 0xfffffff9Segmentation fault ---------------------------------------------------------------------- >Comment By: Colin McCormack (coldstore) Date: 2010-05-29 22:07 Message: I see. If the legally freed stack allocation has been placed on the stack, then it has been placed on the stack with the pointer to the next element in the stack uninitialized from the value it was assigned immediately before it was freed. So even if this were the case, it simply means there's a different bug - specifically that something is being inserted onto the stack (without passing through PUSH) without its next pointer initialized. Generation counting would, in either case enumerated, avail us nothing. ---------------------------------------------------------------------- Comment By: Alexandre Ferrieux (ferrieux) Date: 2010-05-29 20:10 Message: No, I did not say refcounting, but generation counting. That is, a kind of timestamp that is incremented on each CF allocation, and stored in one new field of them. So that, when in your debugging printfs you display a frame pointer (and associated gen count), you can tell whether you are looking at a stale frame or at a new one that just happens to reuse the same address (legally freed) as suggested by Miguel. ---------------------------------------------------------------------- Comment By: Colin McCormack (coldstore) Date: 2010-05-29 10:26 Message: Given that we believe stacks should never share elements, but we have evidence that they are, all refcounting would do at this stage is convert a segv into a leak with the added disutility of exposing frames which should not be visible to uplevel. ---------------------------------------------------------------------- Comment By: Alexandre Ferrieux (ferrieux) Date: 2010-05-29 07:01 Message: Then maybe adding a generation count field could tell them apart; ---------------------------------------------------------------------- Comment By: miguel sofer (msofer) Date: 2010-05-28 21:08 Message: Note that recreating 'bottom' at each go may well create some confusing ouput here: the callFrame for bottomp's body (and bottom's base CF) will be popped when the old version is rewinded, then the new CFs will be created at the same address - ie, at the precise same spot in Tcl's execution stack. Depending on the details of the instrumentation, this could appear to be 'reusing a popped CF'. ---------------------------------------------------------------------- Comment By: miguel sofer (msofer) Date: 2010-05-28 20:58 Message: Note that 'topp' recreates the 'bottom' coroutine at each go. What will be happening here is: 1. 'top' starts, creates 'bottom', sets 'bottom' to be called from the evloop and yields 2. 'bottom starts, sets 'top' to be called from the evloop and yields 3. 'top' starts, creates a NEW 'bottom (thus killing the suspended 'bottom'), sets 'bottom' to be called from the evloop and yields 4. goto 2 ---------------------------------------------------------------------- Comment By: miguel sofer (msofer) Date: 2010-05-28 20:51 Message: Could you please post the instrumenting code that produces that output? ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=3008307&group_id=10894 |