[Pharo-dev] Processor>>activeProcess is wrong when a process is stepped by a forked process

2020-01-21 Thread Thomas Dupriez

Hello

Some time ago, I've stumbled upon a challenging bug in pharo. I tried 
some things, but this bug still eludes me. Maybe someone here has an idea?


The bug is that the value of `Processor activeProcess` is wrong inside a 
process being stepped by a forked process.


In other words, let's say process D is the (frozen) process I am 
debugging, and its code is to store the active process into some 
variable with `p := Processor activeProcess`:
- If I step process D normally (with `D step`), then p is correct and 
worth process D
- If I fork to create a process F that steps process D, then p is 
incorrect and worth process F


You will find below the code of the two tests I am using to show the 
bug, as well as a condensed version of my findings so far. If you have 
any idea or lead as to where this bug could come from, I would be very 
grateful.


Thomas Dupriez

-

Here is the code of the failing test, where process F steps process D:

```
/testActiveProcessInProcessSteppedInForkedProcess//
//| s p D done |//
//    s := Semaphore new. done := false.//
//    "Create debugged process"//
//    D := [p := Processor activeProcess. done := true] newProcess name: 
'D'; yourself.//
//    "Until the execution of the debugged process is over, create a 
forked process to step it"//

//    [done]//
//        whileFalse: [ //
//            [debuggedProcess step. s signal] forkNamed: 'F'.//
//            s wait.//
//        ].//
//    self assert: D identicalTo: p/
```

And here is the passing test, where we step process D directly:

```
/testActiveProcessInProcessDirectlyStepped//
//| s p D done |//
//    s := Semaphore new. done := false.//
//    "Create debugged process"//
//    D := [p := Processor activeProcess. done := true] newProcess name: 
'D'; yourself.//
//    "Until the execution of the debugged process is over, step it 
directly"//

//    [done]//
//        whileFalse: [ //
//            debuggedProcess step.//
//        ].//
//    self assert: D identicalTo: p/
```

-

Here are my findings so far:

The call chain of Process>>step is:
- Process>>step
- which calls Process>>evaluate:onBehalfOf:
- which calls BlockClosure>>ensure:
- which calls BlockClosure>>valueNoContextSwitch

1) Replacing the call to BlockClosure>>valueNoContextSwitch with a call 
to BlockClosure>>value does not affect the results of the test


2) Since #valueNoContextSwitch is a primitive, it cannot be instrumented 
easily. I instrumented right before and after it gets called in the code 
of BlockClosure>>ensure to check the value of active process. No wrong 
value there, so the problem appears inside the execution of 
#valueNoContextSwitch, and it disappears before this method call returns.


3) The block being evaluated by #valueNoContextSwitch contains a call to 
Context>>step, which ultimately calls 
InstructionStream>>interpretNextV3PlusClosureInstructionFor: (the method 
that read what the next bytecode is and applies it to the execution it 
is stepping. I instrumented this method to log the name of the active 
process, and the context being stepped during the execution of both 
tests. The log show a difference between the passing and failing test:
- Passing test: the active process is D for a long time, then 'Test 
execution watch dog" for a bit, and finally, it is "Morphic UI Process". 
So everything looks in order: the active process is D until the test 
ends and the UI process takes control back
- Failing test: The logged active process alternates between F and D, 
and looks like this: (I put some F D patterns in bold for readability) 
*F D* F D *F D*.*F D* F F D F F *F D* F D *F D*...*F D* D D D D r M 
M M M...
"M" is the morphic UI Process, "r" is a seemingly random process whose 
name is "1006977792" in the log. I also logged the ast nodes being 
stepped, but I don't really know how to exploit it.


4) I did some experiments by tweaking the tests and changing which 
process creates D, which process steps F...and had surprising results:

4-1) Original failing test
a

In the original failing test, the test process creates the debugged 
process and a fork, and the fork steps the debugged process (blue 
arrow). This test fails.

4-2) Original passing test
a

In the original passing test, the test process creates the debugged 
process and steps it. This test passes.

4-3) Forked process creates AND steps the debugged process
a
If the forked process is the one to create the debugged process, the 
test passes!

4-4) /Forked process creates the debugged process, and TestProcess steps it/
a
So maybe the test passes whenever the debugged process is a descendant 
of the process stepping it? No, 4-5) shows that it is not necessary.
4-5) /A forked process creates the debugged process. Another forked 
process steps the debugged process

/a




Re: [Pharo-dev] Breakpoint restart error

2019-08-05 Thread Thomas Dupriez

Hi ben,

If you don't touch the new error and keep stepping over in the original 
debugger, it does not get confused. It's not really a "solution" though, 
merely an observation.



The issue is not related to the restart. It comes from stepping over a 
message with a breakpoint.
For example, if you also set a breakpoint on the "b := 2" node and step 
over it, there is the same issue. Example code:


Object compile: 'myTest2
  |a b c|
  a := 1.
  b := 2.
  c := 3'.
Breakpoint new node: (Object>>#myTest2) ast; install.
Breakpoint new node: (Object>>#myTest2) ast children first statements 
second; install. "Installing breakpoint on node b := 2"

Object new myTest2.
", ,  -> issue"


In your example, here's what happens:
- you run the test
- the breakpoint triggers, and stops the execution
- you step over two times
- you restart, which means the next code to be executed is now the 
breakpoint that was inserted at the start of the test method

- you step over a breakpoint, which causes the issue.

A very similar issue occurs when stepping over a 'self halt'.

Cheers,
Thomas

On 04/08/2019 17:09, Ben Coman wrote:
I trying to set a breakpoint programatically so that users can be 
dropped into the custom script they can add to a system. I try...


Object compile: 'myTest
  |a b c|
  a := 1.
  b := 2.
  c := 3'.
Breakpoint new node: (Object>>#myTest) ast; install.
Object new myTest.
"click      "

but the following error appears and the debugger gets confused...
image.png

What am I doing wrong?

cheers -ben


Re: [Pharo-dev] Request-info bot on github

2019-03-26 Thread Thomas Dupriez

Ok. I wrote a new comment and another bot removed the label. :)

Thomas

On 26/03/2019 17:11, Marcus Denker wrote:

I think you should not edit but put a new comment. The bot seems to only get to 
see new comments, not edit actions of existing comments.


On 26 Mar 2019, at 17:06, Thomas Dupriez  wrote:

Hello, just asking if this behaviour is normal:

- I created an issue with an empty body.
- The request-info bot posted a message to it, saying it was empty and asking for more 
details. It also added the "more-information-needed" label.
- I updated the body of the issue
- Now the issue no longer has an empty body, but it still has the message from 
the bot and the label.

The issue in question: https://github.com/pharo-project/pharo/issues/3025

Thomas








[Pharo-dev] Request-info bot on github

2019-03-26 Thread Thomas Dupriez

Hello, just asking if this behaviour is normal:

- I created an issue with an empty body.
- The request-info bot posted a message to it, saying it was empty and 
asking for more details. It also added the "more-information-needed" label.

- I updated the body of the issue
- Now the issue no longer has an empty body, but it still has the 
message from the bot and the label.


The issue in question: https://github.com/pharo-project/pharo/issues/3025

Thomas




[Pharo-dev] Questions about DebugSession>>isContextPostMortem:

2019-03-21 Thread Thomas Dupriez

Hello,

While looking at the DebugSession>>isContextPostMortem: method (code 
below), I got three questions:


1) There is a check for whether the suspendedContext (top context) of 
the process is nil. Does it even make sense for a process not to have 
any top context?


2) It seems that all the last 3 lines are doing is to check whether 
selectedContext is in the context chain of the process. Could they be 
rewritten into this simpler one-liner?   `|^ (suspendedContext 
hasContext: selectedContext) not`|


