avoitishin / xray-16

XRAY 16 Engine Modifications
Other
10 stars 6 forks source link

'clsid' crash, _g.script #16

Closed BeaconDev closed 9 years ago

BeaconDev commented 9 years ago

We've been running into a really strange issue lately, where the game will randomly crash with the following error:

FATAL ERROR

[error]Expression : fatal error [error]Function : CScriptEngine::lua_error [error]File : ..\xrServerEntities\script_engine.cpp [error]Line : 180 [error]Description : [error]Arguments : LUA error: ...n\stalker call of pripyat\gamedata\scripts_g.script:331: attempt to call method 'clsid' (a nil value)

stack trace:

0023:0077723F xrCore.dll, xrDebug::fatal() 0023:0A441835 xrGame.dll, CDialogHolder::IgnorePause()

It's very random, I can't seem to replicate it, and doesn't seem caused by anything specific, it just happens.

What we seem to be seeing is that our random weapon system is calling IsStalker() on an object when it spawns to check whether to proceed with spawning weapons and ammo, this function then checks for a clsid, which returns nil and causes the crash.

That's what we think, at least!

Hoping you guys could perhaps shed some light or more info on the issue.

revolucas commented 9 years ago

Have you made any script changes to _g.script to utilize the new is_stalker game_object method?

I suggest changing get_clsid:

function get_clsid(obj)
    if not (obj) then
        callstack()
        printf("ERROR: get_clsid - obj is nil!")
        return
    end
    if not (obj.clsid) then
        callstack()
        printf("ERROR: no clsid method for %s",obj:name())
        return
    end
    return obj:clsid()
end

Then replace this function in _g.script:

function callstack()
    if (log1 and debug and type(debug.traceback) == 'function') then 
        log1(debug.traceback('\n', 2))
    end
end

Here is my printf function if you don't have one already:

function printf(fmt,...)
    if not (fmt) then return end
    local fmt = tostring(fmt)

    if (select('#',...) >= 1) then
        local i = 0
        local p = {...}
        local function sr(a)
            i = i + 1
            if (type(p[i]) == 'userdata') then
                return 'userdata'
            end
            return tostring(p[i])
        end
        fmt = string.gsub(fmt,"%%s",sr)
    end

    if (log1) then 
        log1(fmt)
    else 
        get_console():execute("load ~#debug msg:"..fmt)
    end 
end

Which will only work if you have the lua logging feature enabled using the -dbg in command line.

You asked about the command line on epicstalker forums. You need to create a shortcut to bin\xrEngine.exe from inside the main directory. Keep in mind it's possible you may not get a crash log when using a shortcut to xrEngine if you use Windows 8.1 for unknown reasons.

All the above should help you get more information about what is being nil, when and why.

BeaconDev commented 9 years ago

I understand how to do a command line alteration, but the game won't launch with -dbg set. Steam says I'm playing the game for 5 seconds, but the .exe never launches and then nothing happens.

revolucas commented 9 years ago

You have to create your own shortcut to xrEngine.exe. You cannot use the stalker-cop.exe. If you add command line through steam library it adds the command line to the launcher and game will not launch.

BeaconDev commented 9 years ago

Yeah I did that too, but it didn't work. It's ok, Smokem recommended, over in the other issue, to use a .cmd instead which worked fine.

BeaconDev commented 9 years ago

Ok, here's the latest. I'm using the new get_clsid() and callstack() functions you provided Alun, here's my log: http://puu.sh/ffhQP/3cd0bf653b.log

Current crash is as follows:

[error]Expression : fatal error [error]Function : CScriptEngine::lua_error [error]File : ..\xrServerEntities\script_engine.cpp [error]Line : 184 [error]Description : [error]Arguments : LUA error: ...n\stalker call of pripyat\gamedata\scripts_g.script:343: attempt to call method 'name' (a nil value)

stack trace:

0023:0056722F xrCore.dll, xrDebug::fatal() 0023:060206D5 xrGame.dll, CDialogHolder::IgnorePause() 0023:0600A8A9 xrGame.dll, CDialogHolder::IgnorePause()

Line 343 is the line: printf("ERROR: no clsid method for %s",obj:name())

revolucas commented 9 years ago

obj is nil. So someplace in your scripts you have a nil object being passed to one of these functions: (IsStalker IsMonster isWeapon isArtefact) These functions support either passing the object or passing the clsid. But somewhere for you they are both nil.

Callstack didn't work for you, it should show the last script to call this function. Since I posted almost 3 weeks ago, log was fixed. You must replace 'log1' with just 'log' or just replace all the callstack() with print_stack(), since it's now an exported engine function.

Or if you have a scripter on your team ask him to use notepad++ and to add extra checks to all the places these functions are used to make sure either the game object being passed or the clsid is not nil.