Crashed without any message

Posted by Jcl on Sun 19 Jul 2015 11:29 AM — 20 posts, 73,431 views.

#0
The process just terminated silently, so I can't provide any information to figure out what's wrong.
Adding some codes to try{} catch exceptions globaly and logging it might help.

This happens both old versions and the new version 4.98, once a week or more.
Australia Forum Administrator #1
What language? Lua doesn't have try/catch.
USA Global Moderator #2
I think Jcl means add a global try/catch to the C++ main.
#3
Fiendish said:

I think Jcl means add a global try/catch to the C++ main.


Yes. Both C++ main and the calling point between C++ and Lua might need the try/catch code.
Australia Forum Administrator #4
Even if there was one, I doubt it would tell us much, like why it happened. Last time this happened to you it was some subtle issue with triggers. Without seeing your setup it is hard to comment, but maybe you are somehow deleting something while it is still in use.
#5
Nick Gammon said:

Even if there was one, I doubt it would tell us much, like why it happened. Last time this happened to you it was some subtle issue with triggers. Without seeing your setup it is hard to comment, but maybe you are somehow deleting something while it is still in use.


I think the main program should work normally even if there was an unexpected exception or fatal error in plugins.
And, logs are helpful to find out what's wrong in plugin.
Australia Forum Administrator #6
What is the difference going to be from getting a message "Access Violation" (which it probably is) to just having it crash? Neither one really points at what the problem is.
#7
Nick Gammon said:

What is the difference going to be from getting a message "Access Violation" (which it probably is) to just having it crash? Neither one really points at what the problem is.


If the main program crashed, the connection would be disconnected, and the role will be offline and lose something.

If it continue to work, although one of the plugin had stopped working, but the rest is still fine. The role is alive at least.
And I have chance to reinstall the stopped plugin via another Idle-Check plugin.
Amended on Tue 21 Jul 2015 07:01 AM by Jcl
Australia Forum Administrator #8
Quote:

If it continue to work ...


Once you have corrupted RAM? Who knows what will happen next?

Perhaps if we get onto the real problem ...
Australia Forum Administrator #9
I think I tried the try...catch idea once. Either it didn't work at all, didn't do anything useful, or made things worse.

In an event-driven system like MFC, I don't even control the "main loop". That is part of the Windows event handler. The "first part" (where you might possibly add such a handler) is when an event comes in, like a keypress, mouse movement, or incoming byte from the server.

Even then, quite a few events result in the original event being consumed and another "helper" event pushed into the event queue.

I think you need to isolate down what is causing this. When did it start? At around that time, what did you change? New plugin? New trigger? Can you remove things (eg, plugins) and see if the problem goes away?
#10
The plugin does working normally at most time.
And it will does crash after unknown time, maybe one hour, one day, one week or more.
The problem is, when it crashed, the process terminated silently, without leaving any tips or output from mud server, so I have no way to find out the wrong place.

Can you leave me some stack trace or others helpful?
Australia Forum Administrator #11
In the release version, a stack trace wouldn't tell you much. If you had the debug version running, with the IDE, and it crashed, the stack trace might help.

I'm presuming one of your plugins is doing it, because no-one else has complained.

All I can suggest is the "binary" approach.

Remove half the plugins, test for a week. If it crashes, the problem is in the half you still have - if not, it is in the other half. Then remove half of what is left, and so on, until you narrow it down to one plugin.
Australia Forum Administrator #12
It would help if you gave a bit more detail about your setup.

Template:summary

Please provide a summary of your world configuration:

  • Either use the scripting Immediate window (Ctrl+I) to execute: Debug ("summary")

    or

  • Install the Summary plugin (see "Summary" feature) and type "summary"

Then copy the resulting information from the output window, and paste into a Forum message.

You need version 4.55 onwards of MUSHclient to do this.

#13
-------------- MUSHclient summary --------------

MUSHclient version: 4.98
Compiled: May 10 2015.
Time now: 星期四, 七月 23, 2015, 9:07 下午
Client running for: 2d 16h 36m 36s
World opened for: 2d 16h 36m 26s
World connected for: 1d 21h 59m 38s
Operating system: Windows Server 2003
Libraries: Lua 5.1.4, PCRE 8.36, PNG 1.6.17, SQLite3 3.8.8.3, Zlib 1.2.8
World name: 'magic', ID: 341807e7d26d7d980beabef6
-- Scripting --
Script language: Lua, enabled: yes
Scripting active: yes
Lua sandbox is 127 characters, DLL loading allowed: yes
Scripting prefix: '/'. External editor in use: NO.
Scripting for: 204.223058 seconds.
-- Triggers, aliases, timers, variables --
** Triggers: 2 in world file, triggers enabled: yes. [Triggers]
1 enabled, 2 regexp, 2485462 attempts, 0 matched, 2.877735 seconds.
** Aliases: 48 in world file, aliases enabled: yes. [Aliases]
47 enabled, 0 regexp, 18118111 attempts, 1127 matched, 8.472045 seconds.
** Timers: 2 in world file, timers enabled: yes. [Timers]
0 enabled, 0 fired.
Timers checked every 0.1 seconds.
** Variables: 0.
-- MCCP --
MCCP active, took 2.723442 seconds to decompress
MCCP received 13539406 compressed bytes, decompressed to 165551303 bytes.
MCCP compression ratio was: 8.2% (lower is better)
-- Plugins (Processing order) --
ID: fffe00000000000000000000, 'a_reconnect', (Lua, 0.006 s) Enabled [Al Ti Cb]
ID: ffff00000000000000000000, 'default', (Lua, 3.056 s) Enabled [Al Cb]
ID: fffff0000000000000000001, 'boss', (Lua, 0.396 s) DISABLED [Tr Al Va]
ID: ffff00000000000000000002, 'fuben', (Lua, 125.906 s) DISABLED [Tr Al Ti Va Cb]
ID: ffff00000000000000000001, 'quest', (Lua, 0.517 s) DISABLED [Tr Al Ti Va Cb]
ID: fffff0000000000000000003, 'team', (Lua, 0.016 s) Enabled [Tr Va Cb]
ID: fffff0000000000000000006, 'fighter', (Lua, 0.373 s) Enabled [Tr Al Ti Va]
** Plugins: 7 loaded, 4 enabled.
-- Comms --
Connect phase: 8 (Open). NAWS wanted: NO
Received: 13543582 bytes (13226 Kb)
Sent: 15274246 bytes (14916 Kb)
Received 470840 packets, sent 375481 packets.
Total lines received: 2486978
This connection: Sent 375471 lines, received 1870871 lines.
Telnet (IAC) received: DO: 44, DONT: 0, WILL: 35, WONT: 2, SB: 4 [Telnet]
-- MXP --
MXP active: NO, Pueblo mode: NO, Activated: On command
MXP tags received: 0
MXP entities received: 0
MXP errors: 0
-- Commands --
Commands in command history: 316
Speed walking enabled: yes. Speed walking prefix: .
Command stacking enabled: yes. Command stack character: ';'
Accelerators defined: 0
-- Miniwindows --
** Miniwindows: 0 loaded, 0 shown.
-- Output window --
Output pixels: width 1344, height: 581, font width: 8, font height: 16
can show 168 characters, wrapping at column 160, height 36 lines.
Output buffer: 4996 of 5000 lines.
-- Miscellaneous --
Logging: NO, tracing: NO
** SQLite3 databases: 0
Sound buffers in use: 0