3) Overall, this method says that a context C is "post mortem" if the 
process controlled by the DebugSession has a top context and C is not in 
its context chain. That's the practical definition. Could someone shed 
some light on the high-level definition of "post mortem"? Because "post 
mortem" is like "after death", but the death of what? A context that 
merely belongs to another context chain would be considered "post 
mortem" by the practical definition, but there's no death in this case...

||


```

|DebugSession>>isContextPostMortem: selectedContext "return whether 
we're inspecting a frozen exception without a process attached" | 
suspendedContext | suspendedContext := interruptedProcess 
suspendedContext. suspendedContext ifNil: [ ^ false ]. (suspendedContext 
== selectedContext) ifTrue: [ ^ false ]. ^ (suspendedContext 
findContextSuchThat: [:c | c sender == selectedContext]) isNil ``` |


Does someone know the answer to some (or all) of these questions?

Thomas



Re: [Pharo-dev] looking for an author of a Beginning Pharo or related

2019-03-01 Thread Thomas Dupriez

Hello,

The timing of this mail is interesting, because just yesterday I 
stumbled on the "Free Software Needs Free Documentation" preface of the 
GDB documentation.


It's a dozen paragraph so not exactly a short read, but the gist of it 
is that the author urges other authors to use free documentation 
licenses for the documentations/manuals they are writing, so that they 
can be modified and grown by the community along with the free software 
they talk about.


I've attached the full version if some people are interested in reading it.

Sorry for this tangent, Stéphane. The timing was just too perfect. :)

Thomas

On 01/03/2019 08:09, Stéphane Ducasse wrote:

Hi guys

We have been contacted by a (good) editor that would like to publish 
on Beginning Pharo or related.
I have a lot of material that I can give but no energy to write such 
book :)


If one of you in interested, let me know. I could even be a co-author.

Stef



Stéphane Ducasse
http://stephane.ducasse.free.fr
http://www.synectique.eu / http://www.pharo.org
03 59 35 87 52
Assistant: Julie Jonas
FAX 03 59 57 78 50
TEL 03 59 35 86 16
S. Ducasse - Inria
40, avenue Halley,
Parc Scientifique de la Haute Borne, Bât.A, Park Plaza
Villeneuve d'Ascq 59650
France

Free Software Needs Free Documentation

The biggest deficiency in the free software community today is not in the 
software—it is the lack of good free documentation that we can include with the 
free software. Many of our most important programs do not come with free 
reference manuals and free introductory texts. Documentation is an essential 
part of any software package; when an important free software package does not 
come with a free manual and a free tutorial, that is a major gap. We have many 
such gaps today.
Consider Perl, for instance. The tutorial manuals that people normally use are 
non-free. How did this come about? Because the authors of those manuals 
published them with restrictive terms—no copying, no modification, source files 
not available—which exclude them from the free software world.
That wasn’t the first time this sort of thing happened, and it was far from the 
last. Many times we have heard a GNU user eagerly describe a manual that he is 
writing, his intended contribution to the community, only to learn that he had 
ruined everything by signing a publication contract to make it non-free.
Free documentation, like free software, is a matter of freedom, not price. The 
problem with the non-free manual is not that publishers charge a price for 
printed copies—that in itself is fine. (The Free Software Foundation sells 
printed copies of manuals, too.) The problem is the restrictions on the use of 
the manual. Free manuals are available in source code form, and give you 
permission to copy and modify. Non-free manuals do not allow this.
The criteria of freedom for a free manual are roughly the same as for free 
software. Redistribution (including the normal kinds of commercial 
redistribution) must be permitted, so that the manual can accompany every copy 
of the program, both on-line and on paper.
Permission for modification of the technical content is crucial too. When 
people modify the software, adding or changing features, if they are 
conscientious they will change the manual too—so they can provide accurate and 
clear documentation for the modified program. A manual that leaves you no 
choice but to write a new manual to document a changed version of the program 
is not really available to our community.
Some kinds of limits on the way modification is handled are acceptable. For 
example, requirements to preserve the original author’s copyright notice, the 
distribution terms, or the list of authors, are ok. It is also no problem to 
require modified versions to include notice that they were modified. Even 
entire sections that may not be deleted or changed
are acceptable, as long as they deal with nontechnical topics (like this one). 
These kinds of restrictions are acceptable because they don’t obstruct the 
community’s normal use of the manual.
However, it must be possible to modify all the technical content of the manual, 
and then distribute the result in all the usual media, through all the usual 
channels. Otherwise, the restrictions obstruct the use of the manual, it is not 
free, and we need another manual to replace it.
Please spread the word about this issue. Our community continues to lose 
manuals to proprietary publishing. If we spread the word that free software 
needs free reference manuals and free tutorials, perhaps the next person who 
wants to contribute by writing documentation will realize, before it is too 
late, that only free manuals contribute to the free software community.
If you are writing documentation, please insist on publishing it under the GNU 
Free Documentation License or another free documentation license. Remember that 
this decision requires your approval—you don’t have to 

[Pharo-dev] ProcessBrowser does not auto-update itself by default? Should it?

2019-02-04 Thread Thomas Dupriez

Hello,

The Process Browser does not auto-updates itself by default to show new 
processes and hide processes that stopped.


Is there a specific reason for that? The first time I opened it I kind 
of expected it would auto-update itself, and I think this may be a more 
"intuitive" behaviour that no auto-updates by default. What do you think?


Getting auto-updates is "easy" (there is no button in the UI (something 
to improve?), but one can call the "toggleAutoUpdate" method to get this 
behaviour). My question is about it not being default.


Thomas




[Pharo-dev] Debugger opening on user halt and not Object>>halt

2019-01-30 Thread Thomas Dupriez

Hello,

Does someone know which is the code responsible for the debugger opening 
on the halt of the user instead of Object>>halt (see picture)? It's neat 
but it's not the regular behaviour so I'm guessing it is handled 
somewhere specifically for halt messages?



Thomas



Re: [Pharo-dev] DebugSession>>activePC:

2019-01-11 Thread Thomas Dupriez via Pharo-dev
--- Begin Message ---
Yeah, it's a bit unfortunate you assumed I wanted to remove the method. 
It brought up a not so pleasant discussion.

Everyone makes mistakes. :-)

So if I understand, this method gives the pc that maps to the ast node 
the debugger should highlight when a context is selected in the stack 
widget? If I'm right, how comes that this method has no senders in the 
debugger code? That would mean this feature is also implemented 
somewhere else.


Thomas

Le 11/01/2019 à 20:28, Eliot Miranda a écrit :

Hi Thomas,

   forgive me, my first response was too terse.  Having thought about it in the 
shower it becomes clear :-)


On Jan 11, 2019, at 6:49 AM, Thomas Dupriez  
wrote:

Hi,

Yes, my question was just of the form: "Hey there's this method in DebugSession. 
What is it doing? What's the intention behind it? Does someone know?". There was no 
hidden agenda behind it.

@Eliot

After taking another look at this method, there's something I don't understand:

activePC: aContext
^ (self isLatestContext: aContext)
 ifTrue: [ interruptedContext pc ]
 ifFalse: [ self previousPC: aContext ]

isLatestContext: checks whether its argument is the suspended context (the 
context at the top of the stack of the interrupted process). And if that's 
true, activePC: returns the pc of **interruptedContext**, not of the suspended 
context. These two contexts are different when the debugger opens on an 
exception, so this method is potentially returning a pc for another context 
than its argument...

Another question I have to improve the comment for this method is: what's the high-level 
meaning of this concept of "activePC". You gave the formal definition, but 
what's the point of defining this so to speak? What makes this concept interesting enough 
to warrant defining it and giving it a name?

There are two “modes” where a pc us mapped to a source range.  One is when 
stepping a context in the debugger (the context is on top and is actively 
executing bytecodes).  Here the debugger stops immediately before a send or 
assignment or return, so that for sends we can do into or over, or for 
assignments or returns check stack top to see what will be assigned or 
returned.  In this mode we want the pc of the send, assign or return to map to 
the source range for the send, or the expression being assigned or returned.  
Since this is the “common case”, and since this is the only choice that makes 
sense for assignments ta and returns, the bytecode compiler constructs it’s pc 
to source range map in terms of the pc of the first byte if the send, assign or 
return bytecode.

The second “mode” is when selecting a context below the top context.  The pc 
for any context below the top context will be the return pc for a send, because 
the send has already happened.  The compiler could choose to map this pc to the 
send, but it would not match what works for the common case. Another choice 
would appear be to have two map entries, one for the send and one for the 
return pc, both mapping to the source range.  But this wouldn’t work because 
the result of a send might be assigned or returned and so there is a potential 
conflict.  I stead the reasonable solution is to select the previous pc for 
contexts below the top of context, which will be the pc for the start of the 
send bytecode.

HTH


Cheers,
Thomas


On 11/01/2019 13:53, Tudor Girba wrote:
Hi,

@Eliot: Thanks for the clarifying answer.

I believe you might have jumped to conclusion about the intention of the 
question. Thomas asked a legitimate question. Without users of a method it is 
hard to understand its use. It does not necessarily imply that the intention is 
to remove it, but it does show that someone wants to understand.

As far as I know, Thomas actually wants to write a test to cover that usage. I 
am sure that you appreciate and encourage that :).

@Thomas: Thanks for this effort!

Cheers,
Doru



On Jan 10, 2019, at 3:11 PM, Eliot Miranda  wrote:

Hi Thomas,


On Jan 10, 2019, at 2:24 AM, Thomas Dupriez via Pharo-dev 
 wrote:



in a stack of contexts the active pc is different for the top context.  For 
other than the top context, a context’s pc will be pointing after the send that 
created the context above it, so to find the pc of the send one finds the 
previous pc.  For the top context its pc is the active pc.

Typically the debugger is invoked in two different modes, interruption or 
exception. When interrupted, a process is stopped at the next suspension point 
(method entry or backward branch) and the top context in the process is the 
context to be displayed in the debugger.  When an exception occurs the 
exception search machinery will find the signaling context, the context that 
raised the exception, which will be below the search machinery and the debugger 
invocation above that. The active pc of the signaling context will be the of 
for the send of digbsl et al.

So the distinction is important an

Re: [Pharo-dev] DebugSession>>activePC:

2019-01-11 Thread Thomas Dupriez

Hi,

Yes, my question was just of the form: "Hey there's this method in 
DebugSession. What is it doing? What's the intention behind it? Does 
someone know?". There was no hidden agenda behind it.


@Eliot

After taking another look at this method, there's something I don't 
understand:


activePC: aContext
^ (self isLatestContext: aContext)
        ifTrue: [ interruptedContext pc ]
        ifFalse: [ self previousPC: aContext ]

isLatestContext: checks whether its argument is the suspended context 
(the context at the top of the stack of the interrupted process). And if 
that's true, activePC: returns the pc of **interruptedContext**, not of 
the suspended context. These two contexts are different when the 
debugger opens on an exception, so this method is potentially returning 
a pc for another context than its argument...


Another question I have to improve the comment for this method is: 
what's the high-level meaning of this concept of "activePC". You gave 
the formal definition, but what's the point of defining this so to 
speak? What makes this concept interesting enough to warrant defining it 
and giving it a name?


Cheers,
Thomas

On 11/01/2019 13:53, Tudor Girba wrote:

Hi,

@Eliot: Thanks for the clarifying answer.

I believe you might have jumped to conclusion about the intention of the 
question. Thomas asked a legitimate question. Without users of a method it is 
hard to understand its use. It does not necessarily imply that the intention is 
to remove it, but it does show that someone wants to understand.

As far as I know, Thomas actually wants to write a test to cover that usage. I 
am sure that you appreciate and encourage that :).

@Thomas: Thanks for this effort!

Cheers,
Doru



On Jan 10, 2019, at 3:11 PM, Eliot Miranda  wrote:

Hi Thomas,


On Jan 10, 2019, at 2:24 AM, Thomas Dupriez via Pharo-dev 
 wrote:



in a stack of contexts the active pc is different for the top context.  For 
other than the top context, a context’s pc will be pointing after the send that 
created the context above it, so to find the pc of the send one finds the 
previous pc.  For the top context its pc is the active pc.

Typically the debugger is invoked in two different modes, interruption or 
exception. When interrupted, a process is stopped at the next suspension point 
(method entry or backward branch) and the top context in the process is the 
context to be displayed in the debugger.  When an exception occurs the 
exception search machinery will find the signaling context, the context that 
raised the exception, which will be below the search machinery and the debugger 
invocation above that. The active pc of the signaling context will be the of 
for the send of digbsl et al.

So the distinction is important and the utility method is probably useful.

Do you want to remove the method simply because there are no senders in the 
image?

