Undefined Behavior Optimization IRL

A coworker asked me to look at a mysterious segfault crash today, in some simple c++ code that didn’t look like it could possibly crash. Further adding to the mystery, it was 100% reproducible on Android and OSX/iOS, but not PC. Here it is (with a whole bunch of irrelevant details removed):

sprite0 starts out as a valid pointer. We then search our scenegraph for another sprite, and if we find it, assign it to sprite0 instead.

Then we crash because sprite0 is null, despite that we know it started out valid, and we null checked the only case where we might reassign it.

So. Do you see the problem?

If not, watch this very entertaining cppcon talk about optimization and undefined behavior, and come back. I’ll wait.

Right, so the obvious bit of bad code smell here is the FindChildRef call– that’s weird, right? It returns a reference, but then we convert the reference to a pointer, and null-check it. Which means that we’re assuming the function can return a reference that, converted to a pointer, would point to null. This should not be possible–references in c++ cannot be null. What’s going on?

For that matter, what does FindChildRef return if it doesn’t find anything with the requested name?

It turns out the implementation of that function was doing something deeply problematic:

Now, the FindChild function it calls does return a pointer, but some prior programmer on this project, a big fan of C# or Java perhaps, didn’t much care for that, and wrote a function that returned a reference instead. Which works just fine, until GetChild fails to find something and returns null. Now, we’ve dereferenced a null pointer to get a reference to return, and we’re in the magic land of undefined behavior.

Still, though, we do null check the result, right?

This is where optimization comes in. Since a reference can’t be null, a pointer that was just taken from a reference also cannot be null. So the compiler, very wisely, sees that ‘if (sprite1)’ condition, reasons that it must always be true, and removes it, because it’s redundant.

But of course the reference is null, because we forced it to be. And thus, we reach the seemingly impossible assignment.

(And why does it happen on every platform but PC? Simple–PC is the only platform we don’t use clang on, and clang is more aggressive than the Visual Studio compiler with this kind of optimization.)

I admit I was delighted to discover this–a real-life example of a class of problem I’d previously only read about. And, of course, the fix was simple: replacing FindChildRef with FindChild.

(…and, of course, scrubbing FindChildRef entirely from our code base.)

Quick tip – forward slash autocomplete

A coworker of mine was complaining the other day that Visual Studio’s autocomplete defaults to using backslashes in #include paths–this is pretty annoying if you’re doing cross-platform development since most platforms only allows forward slashes.

Thankfully, you can fix this!–but the setting is a bit buried. In Visual Studio 2017, from Tools->Options:

Alternately, if (like me), you never use autocomplete for include paths, you can use the setting just above that to disable it.

Quick tip – forcing your app to use the higher-performance GPU

I recently switched from a home-built desktop PC to a laptop with an external GPU enclosure, and was surprised to discover that bytopia immediately crashed on startup on this system.

It turns out the NVIDIA driver isn’t always too smart about choosing which GPU to assign to a particular app, and was giving me the integrated Intel chip, which lacked the OpenGL 4.5 features that I’m using.1

You can of course solve this locally in the NVIDIA driver settings by forcing it to use the high-performance GPU, but I’d rather not have to ask every user to figure that out. So, after some google searching (resulting in a few false starts), I found this NVIDIA technical note, which explains the very hacky process by which you can force your app to use the high-performance GPU:

This needs to be in the executable; (annoyingly) it won’t work in a DLL. And, needless to say, this solution is Windows-only; I don’t know if there’s something equivalent for OSX and/or Linux systems.

It turns out that AMD’s method is similar, except their variable is called AmdPowerXpressRequestHighPerformance.2 So, to cover all bases:

I don’t have an AMD card handy so I couldn’t test the AMD version, but I can verify the NVIDIA version worked for me, with one caveat: it doesn’t work with a debugger attached.3  So I still ended up having to force the GPU choice in the driver settings locally, but at least when I distribute the game it will work for other people.


1 I will likely support earlier OpenGL versions eventually, although the performance of the Intel chips I’d need it for is so poor I’m not sure it’s worth the effort–and using direct state access does make the rendering layer easier to read…
2 Via this thread on AMD’s community forums. I don’t have an AMD graphics card to test this with, though, so I’m taking their word for it.
3 Presumably the driver has to inspect the executable to see if it exports the NvOptimusEnablement variable, and having the debugger attached prevents that somehow. (Full disclosure: I don’t know much about how debuggers work. 😛 )

