Skip navigation.

Syndicate

Syndicate content

User login

c++

Visual C++ Apps Crashing in _chkstk Under Load

At work one of the devs was running into a weird problem. He could run a group of our unit tests on his dev box without any problem, but when the same tests ran on our build machine the test host process crashed with an unhandled exception. Thankfully we run all of our processes with an unhandled exception trap which generates a minidump before terminating, so we were able to determine the failure was in a C runtime function _chkstk called upon entry into a particular function that allocates alot of stuff on the stack.

At first, I was thinking stack overflow, but there wasn’t anywhere near 1MB of shit on the stack, which is the default maximum stack size. I thought about stack corruption, but the C-runtime stack checking routines provide an explicit message when stack corruption is detected.

Worst C/C++ Gotcha Yet

Today I ran smack into what is easily the nastiest C/C++ gotcha of my entire software engineering career. From the early 90s reading Sam’s Teach Yourself C in 21 Days with a shitty freeware C compiler from a local BBS, through to today, I have been bit by just about every imaginable C and C++ gotcha, but this one takes the cake.

If you see what’s wrong with this code, you’ve been bitten by this before:

UINT32 x = 0x80000000;
UINT32 y = 2;
UINT64 z = x * y;
cwout << L"x*y=" << std::hex << z << std::endl;

If you think this code will output 0x100000000, you’ve not been bitten by this before.

You see, 2 times 0x80000000 is 0x100000000, which is 2^32 in hex. Unfortunately, since both x and y are 32-bit unsigned integers, the result is a 32-bit unsigned integer as well, implicitly cast to a 64-bit unsigned integer only after the computation is performed.

Things I do after programming in a language for too long

I’ve been going back and forth between C++ and C# alot in my current job. When switching between languages, certain elements bleed together leading to the same mistakes over and over. Some of mine:

C# to C++

  • Putting array braces ([]) on the type instead of the variable name (eg, int[] whatever in C# vs int whatever[] in C++)
  • Writing string literals with naked double quote (ala ") instead of the L prefix to denote Unicode
  • Naming methods with PascalCase instead of the camelCase in our C++ convention
  • Throwing exceptions with new, which particularly sucks since it won’t yield a compile error

The shitty C++ memory leak debugging experience

At my new job I found myself chasing some memory leaks in our rather large C/C++ codebase. Going into the task I was optimistic and just a bit overconfident, knowing as I did that the C Runtime (CRT) has built-in leak-finding goodness.

After the honeymoon, it became clear I was mistaken. Sure, you can set the _CRTDBG_LEAK_CHECK_DF flag with _CrtSetDbgFlag. You can even enable source information with _CRTDBG_MAP_ALLOC. Go ahead. Try it. Use this code:

    #include "stdafx.h"

    extern "C" int main(INT argc, TCHAR *argv[])
    {
            char* c = new char[2048];
            ::strcpy(c, "You're screwed, pal!");

            return 0;
    }

What? The line number reported for the leak is some bullshit location deep within the CRT? How can this be? The CRT is better than that!

Not.

Why doesn't va_start work with reference parameters?

I’ve been hacking alot of C++ lately as a part of my new job. I implemented a simple string formatting function using __vswprintf_s and the C variable argument constructs va_start, va_list, etc.

I was surprised to discover that, when the prev parameter argument passed to va_start is a C++ reference parameter (like, say, const std::wstring&, as in my case), the resulting variable arguments are garbage, and of course any printf-like function produces nonsense and/or crashes.

It’s not at all clear to me why this is, though it sucks rather profoundly.

Syndicate content