Le 13/11/2017 à 14:08, Ben Coman a écrit :


On Mon, Nov 13, 2017 at 8:40 PM, Thomas Dupriez <[email protected] <mailto:[email protected]>> wrote:

    I dug a bit in this issue. Here are the results:


    # Problem raised by Stephanne
    Code like the following is open in the debugger:

        `myMethod
            1+1. <PROGRAMCOUNTER>
            MyClass new myEvalBlock: [
                2+2. <CURSOR>
            ].
            3+3.`

    The program counter is on the 1+1, the cursor is at the end of the
    2+2 line.
    Right-click, "Run to here".
    -> the program counter moves to the 3+3, and does not stop at the
    2+2 (where the cursor is). Even though the 2+2 does get evaluated
    (the myEvalBlock method evaluates the blocks it receives).
    If there was no code after the block, the debugger would jump back
    to the caller of myMethod.

    # Why this happens
    The implementation of RunToHere (source code below) is basically
    to stepOver until the context is different or the source code
    position of the program counter is higher or equal to the source
    code position of the cursor/selection.

    Since the debugger uses stepOver, it executes myEvalBlock without
    stopping, reaches the 3+3 and see it has gone further than the
    source code position of the cursorm so it stops.

    Source code of DebugSession>>#runToSelection:inContext:

        `runToSelection: selectionInterval inContext: aContext
            "Attempt to step over instructions in selectedContext
    until the
            execution reaches the selected instruction. This happens
    when the
            program counter passes the begining of selectionInterval.

            A not nill and valid interval is expected."

            (self pcRangeForContext: aContext) first >=
    selectionInterval first
                ifTrue: [ ^self ].
            self stepOver: aContext.
            [ aContext == self interruptedContext and: [ (self
    pcRangeForContext: aContext) first < selectionInterval first ] ]
                whileTrue: [ self stepOver: aContext ]`

    # Observations and thoughts
    - Replacing the stepOver with a stepInto -> This made the
    RunToHere stops when resolving the 'new' message (because the
    context changes).


Thanks for looking into this Thomas.
What happens if you use stepThrough rather than stepInto?

cheers -ben

Using `stepThrough: aContext` instead of `stepInto: aContext`, the RunToHere in the block stops at the intended place: the 2+2. Printing the sequence of `self pcRangeForContext: aContext` yields the following. It doesn't show precisely the stop in the block, and instead shows an interval encompassing the whole block. That's what I was using to see where the execution was going during the RunToHere loop so I guess that's not a precise enough indicator for this situation...
(21 to: 22)(34 to: 36)(49 to: 60)(38 to: 60)(38 to: 60)

I also tried the case where the block does not get evaluated (changing myEvalBlock so that it does nothing). In this situation, the RunToHere with a stepThrough ends up at the intended place, the 3+3.

So... just use stepThrough for the RunToHere I guess?

Thomas


    - Replacing the stepOver with stepInto and removing the equal
    condition on contexts -> The RunToHere goes to the 3+3. Looking at
    the source code position of the program counter, it doesn't enter
    the block and seems to resolve it in a single step. I don't really
    get why that is, considering using the stepInto button of the
    debugger does enter the block. Here is the series of source code
    positions of the program counter during the RunToHere: (21 to:
    22)(34 to: 36)(34 to: 36)(49 to: 60)(38 to: 60)(38 to: 60)(65 to: 66).
    However, removing the equal condition on contexts means that if
    the method call returns before reaching the cursor, it won't stop!

    - An idea could be to have the RunToHere place a metalink on the
    selected node and let the execution run until it hits the
    metalink, which then updates the debugger. Potential problems are
    that it implies installing a metalink on a method that is already
    on the stack, which may not be that easy to do properly (in
    particular, it affects the program counter since it changes the
    bytecode), and there is the potential case where the metalink is
    never reached (for example imagine the myEvalBlock: method of my
    example is just storing the block and not evaluating it).


    Cheers,
    Thomas



    Le 09/11/2017 à 22:06, Stephane Ducasse a écrit :

        Agreed. Thomas? It would be a good bone to ... (Un bon os a
        ronger) .

        Stef

        On Thu, Nov 9, 2017 at 4:32 AM, Tudor Girba
        <[email protected] <mailto:[email protected]>> wrote:

            Hi,

            The basic tools, such as debugger, are expected to work.
            If something does not work, it’s a bug.

            Cheers,
            Doru


                On Nov 8, 2017, at 11:59 PM, Tim Mackinnon
                <[email protected]> wrote:

                I think it's broken in Pharo 6 too, as I often find it
                unreliable.

                It's hard to know what should work anymore - we really
                need a stabilisation release to let the dust settle.

                I'm always a bit reticent to report things as I'm not
                sure what you expect to work.

                Tim

                Sent from my iPhone

                    On 8 Nov 2017, at 20:40, Stephane Ducasse
                    <[email protected]
                    <mailto:[email protected]>> wrote:

                    Hi

                    I have the following method and I have my cursor
                    -MY CURSOR HERE-
                    I select the menu run to here and .... I exit the
                    method.
                    :(

                    Is run to here working in Pharo 70?
                    I start to get worry about the number of bugs I
                    get when using Pharo70.

                    Stef


                    fileOut
                    "File out the receiver, to a file whose name is a
                    function of the
                    change-set name and a unique numeric tag."

                    | nameToUse |
                    self halt.
                    self class
                    promptForDefaultChangeSetDirectoryIfNecessary.
                    nameToUse := (self defaultChangeSetDirectory /
                    self name , 'cs')
                    nextVersion basename.
                    UIManager default
                    showWaitCursorWhile:
                    [
                    | internalStream |
                    internalStream := (String new: 10000) writeStream.

                    -MY CURSOR HERE-

                    internalStream
                    header;
                    timeStamp.
                    self fileOutPreambleOn: internalStream.
                    self fileOutOn: internalStream.
                    self fileOutPostscriptOn: internalStream.
                    CodeExporter
                    writeSourceCodeFrom: internalStream
                    baseName: (nameToUse copyFrom: 1 to: nameToUse
                    size - 3)
                    isSt: false ]


            --
            www.tudorgirba.com <http://www.tudorgirba.com>
            www.feenk.com <http://www.feenk.com>

            "Value is always contextual."









Reply via email to