If so, this is indicative of a serious problem with the Pharo development 
process.  In the summer I ported VMMaker.oscog to Pharo 6.  Now as feenk try 
and build a VMMaker.oscog image on Pharo 7, the system is broken, in part 
because of depreciations and in part because useful methods (isOptimisedBlock 
(isOptimizedBlock?) in the Opal compiler) have been removed.

Just because a method is not in the image does not imply it is not in use.  It 
simply means that it is not in use in the base image.  As the system gets 
modularised this issue will only increase.  There are lots of collection 
methods that exist as a library that are not used in the base image and 
removing them would clearly damage the library for users.  This is the case for 
lots of so-called system code.  There are users out there, like those of us in 
the vm team, who rely on such system code, and it is extremely unsettling and 
frustrating to have that system code change all the time.  If Pharo is to be a 
useful platform to the vm team it has to be more stable.

--
www.feenk.com

“The smaller and more pervasive the hardware becomes, the more physical the software 
gets."






[Pharo-dev] DebugSession>>activePC:

2019-01-10 Thread Thomas Dupriez via Pharo-dev
--- Begin Message ---

Hello,

I saw that DebugSession>>activePC: has no senders in pharo. Does someone 
know the intention behind it?


activePC: aContext
    ^ (self isLatestContext: aContext)
        ifTrue: [ interruptedContext pc ]
        ifFalse: [ self previousPC: aContext ]

Thomas Dupriez


--- End Message ---


Re: [Pharo-dev] Problem loading a branch of my pharo fork in an image

2018-12-13 Thread Thomas Dupriez
I retried what I described below, but this time I cloned my pharo fork 
using the "Clone from github" option instead of the "Clone remote 
repository".


It's better, but not perfect. here are the differences:

- the pharo repo is marked as "Detached working Copy" instead of "Fetch 
required. Unknown 67dc1e8"

- the changes to the WorldState class>>debugOn: were loaded this time
- however, the package I had added to my branch (BreakpointBrowser) was 
not present, and not shown among the packages iceberg showed when 
double-clickig on the pharo repo


Thomas Dupriez

On 13/12/2018 16:18, Thomas Dupriez wrote:

Hello,

I loaded a branch of my pharo fork in an image using iceberg, but the 
method I was interested in did not change for some reason (my branch's 
latest commit changes this method, but these changes were not visible 
in the image I loaded my branch in).


Does someone has an idea of what could have happened? Did I do 
something wrong?


Here's what I did step-by-step if that helps:

- fresh pharo 7 image
- open iceberg
- repair repository "pharo"
- Clicked "Clone again this repository"
- Chose "Clone remote repository", and put the url of my pharo fork: 
"https://github.com/dupriezt/pharo;

