Recursive errors

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Recursive errors

Nicolas Cellier
Hi all,
with the new exception handling, I have encountered some recursive error.
Very hard to debug because the stack grows too fast.
The origin is when trying to browse revisions of a removed method.
I have a:

MethodReference >>timestamp
      receiver: a MethodReference Parser >> #externalFunctionDeclaration
UndefinedObject(Object)>>doesNotUnderstand: #timeStamp
...
Debugger class>>openOn:context:label:contents:fullView:
...
SmalltalkImage>>logError:inContext:to:
...
Context>>printDetails:
...
[] in Context>>printDetails:
Context>>tempsAndValuesLimitedTo:indent:
Context>>tempNames
Context(InstructionStream)>>debuggerMap
CompiledMethod>>debuggerMap
    receiver: (MCRepository class>>#browseMethodRevisionsService "a
CompiledMethod(2459914)")
   receiver isInstalled ==> false !!! (because I did recompileAll at one point)
DebuggerMethodMap class>>forMethod:
...
CompiledMethod>>methodNode
    [source]: a Text for 'Vw6ilbntYC3Kf9Bz3g3T3YJ+J74W7Mmk9gPb...
    note that the source is broken, I don't know where it comes from,
the compiledMethod is not installed...
   this context will catch SyntaxErrorNotificationSignal
...
Parser>>parseCue:noPattern:ifFail:
   this context will catch ReparseAfterSourceEditing
...
SyntaxErrorNotification(Exception)>>signal
   expected, the source is broken...
...
Context>>handleSignal:
Context>>handleSignal:
   ^2 consecutive handleSIgnal: here...
   the first one (parseCue:noPattern:ifFail:) only catch
ReparseAfterSourceEditing
    the second one (methodNode) does catch our SyntaxErrorNotification
        on: SyntaxErrorNotification
        do: [:ex | ex return: self decompileWithTemps]
...
CompiledMethod>>decompileWithTemps
   oh but this one tries to get the tempNames by parsing the source!
   let's go for a cycle...
...
Parser>>parseCue:noPattern:ifFail:
   this context will catch ReparseAfterSourceEditing
...
SyntaxErrorNotification(Exception)>>signal
Context>>handleSignal:
Context>>handleSignal:
Context>>handleSignal:
   ouch, I have 3 of them now
   what happens? it's all normal, I now have 2 parseCue:... in the
stack catching ReparseAfterSourceEditing
  the 3rd is catching SyntaxErrorNotification and retries parsing tempNames...
  and we're back to another cycle.
...
tada, there's more than 1000 handleSignal: in the stack when I
interrupted the process, and it's impossible to debug, and I thought
the new exception handling had a problem...
It doesn't so far.
We have another problem with broken source for an uninstalled
CompiledMethod, that tries to decompile using broken source...

I'm happy that I'm not the root cause, but this is most annoying.
IMO, if we decompile a block, we might want to find the temp names
from the method source, but if we decompile a method, what's the
point???

Reply | Threaded
Open this post in threaded view
|

Re: Recursive errors

Nicolas Cellier
my snippet for inspecting (part of) the stack:

| tmp list i |
tmp := sender.
list := Array new: 200.
i := 0.
[tmp sender == nil]
    whileFalse: [
        list atWrap: (i := i+1) put: tmp.
        tmp := tmp sender].
    ^{list. i}

The stack was only about 150,000 deep, but our tools do not really
scale at this depth...

Le jeu. 15 avr. 2021 à 01:57, Nicolas Cellier
<[hidden email]> a écrit :

>
> Hi all,
> with the new exception handling, I have encountered some recursive error.
> Very hard to debug because the stack grows too fast.
> The origin is when trying to browse revisions of a removed method.
> I have a:
>
> MethodReference >>timestamp
>       receiver: a MethodReference Parser >> #externalFunctionDeclaration
> UndefinedObject(Object)>>doesNotUnderstand: #timeStamp
> ...
> Debugger class>>openOn:context:label:contents:fullView:
> ...
> SmalltalkImage>>logError:inContext:to:
> ...
> Context>>printDetails:
> ...
> [] in Context>>printDetails:
> Context>>tempsAndValuesLimitedTo:indent:
> Context>>tempNames
> Context(InstructionStream)>>debuggerMap
> CompiledMethod>>debuggerMap
>     receiver: (MCRepository class>>#browseMethodRevisionsService "a
> CompiledMethod(2459914)")
>    receiver isInstalled ==> false !!! (because I did recompileAll at one point)
> DebuggerMethodMap class>>forMethod:
> ...
> CompiledMethod>>methodNode
>     [source]: a Text for 'Vw6ilbntYC3Kf9Bz3g3T3YJ+J74W7Mmk9gPb...
>     note that the source is broken, I don't know where it comes from,
> the compiledMethod is not installed...
>    this context will catch SyntaxErrorNotificationSignal
> ...
> Parser>>parseCue:noPattern:ifFail:
>    this context will catch ReparseAfterSourceEditing
> ...
> SyntaxErrorNotification(Exception)>>signal
>    expected, the source is broken...
> ...
> Context>>handleSignal:
> Context>>handleSignal:
>    ^2 consecutive handleSIgnal: here...
>    the first one (parseCue:noPattern:ifFail:) only catch
> ReparseAfterSourceEditing
>     the second one (methodNode) does catch our SyntaxErrorNotification
>         on: SyntaxErrorNotification
>         do: [:ex | ex return: self decompileWithTemps]
> ...
> CompiledMethod>>decompileWithTemps
>    oh but this one tries to get the tempNames by parsing the source!
>    let's go for a cycle...
> ...
> Parser>>parseCue:noPattern:ifFail:
>    this context will catch ReparseAfterSourceEditing
> ...
> SyntaxErrorNotification(Exception)>>signal
> Context>>handleSignal:
> Context>>handleSignal:
> Context>>handleSignal:
>    ouch, I have 3 of them now
>    what happens? it's all normal, I now have 2 parseCue:... in the
> stack catching ReparseAfterSourceEditing
>   the 3rd is catching SyntaxErrorNotification and retries parsing tempNames...
>   and we're back to another cycle.
> ...
> tada, there's more than 1000 handleSignal: in the stack when I
> interrupted the process, and it's impossible to debug, and I thought
> the new exception handling had a problem...
> It doesn't so far.
> We have another problem with broken source for an uninstalled
> CompiledMethod, that tries to decompile using broken source...
>
> I'm happy that I'm not the root cause, but this is most annoying.
> IMO, if we decompile a block, we might want to find the temp names
> from the method source, but if we decompile a method, what's the
> point???

Reply | Threaded
Open this post in threaded view
|

Re: Recursive errors

marcel.taeumel
Hi Nicolas.

IMO, if we decompile a block, we might want to find the temp names
> from the method source, but if we decompile a method, what's the
> point???

Hmm.. aren't there several "layers" of source code possible in a method trailer? See CompiledMethodTrailer class >> #trailerKinds. Even if you have to decompile a method, temp names might still be available from somewhere.

Best,
Marcel

Am 15.04.2021 02:02:36 schrieb Nicolas Cellier <[hidden email]>:

my snippet for inspecting (part of) the stack:

| tmp list i |
tmp := sender.
list := Array new: 200.
i := 0.
[tmp sender == nil]
whileFalse: [
list atWrap: (i := i+1) put: tmp.
tmp := tmp sender].
^{list. i}

The stack was only about 150,000 deep, but our tools do not really
scale at this depth...

Le jeu. 15 avr. 2021 à 01:57, Nicolas Cellier
a écrit :

>
> Hi all,
> with the new exception handling, I have encountered some recursive error.
> Very hard to debug because the stack grows too fast.
> The origin is when trying to browse revisions of a removed method.
> I have a:
>
> MethodReference >>timestamp
> receiver: a MethodReference Parser >> #externalFunctionDeclaration
> UndefinedObject(Object)>>doesNotUnderstand: #timeStamp
> ...
> Debugger class>>openOn:context:label:contents:fullView:
> ...
> SmalltalkImage>>logError:inContext:to:
> ...
> Context>>printDetails:
> ...
> [] in Context>>printDetails:
> Context>>tempsAndValuesLimitedTo:indent:
> Context>>tempNames
> Context(InstructionStream)>>debuggerMap
> CompiledMethod>>debuggerMap
> receiver: (MCRepository class>>#browseMethodRevisionsService "a
> CompiledMethod(2459914)")
> receiver isInstalled ==> false !!! (because I did recompileAll at one point)
> DebuggerMethodMap class>>forMethod:
> ...
> CompiledMethod>>methodNode
> [source]: a Text for 'Vw6ilbntYC3Kf9Bz3g3T3YJ+J74W7Mmk9gPb...
> note that the source is broken, I don't know where it comes from,
> the compiledMethod is not installed...
> this context will catch SyntaxErrorNotificationSignal
> ...
> Parser>>parseCue:noPattern:ifFail:
> this context will catch ReparseAfterSourceEditing
> ...
> SyntaxErrorNotification(Exception)>>signal
> expected, the source is broken...
> ...
> Context>>handleSignal:
> Context>>handleSignal:
> ^2 consecutive handleSIgnal: here...
> the first one (parseCue:noPattern:ifFail:) only catch
> ReparseAfterSourceEditing
> the second one (methodNode) does catch our SyntaxErrorNotification
> on: SyntaxErrorNotification
> do: [:ex | ex return: self decompileWithTemps]
> ...
> CompiledMethod>>decompileWithTemps
> oh but this one tries to get the tempNames by parsing the source!
> let's go for a cycle...
> ...
> Parser>>parseCue:noPattern:ifFail:
> this context will catch ReparseAfterSourceEditing
> ...
> SyntaxErrorNotification(Exception)>>signal
> Context>>handleSignal:
> Context>>handleSignal:
> Context>>handleSignal:
> ouch, I have 3 of them now
> what happens? it's all normal, I now have 2 parseCue:... in the
> stack catching ReparseAfterSourceEditing
> the 3rd is catching SyntaxErrorNotification and retries parsing tempNames...
> and we're back to another cycle.
> ...
> tada, there's more than 1000 handleSignal: in the stack when I
> interrupted the process, and it's impossible to debug, and I thought
> the new exception handling had a problem...
> It doesn't so far.
> We have another problem with broken source for an uninstalled
> CompiledMethod, that tries to decompile using broken source...
>
> I'm happy that I'm not the root cause, but this is most annoying.
> IMO, if we decompile a block, we might want to find the temp names
> from the method source, but if we decompile a method, what's the
> point???



Reply | Threaded
Open this post in threaded view
|

Re: Recursive errors

Craig Latta
In reply to this post by Nicolas Cellier

Hi Nicolas--

 > with the new exception handling, I have encountered some recursive
 > error. Very hard to debug because the stack grows too fast.

      Sounds like you could debug this in the VM simulator?


-C

--
Craig Latta  ::  research computer scientist
Black Page Digital  ::  Berkeley, California
663137D7940BF5C0AFC :: 1349FB2ADA32C4D5314CE



Reply | Threaded
Open this post in threaded view
|

Re: Recursive errors

Nicolas Cellier
Hi Craig,
yes, I did not try that. This can be a solution once we know how to reproduce...
Once the stack is high, it's too late, the interface gets
unresponsive, so the simulation would only worsen.
We would need some sort of recording debugger in order to produce the
bug fast enough and then backtrack in a simulated env...
I guess that an instrumented VM could do that.
I wonder how hard such a project would be...

Le jeu. 15 avr. 2021 à 15:40, Craig Latta <[hidden email]> a écrit :

>
>
> Hi Nicolas--
>
>  > with the new exception handling, I have encountered some recursive
>  > error. Very hard to debug because the stack grows too fast.
>
>       Sounds like you could debug this in the VM simulator?
>
>
> -C
>
> --
> Craig Latta  ::  research computer scientist
> Black Page Digital  ::  Berkeley, California
> 663137D7940BF5C0AFC :: 1349FB2ADA32C4D5314CE
>
>
>