Hi,
I'm having minor problems getting my head around the right way to write a very simple ToGo GUI app that has an unusually simple UI. Like the app I mentioned yesterday, it just sends some data to a server by (blocking) TCP/IP , reads the response, and (optionally) displays it to the user. The catch is that the GUI is built entirely out of message boxes. It either starts up and immediately does a MessageBox>>warning: if there's some problem with the settup. Or else it starts up, sends the data, and then does a MessageBox>>notify: when the data comes back from the server. In either case it exits as soon as the user clicks OK on the popup box. I've got it to the point where it works, sort of, but I've been adding stuff more-or-less at random and I don't know if I'm missing something or doing too much. First, I vaguely remember some post by Blair (which I can't find now, not even on Google) in which he said something about doing a #forkMainIfMain if using MessageBoxes before the GUI system was settup. I'm calling #forkMainIfMain from my app's MySessionManager>>main, before I do anything else, but I suspect that it's making no difference. Is it necessary here ? Second, I'm not sure how the make the app exit early (e.g, if the wrong parameters have been set). I'm calling #exit: 2, *and* doing an early return from #main, *and* setting a flag for my #keepAlive method (see below), and it seems as if I'm probably doing more than I need to, just to exit an application. Third, I've overridden #keepAlive so that it just checks a flag to see if the #main has finished (possibly early-outed), if the flag is set then it calls #quit: with the same exit status that was recorded when a call to #exit: was made (I overrode #exit: to save the status). Is that necessary, I know I need a #keepAlive method, but could I make it simpler and just always ignore it, relying on the call to #exit: to ensure that the app dies at the right time ? Alternatively, would the right thing be to set the flag and early-out from main, and rely on #keepAlive calling #quit: (and what is the difference between #quit: and #exit: anyway) ? Lastly, I'm getting a warning written to the Windows debug stream: WARNING: no processes are Ready to run in the period between my sending the data to the server and getting a response. I *think* that means that the idle process hasn't been set up properly, in which case there's an architectural problem with the way I'm doing things. The app does work, however, so is that a warning I should try to do anything about ? If so what ? Thanks in advance for any help or insight. -- chris |
> It either starts up and immediately does a MessageBox>>warning: if there's
some > problem with the settup. Or else it starts up, sends the data, and then does a > MessageBox>>notify: when the data comes back from the server. In either case > it exits as soon as the user clicks OK on the popup box. Is your problem that you can't use MessageBox before you show a Shell in the deployed app? If yes try the following: (MessageBox new) taskModal; caption: 'myCap'; errorMsg: 'myMessage'. I have no idea why it works. |
In reply to this post by Chris Uppal-3
Chris
You wrote in message news:3ee6f1cb$0$45175$[hidden email]... > Hi, > > I'm having minor problems getting my head around the right way to write a very > simple ToGo GUI app that has an unusually simple UI. > .... > I've got it to the point where it works, sort of, but I've been adding stuff > more-or-less at random and I don't know if I'm missing something or doing too > much. > > First, I vaguely remember some post by Blair (which I can't find now, not even > on Google) in which he said something about doing a #forkMainIfMain if using > MessageBoxes before the GUI system was settup. I'm calling #forkMainIfMain > from my app's MySessionManager>>main, before I do anything else, but I suspect > that it's making no difference. Is it necessary here ? No. It is true that you would need to do that if using a non-task modal message box at some point in the startup processing _before_ #main. This is because all the system startup happens on the single high priority startup thread. This thread is the same one as that which was running when the image was saved (i.e. the old main thread), although this is immaterial. As one of the last actions in the startup the new main UI thread is started. Your override of #main is called from this thread as the result of a deferred action being processed when the message loop first becomes empty. You can safely open a message box from #main, or any subsidiary function, which can readily be demonstrated by modifying HelloWordSessionManager>>main as follows, and then deploying and running the resulting .exe: main (MessageBox confirm: 'Are you sure you want to say hello') ifTrue: [self mainShellClass new show position: 0 @ 0] Non-task modal message boxes cause problems in early startup stages (or after shutdown has been initiated), because they implicitly start another UI process so they can block the one that wants to open the message box. This is undesirable because it may mean processing occurring before the system has properly initialised itself, or (if on shutdown) it might allow further processing to occur rather too late in the life of the session. You can use message boxes at these times by making them task modal - these start up a nested message loop, and effectively block the UI thread while allowing repainting etc. However it is generally not necessary to intervene in the startup or shutdown activities of the session manager, and from what you say you are not doing that anyway. > > Second, I'm not sure how the make the app exit early (e.g, if the wrong > parameters have been set). I'm calling #exit: 2, *and* doing an early return > from #main, *and* setting a flag for my #keepAlive method (see below), and it > seems as if I'm probably doing more than I need to, just to exit an > application. > > Third, I've overridden #keepAlive so that it just checks a flag to see if the > #main has finished (possibly early-outed), if the flag is set then it calls > #quit: with the same exit status that was recorded when a call to #exit: was > made (I overrode #exit: to save the status). Is that necessary, I know I need > a #keepAlive method, but could I make it simpler and just always ignore it, > relying on the call to #exit: to ensure that the app dies at the right time ? > Alternatively, would the right thing be to set the flag and early-out from > main, and rely on #keepAlive calling #quit: (and what is the difference > between #quit: and #exit: anyway) ? In the above example the application will exit if you press 'No'. This is because the standard keep alive processing will detect the absence of any windows and automatically shut down the system. Since you have no windows, you need to prevent this happenning. As you know, the way to do this is to override #keepAlive, and it is easiest to just override this to do nothing if you have some point you can explicitly trigger shutdown. SessionManager>>exit: posts a WM_QUIT message to the application. This is the "approved" way to terminate a Windows application, and in Dolphin this is detected in the message loop (see InputState>>pumpMessage:), and results in a #onQuit: event being sent back to the SessionManager. The important point about is this is that the WM_QUIT is only a request, and it is possible to override #onQuit: to prompt the user or otherwise decline the request - any message box here should be taskModal to avoid getting more than one of them popping up BTW. See DevelopmentSessionManager>>onQuit: for an example. Note that #onQuit: may also get invoked when Windows itself is shutting down, and again it is possible to veto this shutdown by returning false from #onQuit:. Generally speaking one does not need to differentiate between the end of the Windows session and normal application shutdown - certainly the development system does not, and prompts to save the image using the same mechanism in both cases. So the difference between #quit: and #exit: is that the latter posts a WM_QUIT to the message loop that may result in the former being called if the application accepts the request to exit. #quit: calls the VM primitive which actually shuts down the system. In your case even though you don't have any Windows, I would still call #exit:, since the WM_QUIT will cleanly close any windows open in your app (message boxes, hidden windows, etc), and the route it takes will be the same as that for windows session termination which you need to allow for anyway. You probably won't need to override #onQuit:, etc. > > Lastly, I'm getting a warning written to the Windows debug stream: > WARNING: no processes are Ready to run > in the period between my sending the data to the server and getting a response. > I *think* that means that the idle process hasn't been set up properly, in > which case there's an architectural problem with the way I'm doing things. The > app does work, however, so is that a warning I should try to do anything about > ? If so what ? It does indeed mean that the VM found that no processes were in a runnable state. This will only happen if the idle process gets blocked for some reason. It causes the VM to send an idle panic interrupt to the Processor global, which gets forwarded to InputState>>idlePanic, the instance of InputState being the owner of main UI and idle processes. InputState responds by starting a new idle process. You could insert some debug at this point to dump out the stack of the current idler onto the system debug trace stream - I'd do this with outputDebugString() directly, rather than using the Trace global, as that is an instance of DebugTraceStream which has a mutex protecting against more than one process trying to output at once. You probably don't want to cause more process system primitives to be called when handling an idle panic interrupt! You might find the issue goes away if you take out the #forkMainIfMain anyway. In summary: 1) Remove the #forkMainIfMain 2) Override SessionManager>>keepAlive to do nothing (hmmm, the keep alive method is actually responsible for killing the system, bit of bad naming that) 3) Call #exit: to shut down when you are ready. 4) Be aware that non-task modal message boxes will cause a new main UI process to be started, so use a task modal box when this may be undesirable. In your case you might want to just use these by default, since the main purpose of the other sort is to avoid going into a "mode" when multiple windows are displayed. Regards Blair |
In reply to this post by Chris Uppal-3
Hi Chris,
As Maxim mentioned, using a TaskModal MessageBox will stop the application immediately exiting. > First, I vaguely remember some post by Blair (which I can't find now, > not even on Google) in which he said something about doing a > #forkMainIfMain if using MessageBoxes before the GUI system was > settup. I'm calling #forkMainIfMain from my app's > MySessionManager>>main, before I do anything else, I think you have this around the wrong way. Anything that causes a new main process to be forked can cause the application to exit early if there are no visibleWindows. (See InputState>>aboutToIdle). Showing a non-taskModal MessageBox or sending #forkMainIfMain will cause a new main to be forked. Even if you were not sending #forkMainIfMain yourself, if you are using a Socket, and it blocks, then it will send #forkMainIfMain (See Socket>>waitOn:) The solution is to either make sure you show your shell before using a socket, or as you have done, take manual control with your own implementation of #keepAlive. > Second, I'm not sure how the make the app exit early (e.g, if the > wrong parameters have been set). I'm calling #exit: 2, *and* doing > an early return from #main, *and* setting a flag for my #keepAlive > method (see below), and it seems as if I'm probably doing more than I > need to, just to exit an application. In a similar situation, I just send #exit:. > Third, I've overridden #keepAlive so that it just checks a flag to > see if the #main has finished (possibly early-outed), if the flag is > set then it calls #quit: with the same exit status that was recorded > when a call to #exit: was made (I overrode #exit: to save the > status). Is that necessary, I know I need a #keepAlive method, but > could I make it simpler and just always ignore it, relying on the > call to #exit: to ensure that the app dies at the right time ? > Alternatively, would the right thing be to set the flag and early-out > from main, and rely on #keepAlive calling #quit: I have an application where I set a flag to stop #keepAlive quiting at certain stages during startup/shutdown. I decided not to always ignore it because it seemed like a good backup to ensure that my process would terminate if something unexpected occurs. > (and what is the > difference between #quit: and #exit: anyway) ? I believe that #exit is more graceful because it first calls PostQuitMessage and responds to the resulting WM_QUIT by sending #quit (in InputState>>pumpMessage:) #quit then does the graceful shutdown of the image. I am not sure what the consequences are of not calling the PostQuitMessage function, but I have done it plenty of times without seeing any obvious problems. > > Lastly, I'm getting a warning written to the Windows debug stream: > WARNING: no processes are Ready to run I am also seeing this. Steve -- Steve Waring Email: [hidden email] Journal: http://www.stevewaring.net/blog/home/index.html |
Steve,
> > Second, I'm not sure how the make the app exit early (e.g, if the > > wrong parameters have been set). I'm calling #exit: 2, *and* doing > > an early return from #main, *and* setting a flag for my #keepAlive > > method (see below), and it seems as if I'm probably doing more than > > I need to, just to exit an application. > > In a similar situation, I just send #exit:. That didn't seem to be enough. My #main just went on processing after the call to #exit. I have to early-out from #main *and* call #exit.. > I have an application where I set a flag to stop #keepAlive quiting at > certain stages during startup/shutdown. I decided not to always > ignore it because it seemed like a good backup to ensure that my > process would terminate if something unexpected occurs. That's a good point. What I've now ended up with is something like: main [self exit: (self realMain). ^ self] on: Exception do: [... default handling...]. self exit: 3. realMain "answers exit status" (..a check..) ifFalse: [^ 1]. (..another check..) ifFalse: [^ 1]. ... real processing ... ^ (... processing worked..) ifTrue: [0] ifFalse: [1]. where I've overriden #exit: to set the "I've finished" flag before doing a super-send. #keepAlive just checks the flag and does a #quit: if the flag is set. Seems to work OK, and doesn't feel nearly as clumsy as what I had before. I think if I needed to exit directly from deeper into the call chain from #main (i.e. without having entered the message-loop), then I'd throw a special ExitException in order to get straight back to the #main. Fortunately I don't have to bother in this case. > > Lastly, I'm getting a warning written to the Windows debug stream: > > WARNING: no processes are Ready to run > > I am also seeing this. Thanks for the confirmation. I now suspect it to be a bug. See my response to Blair. -- chris |
In reply to this post by Blair McGlashan
Blair,
Thank you for the information and clarifications. > [...] You can safely > open a message box from #main, or any subsidiary function Good. The call to #forkMainIfMain goes on the scrap heap. > In the above example the application will exit if you press 'No'. > This is because the standard keep alive processing will detect the > absence of any windows and automatically shut down the system. Since > you have no windows, you need to prevent this happening. As you > know, the way to do this is to override #keepAlive, and it is easiest > to just override this to do nothing if you have some point you can > explicitly trigger shutdown. Just to add. Without the #keepAlive override, the app didn't die at any reliable time. Sometimes it died before sending the message, sometimes it was able to stay around long enough to send the message but not read the response, sometimes it ran to completion. I'm assuming that that's what would be expected if the absence of windows is detected by a different Process. > > Lastly, I'm getting a warning written to the Windows debug stream: > > WARNING: no processes are Ready to run > > in the period between my sending the data to the server and getting > > a response. [...] > > It does indeed mean that the VM found that no processes were in a > runnable state. This will only happen if the idle process gets > blocked for some reason. It causes the VM to send an idle panic > interrupt to the Processor global, which gets forwarded to > InputState>>idlePanic, the instance of InputState being the owner of > main UI and idle processes. InputState responds by starting a new > idle process. You could insert some debug at this point [...] Quite a bit of tracing later, I'm convinced that the problem is that the SessionManager hasn't started an idle process at all. I've added: self inputState ensureIdlerRunning. at the start of my #main, and the problem goes away completely. A bug ? Or something that I just didn't realise that I was expected to do myself ? On the way, I found that I was getting sporadic errors generated, so I think there may be a real bug here. It seemed, when it happened at all, to be something going wrong as a new Idler was started after the panic. I added some tracing to the relevant methods of InputState that sent the Process name and method names to the debug stream as they were invoked; I also added the Process name to my own logging. Here's an annotated trace of the app deciding to exit with an error popup (rather than send any data to the server at all): (1st column is time in seconds, 2nd column is thread name, rest is logging) # We start here, the first messages are from InputState # before my #main is entered. # Note that there is no call to InputState>>forkIdler. # The second line comes from logging added to # the # idler isNil ifFalse: [...] # clause in #primaryStartup. 0.00000000 Main: in: InputState>>primaryStartup 0.00526911 Main: Killing existing idler 0.00857455 Main: in: InputState>>guiStartup 0.00980851 Main: in: InputState>>forkMain 0.01004681 Main: in: InputState>>aboutToForkUI # Now we are in my #main. The first thing I do is change # the process name to 'Snippet' (the name of my app) so # it doesn't get confused with any new # Process called main. 0.01048066 Snippet: Startup -- Changed Process name to 'Snippet' # Now snippet decides it has invalid arguments so it should # show a popup error message and exit. # Showing the popup causes the normal forking of a new # main Process. 0.01084048 Snippet: About to show message: ... 0.01115449 Snippet: in: InputState>>forkMain 0.01211048 Snippet: in: InputState>>aboutToForkUI # Now Snippet has gone idle waiting for the response from the user. # At this point the VM causes an idle panic 0.02256879 WARNING: No processes are Ready to run # We are in #idlePanic, the second line shows that the 'idler' # instvar of the InputState is nil. However the Process # that is fielding the VM interrupt is called 'Idler'. I don't # understand this. 0.02298002 Idler: in: InputState>>idlePanic 0.02315350 Idler: Idler is: nil # Now we are in #forkIdler. Sometimes that worked as # you would expect and start a new idler, other times, # as on this occasion, it would throw an exception and # write a dump file. # NB: 'InputState>>idlePanic' is the name of the Process # here. 0.02348176 InputState>>idlePanic: in: InputState>>forkIdler 0.02413798 Dolphin: Writing dump to '....ERRORS' # Some Process is now starting a new idleLoop. # I don't know if this is the one mentioned above, # or the one forked from InputState>>forkIdler which # has been given a new name. 0.16015527 Idler: in: InputState>>idleLoop # At this point there's a new popup to inform me that: # Primitive Process>>primTerminate failed (2) # I (the user) cancel that, and my application exits 3.76724304 Snippet: Exit with: 2 3.76770036 Idler: in: InputState>>ensureMainRunning And that's the end of the log. I get a similar sort of log if I actually do send data to the server, the only difference is that the idle panic occurs when the app's waiting for the response. It is similar in that it *sometimes* causes the above error when it tries to start the new idler. I never did see the error without the tracing, which further suggests that there's some sort of timing issue here. In both cases, the generated dump file is similar. As it say, the whole problem goes away if I do an #ensureIdlerRunning early on in my #main. So maybe the problem is just that there is no idler, but it does seem odd that starting one causes sporadic errors. The dump file follows, sorry about the munged formatting. -- chris ************************** Dolphin Virtual Machine Dump Report *************************** 12:57:10, 12/06/2003: Primitive Process>>primTerminate failed (2) *----> VM Context <----* Process: {07430004:size 214 words, suspended frame 07430351, priority 1, callbacks 0 last failure 2:nil, FPE mask 3, thread nil} Active Method: SessionManager>>logError: IP: 0736C81D (13) SP: 07430408 BP: 074303E0 (231) ActiveFrame: {074303E4: cf 074303C9, sp 074303F8, bp 074303E0, ip 5, SnippetGUISessionManager(SessionManager)>>logError:} receiver: a SnippetGUISessionManager arg[0]: a Error New Method: VMLibrary>>dump:path:stackDepth:walkbackDepth: Message Selector: #dump:path:stackDepth:walkbackDepth: *----> Stack Back Trace <----* {074303E4: cf 074303C9, sp 074303F8, bp 074303E0, ip 5, SnippetGUISessionManager(SessionManager)>>logError:} receiver: a SnippetGUISessionManager arg[0]: a Error {074303C8: cf 074303AD, sp 074303D8, bp 074303C4, ip 4, SnippetGUISessionManager(SessionManager)>>unhandledException:} receiver: a SnippetGUISessionManager arg[0]: a Error {074303AC: cf 07430391, sp 074303BC, bp 074303A8, ip 4, SnippetGUISessionManager(SessionManager)>>onUnhandledError:} receiver: a SnippetGUISessionManager arg[0]: a Error {07430390: cf 07430379, sp 074303A0, bp 07430390, ip 5, Error>>defaultAction} receiver: a Error {07430378: cf 07430365, sp 07430388, bp 07425D68, ip 57, Error(Exception)>>_propagateFrom:} receiver: a Error arg[0]: a ExceptionHandler temp[0]: nil temp[1]: a ExceptionHandler temp[2]: nil temp[3]: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) temp[4]: nil {07430364: cf 07430349, sp 07430374, bp 07430360, ip 6, Error(Exception)>>_propagate} receiver: a Error temp[0]: nil {07430348: cf 07430331, sp 07430358, bp 07430348, ip 12, Error(Exception)>>signal} receiver: a Error {07430330: cf 07430315, sp 07430340, bp 0743032C, ip 7, Error(Exception)>>signal:} receiver: a Error arg[0]: 'Primitive Process>>primTerminate failed (2)' {07430314: cf 074302F9, sp 07430324, bp 07430310, ip 5, Error class(Exception class)>>signal:} receiver: Error arg[0]: 'Primitive Process>>primTerminate failed (2)' {074302F8: cf 074302DD, sp 07430308, bp 074302F4, ip 4, Process(Object)>>error:} receiver: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) arg[0]: 'Primitive Process>>primTerminate failed (2)' {074302DC: cf 074302C1, sp 074302EC, bp 074302D8, ip 21, Process(Object)>>primitiveFailed} receiver: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) temp[0]: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) {074302C0: cf 074302A9, sp 074302D0, bp 074302C0, ip 8, Process>>primTerminate} receiver: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) {074302A8: cf 07430291, sp 074302B8, bp 074302A8, ip 15, Process>>shutdown} receiver: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) {07430290: cf 07430279, sp 074302A0, bp 07430290, ip 10, Process>>kill} receiver: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) {07430278: cf 0743025D, sp 07430288, bp 07430274, ip 6, ProcessorScheduler>>kill:} receiver: a ProcessorScheduler arg[0]: nil {0743025C: cf 07430241, sp 0743026C, bp 074259E8, ip 11, [] in ProcessorScheduler>>vmi:list:no:with:} receiver: a ProcessorScheduler arg[0]: 532 arg[1]: a LinkedList arg[2]: 9 arg[3]: nil {07430240: cf 0743022D, sp 07430258, bp 07425A90, ip 17, BlockClosure>>ifCurtailed:} receiver: [] @ 9535494 in nil arg[0]: [] @ 16 in ProcessorScheduler>>vmi:list:no:with: temp[0]: nil temp[1]: nil temp[2]: nil {0743022C: cf 07430219, sp 0743023C, bp 074259E8, ip 20, ProcessorScheduler>>vmi:list:no:with:} receiver: a ProcessorScheduler arg[0]: 532 arg[1]: a LinkedList arg[2]: 9 arg[3]: nil {07430218: cf 07430201, sp 07430228, bp 07430218, ip 1, InputState>>isInputAvailable} receiver: a InputState {07430200: cf 074301E9, sp 07430210, bp 07430200, ip 19, InputState>>idleNT} receiver: a InputState {074301E8: cf 074301D1, sp 074301F8, bp 074301E8, ip 16, InputState>>idleLoop} receiver: a InputState {074301D0: cf 074301BD, sp 074301E0, bp 0742B118, ip 18, [] in InputState>>forkIdler} receiver: a InputState temp[0]: nil {074301BC: cf 074301A9, sp 074301CC, bp 07428B80, ip 11, ExceptionHandler(ExceptionHandlerAbstract)>>markAndTry} receiver: a ExceptionHandler temp[0]: nil {074301A8: cf 0743018D, sp 074301B8, bp 074298B0, ip 21, [] in ExceptionHandler(ExceptionHandlerAbstract)>>try:} receiver: a ExceptionHandler arg[0]: [] @ 16 in InputState>>forkIdler temp[0]: a ExceptionHandler temp[1]: nil temp[2]: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) {0743018C: cf 07430179, sp 074301A4, bp 07429C30, ip 17, BlockClosure>>ifCurtailed:} receiver: [] @ 9535494 in nil arg[0]: [] @ 34 in ExceptionHandlerAbstract>>try: temp[0]: nil temp[1]: nil temp[2]: nil {07430178: cf 07430159, sp 07430188, bp 07430170, ip 4, BlockClosure>>ensure:} receiver: [] @ 15 in ExceptionHandlerAbstract>>try: arg[0]: [] @ 34 in ExceptionHandlerAbstract>>try: temp[0]: nil {07430158: cf 07430145, sp 07430168, bp 074298B0, ip 39, ExceptionHandler(ExceptionHandlerAbstract)>>try:} receiver: a ExceptionHandler arg[0]: [] @ 16 in InputState>>forkIdler temp[0]: a ExceptionHandler temp[1]: nil temp[2]: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) {07430144: cf 07430125, sp 07430154, bp 0743013C, ip 7, BlockClosure>>on:do:} receiver: [] @ 16 in InputState>>forkIdler arg[0]: a Signal arg[1]: [] @ 25 in InputState>>forkIdler {07430124: cf 07430109, sp 07430134, bp 0742B118, ip 37, [] in InputState>>forkIdler} receiver: a InputState temp[0]: nil {07430108: cf 074300F5, sp 07430120, bp 07429D90, ip 17, BlockClosure>>ifCurtailed:} receiver: [] @ 9535494 in nil arg[0]: [] @ 42 in InputState>>forkIdler temp[0]: nil temp[1]: nil temp[2]: nil {074300F4: cf 074300E1, sp 07430104, bp 0742B118, ip 53, [] in InputState>>forkIdler} receiver: a InputState temp[0]: nil {074300E0: cf 074300CD, sp 074300F0, bp 0742B448, ip 11, ExceptionHandler(ExceptionHandlerAbstract)>>markAndTry} receiver: a ExceptionHandler temp[0]: nil {074300CC: cf 074300B1, sp 074300DC, bp 07429C50, ip 21, [] in ExceptionHandler(ExceptionHandlerAbstract)>>try:} receiver: a ExceptionHandler arg[0]: [] @ 8 in InputState>>forkIdler temp[0]: nil temp[1]: nil temp[2]: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) {074300B0: cf 0743009D, sp 074300C8, bp 07429A10, ip 17, BlockClosure>>ifCurtailed:} receiver: [] @ 9535494 in nil arg[0]: [] @ 34 in ExceptionHandlerAbstract>>try: temp[0]: nil temp[1]: nil temp[2]: nil {0743009C: cf 0743007D, sp 074300AC, bp 07430094, ip 4, BlockClosure>>ensure:} receiver: [] @ 15 in ExceptionHandlerAbstract>>try: arg[0]: [] @ 34 in ExceptionHandlerAbstract>>try: temp[0]: nil {0743007C: cf 07430069, sp 0743008C, bp 07429C50, ip 39, ExceptionHandler(ExceptionHandlerAbstract)>>try:} receiver: a ExceptionHandler arg[0]: [] @ 8 in InputState>>forkIdler temp[0]: nil temp[1]: nil temp[2]: a Process('Idler' base 07430000 [ACTIVE] in SessionManager>>logError: sp=00000000 ip=8 list=nil) {07430068: cf 07430049, sp 07430078, bp 07430060, ip 7, BlockClosure>>on:do:} receiver: [] @ 8 in InputState>>forkIdler arg[0]: ProcessTermination arg[1]: [] @ 12 in BlockClosure>>newProcess {07430048: cf 00000001, sp 07430058, bp 07428BB0, ip 17, [] in BlockClosure>>newProcess} receiver: [] @ 8 in InputState>>forkIdler temp[0]: nil <Bottom of stack> ***** End of dump ***** |
Free forum by Nabble | Edit this page |