---------------------- End summary ----------------------
#14
I found out the function which caused the crash,and write a simple test code to demonstrate it.


<aliases>
  <alias match="restart" enabled="y" script="restart" />
</aliases>

<script><![CDATA[

require "wait"

function restart()
  ResetPlugin()
  wait.make(function()
    -- Do something here.
    -- When we need to restart, we setup a timer to check it
    if IsTimer("restart_timer") ~= 0 then
      AddTimer("restart_timer", 0, 0, 3, "", timer_flag.Enabled, "restart_timer_func")
    else
      EnableTimer("restart_timer", true)
    end
  end)
end

function restart_timer_func()
  wait.make(function()
    -- Do restart check here
    Note("restart now")
    EnableTimer("restart_timer", false)
    DoAfterSpecial(0.1, "restart", 10)
  end)
end

function ResetPlugin()
  DeleteTemporaryTriggers()
  DeleteTemporaryTimers()
  DeleteTemporaryAliases()
end

]]></script>

Australia Forum Administrator #15
I don't understand why you are using "wait.make" here. None of the code you have uses the wait functions, so that is just adding unnecessary complexity.

I changed your code to:


function restart()
  ResetPlugin()
  -- Do something here.
  -- When we need to restart, we setup a timer to check it
  if IsTimer("restart_timer") ~= 0 then
    AddTimer("restart_timer", 0, 0, 3, "", timer_flag.Enabled, "restart_timer_func")
  else
    EnableTimer("restart_timer", true)
  end
end

function restart_timer_func()
  -- Do restart check here
  Note("restart now")
  EnableTimer("restart_timer", false)
  DoAfterSpecial(0.1, "restart", 10)
end


That didn't crash.

Also, what is it doing? The alias "restart" calls restart(), that adds a timer that calls restart_timer_func(), that calls restart() and so on. What does it all mean?
Australia Forum Administrator #16

DoAfterSpecial(0.1, "restart", 10)

...
function restart()
  ResetPlugin()
...

function ResetPlugin()
  DeleteTemporaryTriggers()
  DeleteTemporaryTimers()
  DeleteTemporaryAliases()
end


DoAfterSpecial creates a temporary timer. Then when that calls restart() that calls ResetPlugin() which deletes the timer which has the script which is currently running. Hence the client crashes. Don't do that.

I have added guard code into version 4.99 to not allow a temporary timer to be deleted if a script is running from it.

https://github.com/nickgammon/mushclient/commit/3386efc
#17
Nick Gammon said:

I don't understand why you are using "wait.make" here. None of the code you have uses the wait functions, so that is just adding unnecessary complexity.

I changed your code to:


function restart()
  ResetPlugin()
  -- Do something here.
  -- When we need to restart, we setup a timer to check it
  if IsTimer("restart_timer") ~= 0 then
    AddTimer("restart_timer", 0, 0, 3, "", timer_flag.Enabled, "restart_timer_func")
  else
    EnableTimer("restart_timer", true)
  end
end

function restart_timer_func()
  -- Do restart check here
  Note("restart now")
  EnableTimer("restart_timer", false)
  DoAfterSpecial(0.1, "restart", 10)
end


That didn't crash.

Also, what is it doing? The alias "restart" calls restart(), that adds a timer that calls restart_timer_func(), that calls restart() and so on. What does it all mean?


I did some quests by the plugin. The procedure is nested loop, and possible to pause in a given situation.
When paused, it need to be restarted at some special conditions and delete temporaries.

The code "wait.make" is needed to do someting at
-- Do something here.
and
-- Do restart check here
Amended on Tue 28 Jul 2015 01:04 PM by Jcl
Australia Forum Administrator #18
Oh OK. Well I think the big problem is deleting the temporary timers.
#19
Nick Gammon said:

Oh OK. Well I think the big problem is deleting the temporary timers.


I had tried to change
DoAfterSpecial(0.1, "restart", 10)
to
Execute("restart")
.

"DoAfterSpecial" cause to crash immediately, and "Execute" probably cause to crash at an unknown time after running normally for long times.