Quick Tip – disabling optimization without getting yourself in trouble

If you’ve worked on a nontrivial game in C++, you’ve probably run into a situation where you’d like to step through some code in the debugger, but the debug build of your game is painfully slow and debugging in release mode is difficult and time-consuming.

Here’s something you probably know (but if you don’t, it will change your life): you can disable optimization selectively per file, and thus have access to good debug information while not crippling your performance by running in debug mode.

In the Microsoft compiler, you do it this way:

This will turn off all optimization in whatever source file you put it in. (The optimize pragma has some options to make the changes more granular, but I’ve never really had a need for that.)

There is, however, a subtle problem here: it is very easy to forget to remove that one innocuous line after adding it–and end up, in the worst case, shipping your game with optimization turned off for some files.1 It would be nice if the compiler would let us know if we forgot to remove this pragma, right?

What I do is create a no_opt.h header and include it in any files I’d like to be able to step through:

Replace _RELEASE_FINAL with whatever your “final” build configuration you release to end users–i.e. the configuration that’s build by your build system.2

With that, the compiler will spit out a message for every file that has optimizations disabled. Further, if you don’t notice the message, it will fail to compile on your final build, giving you a second chance to remove the header.

(I’ve only really done this in Microsoft’s compiler personally, but clang and gcc appear to have similar pragmas available, so it should be easy to extend this to them.)


1. If you’re thinking to yourself that you’re not that forgetful and have always remembered to remove it, I’m sorry to report that you’ve almost definitely shipped code with optimizations disabled.
2. This practice may sound strange if you’re not familiar with it, but at least in game development it’s not unusual to have a “release” build and a “final release” build, where the former will enable optimizations and the latter might go further by turning off developer tools, removing symbols, etc.

bytopia (working title)

For the last few months I’ve been working on a voxel-based construction/exploration game in my spare time. Figured it’s a good time to share some of my progress.

A quick video demo here.

It’s all fairly minimalist so far, but the major features:

  • First pass on procedural world generation.
  • Large worlds (currently +/- about 2 million blocks in any direction, including up/down).
  • Day/night cycle with sun and moon, as well as a rudimentary atmospheric scattering approximation.
  • Normal mapping combining surface normals with a bevel effect on blocks to give everything a nice blocky look.
  • Rudimentary UI, including inventory, main menu, HUD, and a debug console.
  • Fairly polished movement controls and physics for the player (this is a big priority for me–games like this often have awkward-feeling movement and I want to avoid that).

A few technical details:

  • Handwritten in modern C++.
  • Renderer based on OpenGL 4.5.
  • Physics (just for cosmetic effect for dropped items etc) using PhysX.
  • Font rendering/layout using freetype2 and harfbuzz.
  • Windows-only so far, but built with ease of porting in mind.

Moments

Over the last couple years I’ve been impulsively filming a lot of little things I find interesting, but then never doing anything with the footage. So I’ve started a Youtube channel that will be just those pretty little instants: videos mostly less than a minute long, sometimes silent, sometimes with natural audio, sometimes with my own soundtrack added.

I’m not sure how long I’ll keep this up, but I do have a huge archive of this stuff to draw from, so I can probably keep it going for a while even if I don’t film anything new.

Feel free to subscribe, especially if you’re into shallow focus and brevity…

ephemera / moments

Earthquakes

I’ve felt three of them in my lifetime. First, the 2011 Virginia earthquake: I had just returned from a summer in Korea and was staying with my family in the Maryland suburbs. My grandmother and I were the only ones home when the ground started shaking; it felt just like a passing train, so I didn’t really take note of it at first, until I remembered that there weren’t actually any train tracks nearby. I stumbled down the hall and asked my grandmother (in Croatian)–“is this an earthquake?” She nodded, not the least bit concerned–she’d been through many quakes in her long life and knew when to worry.

And then, last year, I was in Hiroshima on vacation when the 2016 Kyushu Earthquakes struck, waking me up two nights in a row in my hotel: first the largest foreshock, and then the 7.0 main quake, which to my inexperienced self felt massive (much bigger than the Virginia quake), but which still was weak enough where I was, more than a hundred miles away, to not do any damage.

(Nearer the epicenter, it was a different story, of course–damage in the Kumamoto area was fairly extensive, but Hiroshima was as close as I got.)

A few days later, I saw a solitary, elderly European tourist at Haneda Airport, carrying a gift bag from Kumamoto Castle. He must have had an unexpectedly interesting vacation.

