Tuesday, February 09, 2010

Gotcha: CreateProcess causes Access Violation

The famous CreateProcess function may fail with an access violation. For example, this innocent looking code causes a crash:

STARTUPINFO si = { sizeof(si) };

PROCESS_INFORMATION pi;

CreateProcess(0, _T("notepad"), 0, 0, FALSE,

   0, 0, 0, &si, &pi);

What’s wrong with this code? Apparently nothing.

The key here is that CreateProcess is not actually a function at all, but a macro that’s expanded to CreateProcessA or CreateProcessW depending a compile time constant (UNICODE).

If we open the docs, we find for the second argument: “The Unicode version of this function, CreateProcessW, can modify the contents of this string”.

The string I passed is a constant string, coming from a region marked as “read only” and this is why the access violation occurs. Changing CreateProcess to CreateProcessA avoids the crash. The reason is that the A function translates the string to unicode and calls the W function. The translated string is in a read/write buffer, so no problem there. This should generally be avoided because of the extra step A functions do.

In recent versions of Visual Studio the default libraries are unicode (as they should be, as the Windows 9x family of OSes is finally dead and buried). This is while a transition from (e.g.) Visual Studio 2003 to 2008 may cause old code to crash.

So, the general solution should be:

TCHAR name[] = _T("Notepad.exe");

CreateProcess(0, name, 0, 0, FALSE, 0, 0, 0, &si, &pi);


Read more: Pavel's Blog

Posted via email from jasper22's posterous