Hi,
Is there a way to add deep recursion protection to the system? eg. RecursiveObject>>#recurse self recurse So calling `RecursiveObject new recurse` in Dolphin raises an exception right away... Throws the following error with this stack: ProcessorScheduler>>stackOverflow: [] in ProcessorScheduler>>vmi:list:no:with: BlockClosure>>ifCurtailed: ProcessorScheduler>>vmi:list:no:with: RecursiveObject>>recurse RecursiveObject>>recurse In Pharo it goes forever until it hits the memory limit (3.6GiB), at which point doing an Alt+. is useless and you have to kill the VM. The example is pretty simple, but when doing Seaside rendering, it is easy to miss some return, causing the receiver to render recursively, turning your image useless. e.g. MyComponent>>renderContentOn: html html render: self someSubComponent MyComponent>>someSubComponent "Here I forget returning the subcomponent" someSubComponent ifNil: [someSubcomponent := OtherComponent new]. When you render MyComponent... boom, because #MyComponent>>#renderContentOn: will be called recursively. Regards, Esteban A. Maringolo |
I just checked in VisualWorks, where I also develop Seaside and also
make these mistakes, and these recursions launch a "Process Monitor Emergency: No space left" process monitor, with the option of killing any running Smalltalk process. Regards, Esteban A. Maringolo On Thu, Apr 25, 2019 at 9:30 AM Esteban Maringolo <[hidden email]> wrote: > > Hi, > > Is there a way to add deep recursion protection to the system? > > eg. > RecursiveObject>>#recurse > self recurse > > So calling `RecursiveObject new recurse` in Dolphin raises an > exception right away... > > Throws the following error with this stack: > ProcessorScheduler>>stackOverflow: > [] in ProcessorScheduler>>vmi:list:no:with: > BlockClosure>>ifCurtailed: > ProcessorScheduler>>vmi:list:no:with: > RecursiveObject>>recurse > RecursiveObject>>recurse > > In Pharo it goes forever until it hits the memory limit (3.6GiB), at > which point doing an Alt+. is useless and you have to kill the VM. > > The example is pretty simple, but when doing Seaside rendering, it is > easy to miss some return, causing the receiver to render recursively, > turning your image useless. > > e.g. > MyComponent>>renderContentOn: html > html render: self someSubComponent > > MyComponent>>someSubComponent > "Here I forget returning the subcomponent" > someSubComponent ifNil: [someSubcomponent := OtherComponent new]. > > When you render MyComponent... boom, because > #MyComponent>>#renderContentOn: will be called recursively. > > Regards, > > Esteban A. Maringolo |
We also have an OutOfMemory exception, we even have tests provoking such a situation (check usage).
However, I believe such tight loops end up in JIT machine code. Checking stack overflow on each stack manipulation is costly. But I totally agree that we should try to catch these situations even if there is a cost. > On 25 Apr 2019, at 14:39, Esteban Maringolo <[hidden email]> wrote: > > I just checked in VisualWorks, where I also develop Seaside and also > make these mistakes, and these recursions launch a "Process Monitor > Emergency: No space left" process monitor, with the option of killing > any running Smalltalk process. > > Regards, > > Esteban A. Maringolo > > On Thu, Apr 25, 2019 at 9:30 AM Esteban Maringolo <[hidden email]> wrote: >> >> Hi, >> >> Is there a way to add deep recursion protection to the system? >> >> eg. >> RecursiveObject>>#recurse >> self recurse >> >> So calling `RecursiveObject new recurse` in Dolphin raises an >> exception right away... >> >> Throws the following error with this stack: >> ProcessorScheduler>>stackOverflow: >> [] in ProcessorScheduler>>vmi:list:no:with: >> BlockClosure>>ifCurtailed: >> ProcessorScheduler>>vmi:list:no:with: >> RecursiveObject>>recurse >> RecursiveObject>>recurse >> >> In Pharo it goes forever until it hits the memory limit (3.6GiB), at >> which point doing an Alt+. is useless and you have to kill the VM. >> >> The example is pretty simple, but when doing Seaside rendering, it is >> easy to miss some return, causing the receiver to render recursively, >> turning your image useless. >> >> e.g. >> MyComponent>>renderContentOn: html >> html render: self someSubComponent >> >> MyComponent>>someSubComponent >> "Here I forget returning the subcomponent" >> someSubComponent ifNil: [someSubcomponent := OtherComponent new]. >> >> When you render MyComponent... boom, because >> #MyComponent>>#renderContentOn: will be called recursively. >> >> Regards, >> >> Esteban A. Maringolo > |
I downloaded a fresh 7.0.3 image and VM, created the above class and
method, and called it. The image is running in Ubuntu within a VirtualBox with 4GB RAM. Such exception was not triggered in my image when it actually filled all the available OS RAM, and I had to kill it using the operative system process manager. If I call it and press Alt+. right away it halts the execution (if running on the main thread). In Dolphin, because it is not JITted, it is instantaneous after a long chain of calls. Crashing the image by such a simple to make mistake should be avoided. Fortunately we have other tools such as Epicea to recover changes, but even still. Regards, Esteban A. Maringolo On Thu, Apr 25, 2019 at 9:47 AM Sven Van Caekenberghe <[hidden email]> wrote: > > We also have an OutOfMemory exception, we even have tests provoking such a situation (check usage). > > However, I believe such tight loops end up in JIT machine code. > > Checking stack overflow on each stack manipulation is costly. > > But I totally agree that we should try to catch these situations even if there is a cost. > > > On 25 Apr 2019, at 14:39, Esteban Maringolo <[hidden email]> wrote: > > > > I just checked in VisualWorks, where I also develop Seaside and also > > make these mistakes, and these recursions launch a "Process Monitor > > Emergency: No space left" process monitor, with the option of killing > > any running Smalltalk process. > > > > Regards, > > > > Esteban A. Maringolo > > > > On Thu, Apr 25, 2019 at 9:30 AM Esteban Maringolo <[hidden email]> wrote: > >> > >> Hi, > >> > >> Is there a way to add deep recursion protection to the system? > >> > >> eg. > >> RecursiveObject>>#recurse > >> self recurse > >> > >> So calling `RecursiveObject new recurse` in Dolphin raises an > >> exception right away... > >> > >> Throws the following error with this stack: > >> ProcessorScheduler>>stackOverflow: > >> [] in ProcessorScheduler>>vmi:list:no:with: > >> BlockClosure>>ifCurtailed: > >> ProcessorScheduler>>vmi:list:no:with: > >> RecursiveObject>>recurse > >> RecursiveObject>>recurse > >> > >> In Pharo it goes forever until it hits the memory limit (3.6GiB), at > >> which point doing an Alt+. is useless and you have to kill the VM. > >> > >> The example is pretty simple, but when doing Seaside rendering, it is > >> easy to miss some return, causing the receiver to render recursively, > >> turning your image useless. > >> > >> e.g. > >> MyComponent>>renderContentOn: html > >> html render: self someSubComponent > >> > >> MyComponent>>someSubComponent > >> "Here I forget returning the subcomponent" > >> someSubComponent ifNil: [someSubcomponent := OtherComponent new]. > >> > >> When you render MyComponent... boom, because > >> #MyComponent>>#renderContentOn: will be called recursively. > >> > >> Regards, > >> > >> Esteban A. Maringolo > > > > |
What if you did something like:
RecursiveObject>>#recurse | data | data := Array new: 1e5. self recurse. ^ data This way, you should run out of heap before the stack gets too large, since you allocate and hold on to an array in each frame. > On 25 Apr 2019, at 14:56, Esteban Maringolo <[hidden email]> wrote: > > I downloaded a fresh 7.0.3 image and VM, created the above class and > method, and called it. > > The image is running in Ubuntu within a VirtualBox with 4GB RAM. > > Such exception was not triggered in my image when it actually filled > all the available OS RAM, and I had to kill it using the operative > system process manager. > > If I call it and press Alt+. right away it halts the execution (if > running on the main thread). > In Dolphin, because it is not JITted, it is instantaneous after a long > chain of calls. > > Crashing the image by such a simple to make mistake should be avoided. > Fortunately we have other tools such as Epicea to recover changes, but > even still. > > > Regards, > > Esteban A. Maringolo > > On Thu, Apr 25, 2019 at 9:47 AM Sven Van Caekenberghe <[hidden email]> wrote: >> >> We also have an OutOfMemory exception, we even have tests provoking such a situation (check usage). >> >> However, I believe such tight loops end up in JIT machine code. >> >> Checking stack overflow on each stack manipulation is costly. >> >> But I totally agree that we should try to catch these situations even if there is a cost. >> >>> On 25 Apr 2019, at 14:39, Esteban Maringolo <[hidden email]> wrote: >>> >>> I just checked in VisualWorks, where I also develop Seaside and also >>> make these mistakes, and these recursions launch a "Process Monitor >>> Emergency: No space left" process monitor, with the option of killing >>> any running Smalltalk process. >>> >>> Regards, >>> >>> Esteban A. Maringolo >>> >>> On Thu, Apr 25, 2019 at 9:30 AM Esteban Maringolo <[hidden email]> wrote: >>>> >>>> Hi, >>>> >>>> Is there a way to add deep recursion protection to the system? >>>> >>>> eg. >>>> RecursiveObject>>#recurse >>>> self recurse >>>> >>>> So calling `RecursiveObject new recurse` in Dolphin raises an >>>> exception right away... >>>> >>>> Throws the following error with this stack: >>>> ProcessorScheduler>>stackOverflow: >>>> [] in ProcessorScheduler>>vmi:list:no:with: >>>> BlockClosure>>ifCurtailed: >>>> ProcessorScheduler>>vmi:list:no:with: >>>> RecursiveObject>>recurse >>>> RecursiveObject>>recurse >>>> >>>> In Pharo it goes forever until it hits the memory limit (3.6GiB), at >>>> which point doing an Alt+. is useless and you have to kill the VM. >>>> >>>> The example is pretty simple, but when doing Seaside rendering, it is >>>> easy to miss some return, causing the receiver to render recursively, >>>> turning your image useless. >>>> >>>> e.g. >>>> MyComponent>>renderContentOn: html >>>> html render: self someSubComponent >>>> >>>> MyComponent>>someSubComponent >>>> "Here I forget returning the subcomponent" >>>> someSubComponent ifNil: [someSubcomponent := OtherComponent new]. >>>> >>>> When you render MyComponent... boom, because >>>> #MyComponent>>#renderContentOn: will be called recursively. >>>> >>>> Regards, >>>> >>>> Esteban A. Maringolo >>> >> >> > |
Hi Sven,
On Thu, Apr 25, 2019 at 10:04 AM Sven Van Caekenberghe <[hidden email]> wrote: > This way, you should run out of heap before the stack gets too large, since you allocate and hold on to an array in each frame. I don't understand the purpose of such expression, since I'm not writing recursive code, where I pay special attention or save the image before running it, but I'm trying to find a way around accidental deep recursions. However I ran these examples in Dolphin and Pharo 7, and in Dolphin it triggers an memory exhaustion exception right away, and in Pharo it grows in memory use, slower than with the previous example, but with the same behavior (unresponsive image once the memory fills the available OS memory). Regards, Esteban A. Maringolo |
> On 25 Apr 2019, at 15:27, Esteban Maringolo <[hidden email]> wrote: > > Hi Sven, > > On Thu, Apr 25, 2019 at 10:04 AM Sven Van Caekenberghe <[hidden email]> wrote: >> This way, you should run out of heap before the stack gets too large, since you allocate and hold on to an array in each frame. > > I don't understand the purpose of such expression, since I'm not > writing recursive code, where I pay special attention or save the > image before running it, but I'm trying to find a way around > accidental deep recursions. I know, it was an experiment. > However I ran these examples in Dolphin and Pharo 7, and in Dolphin it > triggers an memory exhaustion exception right away, and in Pharo it > grows in memory use, slower than with the previous example, but with > the same behavior (unresponsive image once the memory fills the > available OS memory). Too bad, this is a VM issue anyway. > Regards, > > Esteban A. Maringolo > |
On Thu, Apr 25, 2019 at 10:41 AM Sven Van Caekenberghe <[hidden email]> wrote:
> > On 25 Apr 2019, at 15:27, Esteban Maringolo <[hidden email]> wrote: > > However I ran these examples in Dolphin and Pharo 7, and in Dolphin it > > triggers an memory exhaustion exception right away, and in Pharo it > > grows in memory use, slower than with the previous example, but with > > the same behavior (unresponsive image once the memory fills the > > available OS memory). > > Too bad, this is a VM issue anyway. I think this is user related (those who accidentally create deep recursions), but should this be reported on the vm-list? Regards, Esteban A. Maringolo |
Free forum by Nabble | Edit this page |