The entire experience rendered the rest of my trip–stops in Yokohama and then Taipei–a little surreal; all the lost sleep left me in a near-fugue state. I need to get back to Taipei some day, in a better state of mind: I hardly remember what I did for my three days there.

I don’t have any particular motive for writing about this now, to be honest. I just couldn’t sleep last night, and the occasional rumble of passing trucks brought back memories.

Faded Rainbow Desktop

Just thought I’d share this desktop background I made. It started life as a long-exposure photo of the light sculpture in front of the Shaw Library here in DC. Some color manipulation, various blurs, grain, and dust/scratches led to this slightly worn, faded-looking rainbow (click for full size, 3440×1440).

Marija Tresnjak

My grandmother passed away yesterday, peacefully in her sleep. She spent the last few days of her life surrounded by her family and friends. A doctor once told her she’d never live past age 45; she lived to 88.

She saw a lot in those 88 years. She grew up on a barge on the Danube–born, by her own account, at a Romani village by the shore because her parents couldn’t make it to a hospital. As a young woman, fearless, she took up skydiving at a time when it was a brand new idea. She survived the horrors of the second world war, worked with the Yugoslav Partisans, and shared her first kiss with a Jewish stowaway her family smuggled to safety. Her beloved older brother fought with the Partisans, and survived the war only to be shot by his best friend in a dispute over a girl.

When her daughter married an American diplomat and moved to the United States, she and her son followed not long after; they were a tight-knit little family and couldn’t bear to be apart. With her lack of English she had trouble finding work here, so instead she helped raise me and my sister. I always told my friends she was more like a third parent to me than a grandparent.

Of all the people in my family, she was the one who always understood me the best–and the amazing thing is that every single one of us can probably say that. She was not only a grandparent to me, but also often a surrogate grandparent to my friends; she was endlessly generous with her patience, her kindness, and her (usually mischievous) sense of humor.

She was always trying to convince me to be healthier (while, in true Slavic grandmother style, also offering me enormous amounts of food at every opportunity). The next-to-last thing she said to me, lying on her deathbed, was: “You’re so beautiful. I love you so much. Have you lost weight?” She repeated it about ten times.

In the last few years, as her health declined, I’d often sit by her bedside showing her the latest pictures from space, and telling her about stars and exoplanets and black holes and distant galaxes. She never had much interest in science fiction, but was utterly fascinated by science fact. The very last time she spoke to me, she asked me–struggling to get each word out–whether their were any new pictures from Ceres. Curious to the very end.

Yesterday, the Supreme Court ruling came down making same-sex marriage the law of the land. My mother and uncle joyously told her. We don’t know if she heard, but if she did it would have made her incredibly happy. Just a couple hours later, she passed, according to my mother with a “not bad” expression on her face. She was wearing my rainbow bracelet from Pride.

She adamantly didn’t believe in God, but she often said she believed in reincarnation–although she always said so with such a mischievous twinkle in her eye that I’m still not sure whether she was just messing with me or not. If there’s a heaven, I’m sure she’s there now; if reincarnation is real, I’m sure she’s being born again as something totally amazing as we speak. Regardless, she lives on with all of us.

She was the best person I’ve ever known. Let’s all try to be a little better in her memory: a little kinder, a little braver, a little more generous and patient.

Polska_224

I’ll Be Right There

This passage from Kyung-sook Shin’s novel I’ll Be Right There has got me reflecting on my own life today; I’ve had these thoughts so many times over the past few years. (This paragraph is from near the end of the book, although it doesn’t really spoil anything, in case you care about that sort of thing.)

“I’ll never forget what I saw that day. I think that’s why I never married. The memory has faded, but it never goes away. That’s why I am not going to tell you two to get over the things you have gone through. You should think about them and think about them and think about them some more. Think about them until you can’t think anymore. Don’t stop questioning the unjust and puzzling. Maybe if I had gotten there by the date written in her letter, I could have saved her. But then again, maybe her death was already planned, and all she wanted was for me to find her. Human beings are imperfect. We are complicated, indefinable by any wise saying or moral. The guilt, wondering what I’d done wrong, will follow me my whole life like my own shadow. The more you love someone, the stronger that feeling is. But if we cannot despair over the things we’ve lost, then what does it all mean?”

 (Adding to the odd feelings, I and the person this reminded me of had both read Shin’s other novel available in English translation–Please Look After Mom, also wonderful–shortly before her passing.)