4 ms·
Just counting my personal experience, I've seen multiple titles fail cert and delay release thanks to bug backlogs that were mostly filled with memory issues, e
by MaulingMonkey 6y ago
Just counting my personal experience, I've seen multiple titles fail cert and delay release thanks to bug backlogs that were mostly filled with memory issues, even after months of working to reduce the backlog of crash bugs. Perhaps you can't blame that entirely on the C++ codebase, but you sure can't absolve it entirely either.
At every single studio I've worked at I've helped build out crash collecting, symbolizing, or deduplicating infrastructure just to get a lead on where shit is exploding, and seen major productivity outages when tooling crashed frequently enough to disrupt the workflows of my coworkers. Address sanitizer, valgrind, extra debug allocators - I've sunk a lot of time into just making these crashes shallower to debug and quicker to catch.
One of the smallest and quickest projects that comes to mind was an NDS -> iOS and Android port. Do you think most of the time was spent in porting APIs and control schemes? More than half the time on that project was spent just chasing down really stupid memory related crash bugs that were exacerbated in frequency and time by the port. I made damn sure to communicate my concerns about the schedule, and if my memory serves me correctly, we managed to soft launch "only" a week or two late.
C++'s strengths are it's lean portability, speed, and huge existing codebases and tallent pools. Undefined behavior is simply the cost we begrudgingly pay, not it's strength, and even that we often mitigate by trying to figure out ways to write as little C++ as possible - keeping it only for the parts of our codebase that are actually performance sensitive. Tooling is often C#, Python, anything but C++. UB is a pox and constant time sink.
Whenever people call out C++'s UB as it's strength, I'm left wondering how many of their bugs do they actually fix, and how many are begrudgingly fixed by their coworkers. Most of the people whom I've worked with with that attitude don't pull their own weight in the debugging department, so they don't see the full costs of it.
- shultays 6y agoI don't share the same experience. Crashes do happen but I wouldn't call the time sunk there a lot. If you get a ctd, usually a callstack and a bit of thought is enough for figuring out what is going on. At worst case you have valgrind. Very rarely it goes beyond that but even with that I would say it is a well trade off on how relaxed C++'s memory management is compared to Rust. And I believe C++ is relatively safe when you have well designed systems where ownership is clear enough. I have a feeling that if my company suddenly flipped to Rust now, the struggling against borrow checker would be a bigger time sink For me majority of game development is feature development and fixing gameplay related bugs. Which will be same regardless of language you use. And depending on language feature development might be even slower
- MaulingMonkey 6y ago> I don't share the same experience. You can say that again! > If you get a ctd, usually a callstack and a bit of thought is enough for figuring out what is going on. Very different experiences. Sometimes that happens. Sometimes the symbols have been evicted from the symbol server. Sometimes the minidump didn't capture relevant memory (and the full dump would be a couple dozen gigs, making external QA reluctant to constantly capture those). Sometimes the crash is the result of memory corruption from unrelated systems minutes ago that doesn't reproduce when you enable any of your debug allocators because reproing relies on pointer reuse in a hashtable. Frequently custom allocators defeat tools like valgrind and address sanitizer, requiring extra work to either bypass or explicitly annotate valid/invalid memory ranges. Sometimes the process only exit(3)s (technically not even a crash!) from an unrelated thread on a specific bit of UI with no relevant callstacks nor logging, and if you open up the windows charm bar for more than 10 seconds without a debugger attached, and you resort to bisecting p4 history once you've spent the several days even figuring out repo steps. That wasn't even our bug, but it was our workaround... even when the codebase is good, the middleware often isn't! And that is but one of many I've had to deal with. > C++ is relatively safe when you have well designed systems where ownership is clear enough. Meanwhile, the poster I was originally replying was pointing out that you can have unclear object ownership full of globals and C++ is somehow supposedly good at dealing with this. Hopefully you're at least agreeing with me here, in disagreeing with that! :) A lot of gamedev code isn't very well designed, IME, and "relatively" safe can be suprisingly unsafe as well. > I have a feeling that if my company suddenly flipped to Rust now, the struggling against borrow checker would be a bigger time sink The first couple months after I picked up Rust, I had that phase. Now it's quite easy for me - sometimes it requires a deep `.clone()` or two, but in the equivalent C++ codebase you wouldn't have even dreamed of not making the deep copy - because in equivalent C++ code it'd be impossible to do the equivalent fancy zero-copy borrowing nonsense even remotely safely.