Multiple ternary operations in a row that have multiple checks inside of each, a la ( (condition && condition && condition) ? something : something), causes firstly vm crash with error message "DestroyAllThinkers failed" and than, on exit from Gzdoom, hard crash with a very dead marine.
Reproducing steps
1. drop attached archive on gzdoom
2. start new game
3. type into console 'netevent cube'
4. after vm crash type "exit" into console to trigger actual crash with crash report window
To prevent crash open archive/volume_filling/graph_storage.zc and comment lines 18-23.
Edit: its out of array bounds bug. Gzdoom just wont stops on first out of bounds write and continue doing it until it hit the end of a loop inside of which it was called.
Hard crach after exit on VM crash (4.7.0 - 4.8.2)
Moderator: GZDoom Developers
Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
-
- Posts: 1603
- Joined: Mon Jun 12, 2017 12:57 am
Hard crach after exit on VM crash (4.7.0 - 4.8.2)
You do not have the required permissions to view the files attached to this post.
Last edited by Apeirogon on Tue Aug 30, 2022 6:38 am, edited 2 times in total.
-
-
- Posts: 1552
- Joined: Wed May 13, 2009 3:15 am
- Graphics Processor: nVidia with Vulkan support
Re: Multiple ternary with multiple checks crash (4.7.0 - 4.8.2)
I doubt this has anything to do with the ternary operator at all. The crash happens in volume_filling/cube_node.zc at line 141, which is inside an OnDestroy() override, and the error says "tried to write to address zero". This likely indicates that there's a bug in the ZScript code. It's hard to tell without a deeper analysis, but I suppose that by commenting out the mentioned lines in volume_filling/graph_storage.zc the behavior of the code changes so that the bug is not triggered anymore. Nevertheless, the hard crash should probably not happen.
If you still think this is somehow related to the ternary operator, please provide a more concise example.
If you still think this is somehow related to the ternary operator, please provide a more concise example.
-
- Posts: 1603
- Joined: Mon Jun 12, 2017 12:57 am
Re: Multiple ternary with multiple checks crash (4.7.0 - 4.8.2)
Yes, its not a ternary operation, its out of array bounds bug. Commenting aforementioned 6 lines also comment array access functions, since condition and array access related function are in one line.
What is weird here is that instead of crashing after first out of bounds write, like it always doing in all cases, gzdoom continues to write into an array until it hit end of a loop, inside of which writing is happens, and only than crashes.
What is weird here is that instead of crashing after first out of bounds write, like it always doing in all cases, gzdoom continues to write into an array until it hit end of a loop, inside of which writing is happens, and only than crashes.
-
- Posts: 1603
- Joined: Mon Jun 12, 2017 12:57 am
Re: Multiple 'out of array bounds' bug (4.7.0 - 4.8.2)
Found a reason.
Overridden ondestroy virtual have leftover code from previous revision that writes pointer without checking is it null or not. So it goes like
Overridden ondestroy virtual have leftover code from previous revision that writes pointer without checking is it null or not. So it goes like
- Gzdoom executes 'out of array bounds' bug
- crashes
- tries to destroy loaded level and all related to it data
- enters into overridden destructor
- writes to address zero
- print "write to address zero" message into console
- goto 3
-
- Lead GZDoom+Raze Developer
- Posts: 48597
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Hard crach after exit on VM crash (4.7.0 - 4.8.2)
There's not really much that can be done about it. C++ actually has the same limitation that any exception thrown from a destructor will result in a hard abort.
-
- Posts: 1603
- Joined: Mon Jun 12, 2017 12:57 am
Re: Hard crach after exit on VM crash (4.7.0 - 4.8.2)
Well, exception from destructor if there are already some exception happened, lead to instant termination of a program, but that not the point and not entirely what I meant.
Just to be clear, this
will crash and flood console with "oops, cant destroy thinker" messages...which is expected. Stack unwinding, exception bytes and other scary words.
HOWEVER, if you relaunch game from main menu or switch map with CCMD, without relaunching Gzdoom, it would work fine.
Archive in first post after crashing VM also crashes Gzdoom if you try launching a new game, which should not happens.
Just to be clear, this
Code: Select all
version "3.8"
const MAX_SIZE = 6;
class thing : thinker
{
pointer others[MAX_SIZE];
static thing constructor()
{
let t = new("thing");
t.others[0] = new("pointer");
t.others[1] = new("pointer");
t.others[2] = new("pointer");
t.others[3] = new("pointer");
t.others[4] = new("pointer");
t.others[5] = new("pointer");
return t;
}
override void ondestroy()
{
for(int i = 0; i < MAX_SIZE; i++)
{
if(others[i])
{
console.printf("OH NO");
others[i].p.others[i] = null;
}
}
super.ondestroy();
}
void out_of_bound_write(int a, thing t)
{
others[a].p = t;
}
}
class pointer
{
thing p;
}
class debug_build : eventhandler
{
override void NetworkProcess (ConsoleEvent e)
{
if(e.name == "bug")
{
array<thing> t; t.clear();
t.push(thing.constructor() );
t.push(thing.constructor() );
t[0].out_of_bound_write(MAX_SIZE, t[1]);
}
}
}
HOWEVER, if you relaunch game from main menu or switch map with CCMD, without relaunching Gzdoom, it would work fine.
Archive in first post after crashing VM also crashes Gzdoom if you try launching a new game, which should not happens.
-
- Lead GZDoom+Raze Developer
- Posts: 48597
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Hard crach after exit on VM crash (4.7.0 - 4.8.2)
Like I said, it's impossible to avoid the crash here - this happens inside the cleanup operation of another exception.
What I did was to avoid running the garbage collector here, and if I receive another exception then, do a fatal error abort. That will give you a meaningful message, but once you dismiss that it'll still crash because, like I said, having a crash in a destructor (which onDestroy essentially is) is something that cannot be handled gracefully while cleaning up.
What I did was to avoid running the garbage collector here, and if I receive another exception then, do a fatal error abort. That will give you a meaningful message, but once you dismiss that it'll still crash because, like I said, having a crash in a destructor (which onDestroy essentially is) is something that cannot be handled gracefully while cleaning up.