Live data from Hacker News

How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

cookieplmonster.github.io

201–210 of 315 posts

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#201
post #88

Earlier quoted context omitted.

This is more of a problem of the C/C++ standard that it allows uninitialized variables but doesn't give them defined values, considering it "undefined behavior" to read from an uninitialized variable. Java, for example, doesn't have this particular problem because it does specify default values for variables.

But it's this and many other features of C/C++ that make it faster than Java. C/C++ developers really don't want to "pay" for something for safety. Though, I really like the _mm_undefined_ps() intrinsics for SSE that make it clear that you're purposefully not initialising a variable. Something like that for ints and floats would be pretty sweet.

Statically proving the variables get initialized wouldn't change the performance except by making sure you check the return value of sscanf, or turning refusal to check into a couple register wipes. Either way, that's a negligible increase to a hefty function call. It wouldn't require default initializing variables in all circumstances.

When I think of the "no runtime cost" mentality of C/C++ I don't think that normally extends to ignoring errors in I/O functions.

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#202
post #10

This is the kind of thing I'd expect from Raymond Chen - which is extremely high praise! I'm glad they tracked it down even further to figure out exactly why.

Or randomascii. A freaking legend (although he had a heart braking streak of bad events ... I wish him the best)

What happened to him?

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#203

On Windows 11 24H2, more stack space was modified by a new implementation of Critical Sections. IMHO this shows the downfall of Microsoft. Why did they do that? Critical sections have been there for many decades and should be basically bug-free by now. My best guess is someone thought they'd "improve" things and rewrote it, then made some microbenchmark that maybe showed the dubious improvement. The other comment her…

Really? Someone depending on UB in their software represents the downfall of Microsoft?! What a hot take...

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#205
post #167

Earlier quoted context omitted.

When I worked at Microsoft and I had downtime I would sometimes read the code for app compatibility shims out of pure curiosity. Win9x video games that made bad assumptions about the stack were a theme I saw. One of the differences between win9x and NT based windows is that kernel32 (later kernelbase) is a now user mode wrapper atop ntdll, whereas in the olden days kernel32 would trap directly into the kernel. This m…

What was the testing like for such bugs? Is it somehow automated, or is there a lengthy doc describing the manual testing steps, or are there no tests at all?

I interned with the AppCompat team shortly before the release of Windows XP, which was huge for them as it was the first Windows for consumers on the NT kernel.

IIRC, they had a significant lab and tons of infrastructure for exercising and identifying compatibility issues in thousands of popular and less popular software packages. It all got distilled into a huge database of app fingerprints and corresponding compatibility shims to be applied at runtime.

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#206
post #179
post #164

Earlier quoted context omitted.

You both may be right. It could be that ASAN is not instrumenting scanf (or some other random standard lib function). Though since 2015, it certainly has been. https://github.com/google/sanitizers/issues/108 The simpler policy of "don't allow unintialized locals when declared" would also have caught it with the tools available when the game was made (though a bit ham-fisted).

The problem is that after calling scanf(), the number of variables that are defined is a variable number. For example: int x, y, z; int n = scanf("%d %d %d", &x, &y, &z); At compile time, you can make no inferences about which of x, y, and z are defined, because that depends on the returned value n. There are many ways to branch out from this. One is to insist on definite assignment - so if we cannot prove all of the…

I interpret "don't allow unintialized locals when declared" as meaning that this call:

    int n = scanf("%d %d %d", &x, &y, &z);
Would be caught, because it takes references to undeclared variables. To be allowed, the programmer would have to initialize the variables beforehand.

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#207
post #89

Once this category of error is raised to your attention, you start to notice it more and more. A little piece of technology made sense in the original context, but then it got moved to a different context without realizing that move broke the contract. Specifically in this case a flying boat became an airplane. --- I recently worked a bug that feels very similar: A linux cups printer would not print to the selected t…

Infamously, this is also why Ariane 501 blew up.

(a component being reused in a new context where a contract is broken, not bad CUPS drivers)

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#208

Am I the only one to be annoyed by this...? while (this->m_fBladeAngle > 6.2831855) { this->m_fBladeAngle = this->m_fBladeAngle - 6.2831855; } Like, "let's just write a while loop that could turn into an infinite loop coz I'm too lazy to do a division"

I want to assume that the GTA developers did this hack because it was faster than floating point division on the Playstation 2 or something. But knowing they were able to they were able to blow up loading GTA5 by 5 minutes by just parsing json with sscanf, I don't have much hope.

IIRC the whole parsing performance issue was because the original code was written for the SP campaign of GTA5 that only had a handful of objects to parse data for. That was barely a blip in terms of performance impact and AFAIK was written years before GTAOnline was made (where it became an issue - and even then only became an issue much after GTAOnline was first made).

Writing some simple code that works with the data you expect to have without bothering with optimizations is fine, if anything it is one of the actual cases of "premature optimization": even with profiling no real time is spent on that code, your data wont make it spend any time and you should avoid wild guesses since chances are you'll be wrong (even if in this case it could be a correct guess, it'd be like a broken clock guessing the time is always 13:37).

The actual issue with that code was that, after they reused it for GTAOnline and started becoming a performance issue after some time as they added more objects, nobody thought to try and see what is wrong.

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#209

Earlier quoted context omitted.

Or randomascii. A freaking legend (although he had a heart braking streak of bad events ... I wish him the best)

What happened to him?

https://randomascii.wordpress.com/2024/10/01/life-death-and-...

https://randomascii.wordpress.com/2016/10/17/vestibular-dysf...

Re: How a 20 year old bug in GTA San Andreas surfaced in Windows 11 24H2

#210
post #88

Earlier quoted context omitted.

This is more of a problem of the C/C++ standard that it allows uninitialized variables but doesn't give them defined values, considering it "undefined behavior" to read from an uninitialized variable. Java, for example, doesn't have this particular problem because it does specify default values for variables.

But it's this and many other features of C/C++ that make it faster than Java. C/C++ developers really don't want to "pay" for something for safety. Though, I really like the _mm_undefined_ps() intrinsics for SSE that make it clear that you're purposefully not initialising a variable. Something like that for ints and floats would be pretty sweet.

And yet, there is a good chance that C++ will start doing exactly this [1]. Because [2]:

> The performance impact is negligible (less that 0.5% regression) to slightly positive (that is, some code gets faster by up to 1%). The code size impact is negligible (smaller than 0.5%). Compile-time regressions are negligible. Were overheads to matter for particular coding patterns, compilers would be able to obviate most of them.

> The only significant performance/code regressions are when code has very large automatic storage duration objects. We provide an attribute to opt-out of zero-initialization of objects of automatic storage duration. We then expect that programmer can audit their code for this attribute, and ensure that the unsafe subset of C++ is used in a safe manner.

> This change was not possible 30 years ago because optimizations simply were not as good as they are today, and the costs were too high. The costs are now negligible.

[1] https://github.com/cplusplus/papers/issues/1401

[2] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p27...

Post reply on HN