Article

When you've eliminated the possible, consider the impossible

Posted  by Tim Kerchmar.

PublicCategorized as Public.

Tagged with public.

Hello Reader,


I was writing a little utility for manipulating XYZ files, which works great in debug mode, but fails in release mode. Here's the code:


#define PATHSIZE 260

 int WINAPI WinMain(HINSTANCE hI, HINSTANCE hPI, LPSTR acCmdLine, int iWinMode)
{
// if the path isn't at least as long as needed to contain the
// smallest absolute paths possible: "c:\a.xyz" "\a\b.xyz", then
// we can be sure that it is garbage.
size_t stCmdLineLength = strlen(acCmdLine);
if(stCmdLineLength < 10)
{
MessageBox(0, "Please supply an absolute path to a .xyz file",
"Error", 0);
return -3;
}

if(stCmdLineLength >= PATHSIZE)
{
MessageBox(0, "Sorry, that path is too long", "Error", 0);
return -4;
}

// Remove double quotes from XYZ path
char acXYZPath[PATHSIZE];
/* Fails here --> */ strcpy_s(acXYZPath, PATHSIZE - 1, &acCmdLine[1]);
acXYZPath[strlen(acXYZPath) - 1] = 0;

// Confirm that path really points to .xyz
char acXYZPathLowerCase[PATHSIZE];
strcpy_s(acXYZPathLowerCase, PATHSIZE, acXYZPath);
_strlwr_s(acXYZPathLowerCase, PATHSIZE);
if(strcmp(&acXYZPathLowerCase[strlen(acXYZPathLowerCase) - 4],
".kfm") != 0)
{
char acError[256];
sprintf_s(acError, 256, "'%s' is not a valid XYZ", acXYZPath);
MessageBox(0, acError, "Error", 0);
return -2;
}
.
.
.


Right at the "Fails here" spot, in release mode, acXYZPath would have a few garbage characters, followed by a proper copy of acCmdLine. I googled a bit and nothing turned up. Usually, these kinds of errors occur from uninitialized data. Debug mode clears most heap or stack allocated data automatically. If your program depends on those values being cleared for you, and you don't run it in release mode often enough, you'll have a hard to track down bug. But strcpy_s overwrites whatever is in the destination string, and the source string was smaller by a large margin! I tried to use PATHSIZE - 1, but it still failed in the same exact way. Nothing is heap allocated, and the string is copied into acXYZPath, just not at the beginning!


So I did the last resort in these situations, carefully combing the project properties and making release resemble debug mode in the Visual Studio Project Properties dialog. When I turned off the optimizer, voila!, it all works in release mode!


-Tim Kerchmar




Arrow_down Hide comments

The Night School, LLC, empowering our users to create and play!

Powered by Near-TimeTerms of Services | Privacy Policy | Security Policy | Support | Feedback | Help Center |