- ok
- wait for loading bar to complete
- pharo repo is marked as "Fetch required. Unknown 67dc1e8"
- repair repository "pharo"
- chose "Discard local changes and checkout an existing branch"
- chose the branch "BreakpointBrowser" from the "origin" remote
- Clicked "checkout" on the checkout preview window
- wait for loading bar to complete
- browse the method WorldState class>>debugOn:
- It is different from the last commit I made to this branch 
(https://github.com/dupriezt/pharo/commit/ead94e32f138eb435a95cd889f77ca39d4c325f4)


Thomas Dupriez






[Pharo-dev] Problem loading a branch of my pharo fork in an image

2018-12-13 Thread Thomas Dupriez

Hello,

I loaded a branch of my pharo fork in an image using iceberg, but the 
method I was interested in did not change for some reason (my branch's 
latest commit changes this method, but these changes were not visible in 
the image I loaded my branch in).


Does someone has an idea of what could have happened? Did I do something 
wrong?


Here's what I did step-by-step if that helps:

- fresh pharo 7 image
- open iceberg
- repair repository "pharo"
- Clicked "Clone again this repository"
- Chose "Clone remote repository", and put the url of my pharo fork: 
"https://github.com/dupriezt/pharo;

- ok
- wait for loading bar to complete
- pharo repo is marked as "Fetch required. Unknown 67dc1e8"
- repair repository "pharo"
- chose "Discard local changes and checkout an existing branch"
- chose the branch "BreakpointBrowser" from the "origin" remote
- Clicked "checkout" on the checkout preview window
- wait for loading bar to complete
- browse the method WorldState class>>debugOn:
- It is different from the last commit I made to this branch 
(https://github.com/dupriezt/pharo/commit/ead94e32f138eb435a95cd889f77ca39d4c325f4)


Thomas Dupriez




Re: [Pharo-dev] InterruptedContext vs suspendedContext

2018-12-04 Thread Thomas Dupriez

Ok, thanks to you two for these nice answers.

I made a pull-request to improve the comment of the DebugSession class 
based on your answers.


Thomas

On 01/12/2018 19:02, Eliot Miranda wrote:

Hi Andrei, Hi Thomas,

    Andrei, you are right; they are different and the difference is 
important.  As you say, suspendedContext is the top (“hot”) context in 
a process’s context chain, but interruptedContext is the context which 
sent the signal message that eventually raised the exception that 
invoked the debugger.  suspendedContext is therefore where execution 
is in the process, but interruptedContext is where the debugger should 
show the stack.


Thomas, because the exception system is implemented in Smalltalk the 
handling of the initial signal (eg in Object>>#halt), all the way to 
opening a debugger, is itself Smalltalk code, and exists as 
activations from suspendedContext to interruptedContext.  The 
debugger, with help from the exception system, carefully hides this 
processing from the programmer.  If it did not we would have to wade 
through many activations before we found where the exception occurred.


When a process is interrupted by control period things are different. 
 Here, another process handles opening the debugger and indeed 
suspendedContext and interruptedContext are the same.


So the difference between suspendedContext and interruptedContext is 
vital to the debugger.  Without it we would  see the inner machinery 
of the exception system when errors or exceptions are raised.


HTH

_,,,^..^,,,_ (phone)

On Nov 30, 2018, at 7:42 AM, Andrei Chis <mailto:chisvasileand...@gmail.com>> wrote:



Hi,

From what I remember they are not always redundant, but I'm not 100% 
sure they are both needed.


`suspendedContext` from Process is always the top context of a 
process. After execution actions like Step Into, Step Over, Step 
Through it will be the same as interruptedContext in the debugger.


They will be different when opening the debugger as a result of an 
exception.
Exception>>#debug triggers the workflow for opening a debugger. This 
uses `self signalerContext` as the context that is being debugged. 
This is the context where the exception was raised and this will be 
put in the interruptedContext. As this point the execution of the 
current process is not over and it will continue up to 
`MorphicUIManager>>#debugProcess:context:label:fullView:notification: ` 
where the current process is suspended. At that point the two will be 
different, as suspendedContext will be the context of the method 
MorphicUIManager>>#debugProcess:context:label:fullView:notification: 
and the interruptedContext the context that triggered the exception.


But it might be that they are not both needed. One  possible option 
might be to force the process to step to the context that raised the 
exception when the debugger is created. For example 
in DebugSession>>process:context:.
Apart from when opening the debugger I do not know if there is 
another situation where those two can diverge.


Cheers,
Andrei

On Fri, Nov 30, 2018 at 11:54 AM Thomas Dupriez 
mailto:tdupr...@ens-paris-saclay.fr>> 
wrote:


Hello,


Instances of DebugSession have an "interruptedContext" and an
"interruptedProcess" instance variable.

Instances of Process have a "suspendedContext" instance variable.

Does someone know if there is a relation between the
interruptedContext of a DebugSession and the suspendedContext of
its interruptedProcess? At first glance it seems like these two
variables are redundant and store the same Context.

Thomas Dupriez



[Pharo-dev] InterruptedContext vs suspendedContext

2018-11-30 Thread Thomas Dupriez

Hello,


Instances of DebugSession have an "interruptedContext" and an 
"interruptedProcess" instance variable.


Instances of Process have a "suspendedContext" instance variable.

Does someone know if there is a relation between the interruptedContext 
of a DebugSession and the suspendedContext of its interruptedProcess? At 
first glance it seems like these two variables are redundant and store 
the same Context.


Thomas Dupriez



Re: [Pharo-dev] Empirical Analysis of Programming Language Adoption

2018-06-08 Thread Thomas Dupriez

Hello,
I wanted to just write a quick comment, but it turned into an essay, 
sorry. ^^


Le 08/06/2018 à 16:35, Nicolas Cellier a écrit :



2018-06-08 14:50 GMT+02:00 Thierry Goubier >:



Note that this is used in Smalltalk, when you write anInteger, aString
: you're using a form of typing for documentation.

Exactly!

And if you transpose this style to static typing you get things like
    Cat *theCat = new Cat;
Being tainted, I always thought that is was noise...
You'd better rename your variable felix;)
Naming variables/arguments according to their type is only half a 
solution I think.
Because there are actually two things I would like to know about a 
variable/argument when reading code: its type and its meaning.
For example, knowing that an argument named "anInt" is an integer is 
nice, but I would also like to know that it's the number of dice the 
method has to roll. The two information are very useful to quickly 
understand the code.


From what I've seen in Pharo, variables are usually named after their 
meaning, while method argument are named after their type, but in an 
ideal world I would like to know both the type and the meaning of both 
the variables and the arguments.


That's in my opinion one of the advantages of explicit types for reading 
code: you write the type besides the variable/argument, so the name of 
the variable/argument can describe its meaning and I have both informations.



Static typing may help the IDE (refactoring and navigating).
My POV is thus that you enter this information for the tools, not for 
the humans (compiler, navigator, refactoring engine, ...).


I have differently tainted colleagues still thinking that the type 
help them reading code...
So, IMO, this assertion reflects the dominant culture rather than 
intrinsic merits.
IOW, if you want to create a successfull language, just clone an 
existing one :(
I would agree with your colleagues. I got stuck countless times when 
reading pharo code, because there was a message send to a variable I 
didn't know the type of, so I couldn't know which method was being 
called (because there were multiple methods with that name in the 
system). So the only solution was to place a breakpoint and get that 
method to be executed. This is not so easy (at least for me) in programs 
that are not really simple, because:
1) I need to have this method executed in its "normal use environment". 
I can't just execute it with dummy values as argument, because that will 
affect the values the variables will take.
2) I can look into tests, but since I don't know the program, I have no 
idea which tests to run to execute the piece of code.
So in general, it's either asking someone that knows how the program 
work, or spending a lot of (annoying) time figuring out how the entire 
program flows values to get the type of that one variable.


Thomas


Re: [Pharo-dev] better name for #aggregateRuns:

2017-12-12 Thread Thomas Dupriez

Oups, spoke too fast. My bad.

I mean that I don't really see a 'matching element' here, it's more that 
the collection is cut whenever the block given as argument evaluates to 
a different value.



Le 12/12/2017 à 11:11, Thomas Dupriez a écrit :
Hm, aggregateRuns: separates the collection both after and before the 
separator.


#(1 2 3 4 1 2 4 5 6 ) aggregateRuns:  [ :each | each = 4]

->    #(#(1 2 3) #(4) #(1 2) #(4) #(5 6))


Le 12/12/2017 à 11:05, Norbert Hartl a écrit :
For me split methods operate on separators which are not included in 
the result. So name it splitXXX might not be the best idea. And I 
think it should be more explicit. When the matching elements are 
included in the result it needs to indicate where the are added. So 
it is rather something like


xxxAfter:

because the collection is separated after the matching element. What 
the method does is oppositional to flattenXXX. So if we would have 
the opposite term of flatten that might be a good candidate. Then it 
would be something like


roughenAfter:

:) Ok, stupid name but you got the idea.

Norbert






Am 12.12.2017 um 10:50 schrieb Sven Van Caekenberghe <s...@stfx.eu>:

#splitWhile: because the block does not define separators but its 
value indicates runs ?


On 12 Dec 2017, at 10:34, Thomas Dupriez 
<thomas.dupr...@ens-paris-saclay.fr> wrote:


#(1 2 3 4 1 2 3 5 6 ) splitWhen:  [ :each | each = 4]


Le 12/12/2017 à 10:23, Pavel Krivanek a écrit :

Hi,

do you have some proposals for a better name for the message named 
#aggregateRuns?


(#(1 2 3 4 1 2 3 5 6 ) aggregateRuns:  [ :each | each = 4])

#(#(1 2 3) #(4) #(1 2 3 5 6)).

(#(1 2 3 4 1 2 3 4 5 6 ) aggregateRuns:  [ :each | each = 4])

#(#(1 2 3) #(4) #(1 2 3) #(4) #(5 6)).

((1 to: 12) aggregateRuns:  [ :each | (each \\ 3) = 0])

#(#(1 2) #(3) #(4 5) #(6) #(7 8) #(9) #(10 11) #(12)).

The current comment is:
"Answer a new collection of the same species as the
receiver with elements being collections (of the receiver
species) containing those elements of the receiver
for which the given block consecutively evaluates to
the same object."

https://pharo.fogbugz.com/f/cases/20864/add-examples-to-SequenceableCollection-aggregateRuns 



Cheers,
-- Pavel









Re: [Pharo-dev] better name for #aggregateRuns:

2017-12-12 Thread Thomas Dupriez
Hm, aggregateRuns: separates the collection both after and before the 
separator.


#(1 2 3 4 1 2 4 5 6 ) aggregateRuns:  [ :each | each = 4]

->    #(#(1 2 3) #(4) #(1 2) #(4) #(5 6))


Le 12/12/2017 à 11:05, Norbert Hartl a écrit :

For me split methods operate on separators which are not included in the 
result. So name it splitXXX might not be the best idea. And I think it should 
be more explicit. When the matching elements are included in the result it 
needs to indicate where the are added. So it is rather something like

xxxAfter:

because the collection is separated after the matching element. What the method 
does is oppositional to flattenXXX. So if we would have the opposite term of 
flatten that might be a good candidate. Then it would be something like

roughenAfter:

:) Ok, stupid name but you got the idea.

Norbert






Am 12.12.2017 um 10:50 schrieb Sven Van Caekenberghe <s...@stfx.eu>:

#splitWhile: because the block does not define separators but its value 
indicates runs ?


On 12 Dec 2017, at 10:34, Thomas Dupriez <thomas.dupr...@ens-paris-saclay.fr> 
wrote:

#(1 2 3 4 1 2 3 5 6 ) splitWhen:  [ :each | each = 4]


Le 12/12/2017 à 10:23, Pavel Krivanek a écrit :

Hi,

do you have some proposals for a better name for the message named 
#aggregateRuns?

(#(1 2 3 4 1 2 3 5 6 ) aggregateRuns:  [ :each | each = 4])

#(#(1 2 3) #(4) #(1 2 3 5 6)).

(#(1 2 3 4 1 2 3 4 5 6 ) aggregateRuns:  [ :each | each = 4])

#(#(1 2 3) #(4) #(1 2 3) #(4) #(5 6)).

((1 to: 12) aggregateRuns:  [ :each | (each \\ 3) = 0])

#(#(1 2) #(3) #(4 5) #(6) #(7 8) #(9) #(10 11) #(12)).

The current comment is:
"Answer a new collection of the same species as the
receiver with elements being collections (of the receiver
species) containing those elements of the receiver
for which the given block consecutively evaluates to
the same object."

https://pharo.fogbugz.com/f/cases/20864/add-examples-to-SequenceableCollection-aggregateRuns

Cheers,
-- Pavel







Re: [Pharo-dev] better name for #aggregateRuns:

2017-12-12 Thread Thomas Dupriez

#splitByGroupingWhile:

The 'split' indicates it's a method to split a collection, and the 
'GroupingWhile' expresses how it's done: by grouping elements while they 
make the block evaluate to the same value.


Le 12/12/2017 à 10:50, Sven Van Caekenberghe a écrit :

#splitWhile: because the block does not define separators but its value 
indicates runs ?


On 12 Dec 2017, at 10:34, Thomas Dupriez <thomas.dupr...@ens-paris-saclay.fr> 
wrote:

#(1 2 3 4 1 2 3 5 6 ) splitWhen:  [ :each | each = 4]


Le 12/12/2017 à 10:23, Pavel Krivanek a écrit :

Hi,

do you have some proposals for a better name for the message named 
#aggregateRuns?

(#(1 2 3 4 1 2 3 5 6 ) aggregateRuns:  [ :each | each = 4])
 >>> #(#(1 2 3) #(4) #(1 2 3 5 6)).

(#(1 2 3 4 1 2 3 4 5 6 ) aggregateRuns:  [ :each | each = 4])
 >>> #(#(1 2 3) #(4) #(1 2 3) #(4) #(5 6)).

((1 to: 12) aggregateRuns:  [ :each | (each \\ 3) = 0])
 >>> #(#(1 2) #(3) #(4 5) #(6) #(7 8) #(9) #(10 11) #(12)).

The current comment is:
"Answer a new collection of the same species as the
receiver with elements being collections (of the receiver
species) containing those elements of the receiver
for which the given block consecutively evaluates to
the same object."

https://pharo.fogbugz.com/f/cases/20864/add-examples-to-SequenceableCollection-aggregateRuns

Cheers,
-- Pavel







Re: [Pharo-dev] better name for #aggregateRuns:

2017-12-12 Thread Thomas Dupriez

#(1 2 3 4 1 2 3 5 6 ) splitWhen:  [ :each | each = 4]


Le 12/12/2017 à 10:23, Pavel Krivanek a écrit :

Hi,

do you have some proposals for a better name for the message named 
#aggregateRuns?


(#(1 2 3 4 1 2 3 5 6 ) aggregateRuns:  [ :each | each = 4])
    >>> #(#(1 2 3) #(4) #(1 2 3 5 6)).

(#(1 2 3 4 1 2 3 4 5 6 ) aggregateRuns:  [ :each | each = 4])
    >>> #(#(1 2 3) #(4) #(1 2 3) #(4) #(5 6)).

((1 to: 12) aggregateRuns:  [ :each | (each \\ 3) = 0])
    >>> #(#(1 2) #(3) #(4 5) #(6) #(7 8) #(9) #(10 11) #(12)).

The current comment is:
"Answer a new collection of the same species as the
receiver with elements being collections (of the receiver
species) containing those elements of the receiver
for which the given block consecutively evaluates to
the same object."

https://pharo.fogbugz.com/f/cases/20864/add-examples-to-SequenceableCollection-aggregateRuns

Cheers,
-- Pavel





Re: [Pharo-dev] Release: Conveniently browse, deactivate and reactivate halts and breakpoints with the HaltManager

2017-12-08 Thread Thomas Dupriez
HaltManager proposes the deactivation by metalink even on self halt 
because you may want to deactivate the halt without changing the source 
code and completely recompiling the method.


Thomas

Le 07/12/2017 à 21:00, Stephane Ducasse a écrit :

Thanks Thomas and you put screenshots so this is cool.
I have a simple question
if there is only a self halt in the code why you propose to change metalinks?
Stef

On Wed, Dec 6, 2017 at 11:03 AM, Thomas Dupriez
<thomas.dupr...@ens-paris-saclay.fr> wrote:

Hello,

I have developed a package to assist developers managing their halts and
breakpoints: HaltManager.

HaltManager provides a window showing all the breakpoints and halt messages
of the system, and allows one to toggle them on/off with a simple click.
Halt messages can also be toggled via source code rewriting. The
deactivation/reactivation feature is available in all code browsers, not
only in the HaltManager window.

It is available here, with installation instructions and pictures:
https://github.com/dupriezt/HaltManager

Feedback welcome.

Cheers,
Thomas Dupriez







Re: [Pharo-dev] Release: Conveniently browse, deactivate and reactivate halts and breakpoints with the HaltManager

2017-12-06 Thread Thomas Dupriez

Thanks. :)

I think "rewriting" has to be there to indicate it changes the source 
code and recompiles the method, which you may not want.


I agree that users don't necessarily need to now that the other 
deactivation option is done with metalinks.


I could replace "deactivate by metalink" with just "deactivate" to make 
it less technical and keep the "deactivate by rewriting" as is.


Cheers,
Thomas


Le 06/12/2017 à 13:06, Juraj Kubelka a écrit :

Hi Thomas,

nice project.

Maybe “deactivate by metalink/rewriting” is too technical?

Cheers,
Juraj


On Dec 6, 2017, at 07:03, Thomas Dupriez <thomas.dupr...@ens-paris-saclay.fr> 
wrote:

Hello,

I have developed a package to assist developers managing their halts and 
breakpoints: HaltManager.

HaltManager provides a window showing all the breakpoints and halt messages of 
the system, and allows one to toggle them on/off with a simple click. Halt 
messages can also be toggled via source code rewriting. The 
deactivation/reactivation feature is available in all code browsers, not only 
in the HaltManager window.

It is available here, with installation instructions and pictures: 
https://github.com/dupriezt/HaltManager

Feedback welcome.

Cheers,
Thomas Dupriez







[Pharo-dev] Release: Conveniently browse, deactivate and reactivate halts and breakpoints with the HaltManager

2017-12-06 Thread Thomas Dupriez

Hello,

I have developed a package to assist developers managing their halts and 
breakpoints: HaltManager.


HaltManager provides a window showing all the breakpoints and halt 
messages of the system, and allows one to toggle them on/off with a 
simple click. Halt messages can also be toggled via source code 
rewriting. The deactivation/reactivation feature is available in all 
code browsers, not only in the HaltManager window.


It is available here, with installation instructions and pictures: 
https://github.com/dupriezt/HaltManager


Feedback welcome.

Cheers,
Thomas Dupriez




Re: [Pharo-dev] [Debugger] Is "run to here" broken?

2017-11-15 Thread Thomas Dupriez

Here they are:

https://github.com/dupriezt/Pharo-RunToSelectionDebuggerFeature


Le 15/11/2017 à 10:47, Guillermo Polito a écrit :

Thomas, can you try writing some real test cases in SUnit?

I don't care if they are originally red (they will be because it is 
not working).


The idea is that we capture all these different scenarios and have a 
way to know automatically in the future if

 - we fixed all them
 - or we have a regression and broke some.

On Wed, Nov 15, 2017 at 10:44 AM, Thomas Dupriez 
<thomas.dupr...@ens-paris-saclay.fr 
<mailto:thomas.dupr...@ens-paris-saclay.fr>> wrote:




Le 15/11/2017 à 01:19, Ben Coman a écrit :



On 14 November 2017 at 23:55, Thomas Dupriez
<thomas.dupr...@ens-paris-saclay.fr
<mailto:thomas.dupr...@ens-paris-saclay.fr>> wrote:

While working on writing a test, I discovered that just using
stepThrough instead of stepOver may not be the definitive
solution.

# Example1: When using the `value` message directly (instead
of calling a method that does that as in my previous
example), the RunToHere moves the debugSession to the `value`
message and not the inside of the block.

`meth2
    self halt.
    [
        1+1.
        2+2."< cursor before the RunToHere"
    ] ">"value""+1"< result of the RunToHere".
        2+2."< cursor before the RunToHere"
    ].
    3+3.
    "One stepInto is required after the RunToHere to reach
the cursor (the `+2` message)"`

cheers -thomas


In both cases, what happens with an additional step-Through?

cheers -ben

# Example1*:
Operation: RunToHere with cursor at the end of the `2+2.` line + 1
stepThrough.
Result: DebugSession at the `+1`, first instruction of the block
but not the intended position.
Note: Doing an additional stepThrough brings the debugSession to
the intended `+2`.

`meth2
    self halt.
    [
        1">"+1"<"."result of the RunToHere + 1 stepThrough"
        2+2."< cursor before the RunToHere"
    ] ">"value""+1"< result of the RunToHere".
        2">"+2""+1"< result of the RunToHere".
        2">"+2""+3"
Le 13/11/2017 à 17:23, Thomas Dupriez a écrit :




Le 13/11/2017 à 15:56, Ben Coman a écrit :



On Mon, Nov 13, 2017 at 9:32 PM, Thomas Dupriez
<thomas.dupr...@ens-paris-saclay.fr
<mailto:thomas.dupr...@ens-paris-saclay.fr>> wrote:



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



On Mon, Nov 13, 2017 at 8:40 PM, Thomas Dupriez
<thomas.dupr...@ens-paris-saclay.fr
<mailto:thomas.dupr...@ens-paris-saclay.fr>> 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. 
MyClass new myEvalBlock: [
2+2. 
        ].
        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.

  

Re: [Pharo-dev] [Debugger] Is "run to here" broken?

2017-11-15 Thread Thomas Dupriez



Le 15/11/2017 à 01:19, Ben Coman a écrit :



On 14 November 2017 at 23:55, Thomas Dupriez 
<thomas.dupr...@ens-paris-saclay.fr 
<mailto:thomas.dupr...@ens-paris-saclay.fr>> wrote:


While working on writing a test, I discovered that just using
stepThrough instead of stepOver may not be the definitive solution.

# Example1: When using the `value` message directly (instead of
calling a method that does that as in my previous example), the
RunToHere moves the debugSession to the `value` message and not
the inside of the block.

`meth2
    self halt.
    [
        1+1.
        2+2."< cursor before the RunToHere"
    ] ">"value""+1"< result of the RunToHere".
        2+2."< cursor before the RunToHere"
    ].
    3+3.
    "One stepInto is required after the RunToHere to reach the
cursor (the `+2` message)"`

cheers -thomas


In both cases, what happens with an additional step-Through?

cheers -ben

# Example1*:
Operation: RunToHere with cursor at the end of the `2+2.` line + 1 
stepThrough.
Result: DebugSession at the `+1`, first instruction of the block but not 
the intended position.
Note: Doing an additional stepThrough brings the debugSession to the 
intended `+2`.


`meth2
    self halt.
    [
        1">"+1"<"."result of the RunToHere + 1 stepThrough"
        2+2."< cursor before the RunToHere"
    ] ">"value"    "Two stepInto are required after the RunToHere to reach the cursor 
(the `+2` message)"`


# Example2*:
Operation: RunToHere with cursor at the end of the `2+2.` line + 1 
stepThrough

Result: DebugSession at the intended `+2` position.
Note: The additional stepThrough just moves the DebugSession to the next 
instruction. See Example3 for what happens when the target instruction 
is further away.


`meth3
    self halt.
    MyClass new evalBlock:
    [
        1">"+1"< result of the RunToHere".
        2">"+2"RunToHere"

    ].
    3+3.
    "One stepInto is required after the RunToHere to reach the cursor 
(the `+2` message)"`



# Example3:
Operation: RunToHere with cursor at the end of the `3+3.` line. + 1 
stepThrough.

Result: DebugSession is at the `+2` instruction, not the intended `+3` one.

`meth4
    self halt.
    MyClass new evalBlock:
    [
        1">"+1"< result of the RunToHere".
        2">"+2"        3">"+3"RunToHere"

    ].
    4+4.
    "One stepInto is required after the RunToHere to reach the cursor 
(the `+2` message)"`


cheers -thomas


Le 13/11/2017 à 17:23, Thomas Dupriez a écrit :




Le 13/11/2017 à 15:56, Ben Coman a écrit :



On Mon, Nov 13, 2017 at 9:32 PM, Thomas Dupriez
<thomas.dupr...@ens-paris-saclay.fr
<mailto:thomas.dupr...@ens-paris-saclay.fr>> wrote:



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



On Mon, Nov 13, 2017 at 8:40 PM, Thomas Dupriez
<thomas.dupr...@ens-paris-saclay.fr
<mailto:thomas.dupr...@ens-paris-saclay.fr>> 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. 
        MyClass new myEvalBlock: [
            2+2. 
        ].
        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 select

Re: [Pharo-dev] [Debugger] Is "run to here" broken?

2017-11-14 Thread Thomas Dupriez
While working on writing a test, I discovered that just using 
stepThrough instead of stepOver may not be the definitive solution.


# Example1: When using the `value` message directly (instead of calling 
a method that does that as in my previous example), the RunToHere moves 
the debugSession to the `value` message and not the inside of the block.


`meth2
    self halt.
    [
        1+1.
        2+2."< cursor before the RunToHere"
    ] ">"value"    "Two stepInto are required after the RunToHere to reach the cursor 
(the `+2` message)"`


# Example2: Going back to using a dedicated method for evaluating the 
block, but increasing the block's size. The RunToHere moves the 
debugSession to the first message of the block instead of the pointed one.


`meth3
    self halt.
    MyClass new evalBlock:
    [
        1">"+1"< result of the RunToHere".
        2+2."< cursor before the RunToHere"
    ].
    3+3.
    "One stepInto is required after the RunToHere to reach the cursor 
(the `+2` message)"`


cheers -thomas


Le 13/11/2017 à 17:23, Thomas Dupriez a écrit :




Le 13/11/2017 à 15:56, Ben Coman a écrit :



On Mon, Nov 13, 2017 at 9:32 PM, Thomas Dupriez 
<thomas.dupr...@ens-paris-saclay.fr 
<mailto:thomas.dupr...@ens-paris-saclay.fr>> wrote:




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



On Mon, Nov 13, 2017 at 8:40 PM, Thomas Dupriez
<thomas.dupr...@ens-paris-saclay.fr
<mailto:thomas.dupr...@ens-paris-saclay.fr>> 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. 
        MyClass new myEvalBlock: [
            2+2. 
        ].
        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?


Seems like expected behaviour.
Could you create an Issue/Pull Request to provide some concrete code 

Re: [Pharo-dev] [Debugger] Is "run to here" broken?

2017-11-13 Thread Thomas Dupriez



Le 13/11/2017 à 15:56, Ben Coman a écrit :



On Mon, Nov 13, 2017 at 9:32 PM, Thomas Dupriez 
<thomas.dupr...@ens-paris-saclay.fr 
<mailto:thomas.dupr...@ens-paris-saclay.fr>> wrote:




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



On Mon, Nov 13, 2017 at 8:40 PM, Thomas Dupriez
<thomas.dupr...@ens-paris-saclay.fr
<mailto:thomas.dupr...@ens-paris-saclay.fr>> 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. 
        MyClass new myEvalBlock: [
            2+2. 
        ].
        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?


Seems like expected behaviour.
Could you create an Issue/Pull Request to provide some concrete code 
to review?


Now the trick will be if you can devise some tests to go with this.
For examples perhaps look at senders of newDebugSessionNamed:startedAt:
including SpecDebugger>>testBasic.

cheers -ben


I opened an issue on FogBugz: https://pharo.fogbugz.com/f/cases/20687/

Attached are the file out of the test code (MyClass.st) and the fixed 
runToSelection:inContext: (DebugSession-runToSelectioninContext).

I'll make a pull request tomorrow.

For the test, I'm thinking about something like the following, that 
checks the source code position of the pc after the runToSelection. 
(It's not working yet)
Now that I think of it, the source code position of the pc will maybe be 
the whole block (as experienced earlier) so this approach may end up not 
working.

I'll come back to that tomorrow.

Draft for a test:
    `testRunToSelectionInContext
    |context_ process_ session_|
    "The variable names have an underscore to distinguish them from 
those declared in the setUp method of this TestCase (DebuggerModelTest), 
which are not suited for this test (because not making a debug session 
out of suitable code)"

    context_ := [1+1.
        self evalBlock:[

Re: [Pharo-dev] [Debugger] Is "run to here" broken?

2017-11-13 Thread Thomas Dupriez



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



On Mon, Nov 13, 2017 at 8:40 PM, Thomas Dupriez 
<thomas.dupr...@ens-paris-saclay.fr 
<mailto:thomas.dupr...@ens-paris-saclay.fr>> 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. 
        MyClass new myEvalBlock: [
            2+2. 
        ].
        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
<tu...@tudorgirba.com <mailto:tu...@tudorgirba.com>> wrote:

Hi,

The basic tools, such as debugger, are expected to work.
If something

Re: [Pharo-dev] [Debugger] Is "run to here" broken?

2017-11-13 Thread Thomas Dupriez

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. 
        MyClass new myEvalBlock: [
            2+2. 
        ].
        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).


- 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  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  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  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: 1) 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
www.feenk.com

"Value is always contextual."










[Pharo-dev] Alternative window manager

2017-11-10 Thread Thomas Dupriez

Hello,

Does an alternative window manager for pharo exist?

For some reasons I always end up with a tangled mess of windows when 
using the default one. My biggest gripe is that new windows tend to open 
on top of other windows, blocking the view even if there is still empty 
space elsewhere.


I watched this video ( https://www.youtube.com/watch?v=Wx0eNaGzAZU ) 
about the i3 window manager for linux and how it paves the screen with 
the windows to optimise screen space and make things look less messy, 
and was wondering whether something like that existed for pharo.


Cheers,
Thomas




[Pharo-dev] Iceberg. Uncommited changes just after loading code from a repo?

2017-10-24 Thread Thomas Dupriez

Hello,

After cloning a repo with Iceberg, loading the code and before doing any 
change, iceberg sees a lot of additions to the code in the "Synchronize 
Repository" window.


Here are the steps I followed:

- Load fresh Pharo7 image
- Delete the previous clone of my repo in 
/home/dupriez/Pharo/vms/70-x86/pharo-local/iceberg (to start afresh)

- Open Iceberg:
    - Click on "Clone Repository", to clone 
g...@github.com:dupriezt/Calypso.git
    - Right-click on the repo in the list, Metacello/install baseline 
of Calypso (default)
    - Switch to dev branch, creating a local dev branch in the process 
as prompted
    - Without making any change, if I right-click on the Calypso repo 
in the list and click 'Synchronize Repository', there is a significant 
list of additions ready to be commited.



Can someone shed some light on this? How can I get the code of the dev 
branch of this repo as is in my image?


Cheers,
Thomas Dupriez