Here's a case where just adding a breakpoint to a method makes the
method do something entirely different. This makes debugging rather more difficult than it should be, so I consider it a fairly serious bug. Below I list the decompiled version of the method before and after setting the breakpoint. Note that, besides inserting the CodeProbe, the whileTrue: has beome an ifTrue:, and the ifFalse: has become a whileFalse:. As a result, the method only goes through its loop once and then returns, when it should go through the loop tableSize times. I've attached a filein that contains a method that can be used to reproduce the problem. To reproduce, file it in, then set a breakpoint at the point indicated below, then inspect the method and look at the differences in the decompiled version. -Martin ------- The original method, decompiled, with a comment where the breakpoint goes: basicClearForSession: t1 | t2 t3 t4 t5 t6 t7 t8 | t4 := 0. t5 := 1. t6 := tableSize. [t5 <= t6] whileTrue: [t2 := self valueAt: t5. ((t3 := self keyAt: t5) == nil or: [nil == t2]) ifFalse: [nil == (t7 := t2 forSession: t1) ifFalse: [t7 setDeadSession]. nil == (t8 := t2 notForSession: t1) ifTrue: [t3 gbxIsProxy ifTrue: [t4 := t4 + 1] ifFalse: [self dirtyDisable: t3 forValue: t2. keys at: t5 put: nil. values at: t5 put: nil. self removedKey: t3 value: t2]] ifFalse: [ "Put breakpoint here" values at: t5 put: t8. t4 := t4 + 1]]. t5 := t5 + 1]. ^t4 -------------- The decompiled method after adding breakpoint: basicClearForSession: t1 | t2 t3 t4 t5 t6 t7 t8 | t4 := 0. t5 := 1. t6 := tableSize. t5 <= t6 ifTrue: [ [t2 := self valueAt: t5. (t3 := self keyAt: t5) == nil or: [nil == t2]] whileFalse: [nil == (t7 := t2 forSession: t1) ifFalse: [t7 setDeadSession]. nil == (t8 := t2 notForSession: t1) ifTrue: [t3 gbxIsProxy ifTrue: [t4 := t4 + 1] ifFalse: [self dirtyDisable: t3 forValue: t2. keys at: t5 put: nil. values at: t5 put: nil. self removedKey: t3 value: t2]] ifFalse: [(CraftedSmalltalk.CodeProbe) actOn: thisContext. values at: t5 put: t8. t4 := t4 + 1. t5 := t5 + 1]]]. ^t4 <?xml version="1.0"?> <st-source> <time-stamp>From VisualWorks®, 7.4 of December 5, 2005 on January 30, 2006 at 5:29:41 pm</time-stamp> <class> <name>CodeProbeBug</name> <environment>Smalltalk</environment> <super>Core.Object</super> <private>false</private> <indexed-type>none</indexed-type> <inst-vars>tableSize keys values </inst-vars> <class-inst-vars></class-inst-vars> <imports></imports> <category>(none)</category> <attributes> <package>(none)</package> </attributes> </class> <methods> <class-id>CodeProbeBug</class-id> <category>bug</category> <body package="(none)" selector="basicClearForSession:">basicClearForSession: t1 | t2 t3 t4 t5 t6 t7 t8 | t4 := 0. t5 := 1. t6 := tableSize. [t5 <= t6] whileTrue: [t2 := self valueAt: t5. ((t3 := self keyAt: t5) == nil or: [nil == t2]) ifFalse: [nil == (t7 := t2 forSession: t1) ifFalse: [t7 setDeadSession]. nil == (t8 := t2 notForSession: t1) ifTrue: [t3 gbxIsProxy ifTrue: [t4 := t4 + 1] ifFalse: [self dirtyDisable: t3 forValue: t2. keys at: t5 put: nil. values at: t5 put: nil. self removedKey: t3 value: t2]] ifFalse: [values at: t5 put: t8. t4 := t4 + 1]]. t5 := t5 + 1]. ^t4</body> </methods> </st-source> |
At 09:09 PM 1/30/2006, Martin McClure wrote:
>Here's a case where just adding a breakpoint to a method makes the method do something entirely different. This makes debugging rather more difficult than it should be, so I consider it a fairly serious bug. Thanks. I've created this as AR 50230. -- Alan Knight [|], Cincom Smalltalk Development [hidden email] [hidden email] http://www.cincom.com/smalltalk "The Static Typing Philosophy: Make it fast. Make it right. Make it run." - Niall Ross |
In reply to this post by Martin McClure
Martin
I will look at it more closely, however, at first glance it looks like the jump back at the end of the loop got messed up. Furthermore, when trying to figure out if a probed method is correct it is best to look at the bytecodes. The decompiler does not always decompile it correctly. You can create a bytecode sequence by putting in a probe that cannot be generated by legal smalltalk. Terry =========================================================== Terry Raymond Smalltalk Professional Debug Package Crafted Smalltalk 80 Lazywood Ln. Tiverton, RI 02878 (401) 624-4517 [hidden email] <http://www.craftedsmalltalk.com> =========================================================== > -----Original Message----- > From: Martin McClure [mailto:[hidden email]] > Sent: Monday, January 30, 2006 9:10 PM > To: VWNC > Subject: [BUG] 7.4 -- Adding breakpoint seriously screws up control > structures in method > > Here's a case where just adding a breakpoint to a method makes the > method do something entirely different. This makes debugging rather more > difficult than it should be, so I consider it a fairly serious bug. > > Below I list the decompiled version of the method before and after > setting the breakpoint. Note that, besides inserting the CodeProbe, the > whileTrue: has beome an ifTrue:, and the ifFalse: has become a > whileFalse:. > > As a result, the method only goes through its loop once and then > returns, when it should go through the loop tableSize times. > > I've attached a filein that contains a method that can be used to > reproduce the problem. To reproduce, file it in, then set a breakpoint > at the point indicated below, then inspect the method and look at the > differences in the decompiled version. > > -Martin > |
Free forum by Nabble | Edit this page |