Discussion:
An exception arises after calling CreateProcess
(too old to reply)
w***@gmail.com
2008-12-02 03:10:36 UTC
Permalink
Hi,
everyone. In order to update automatically my application, I
invented a "shell" auxiliary application. This shell will perform
updating each time the user click the shortcut from desktop which,in
fact, launch the shell. After updating, the shell would call
CreateProcess to spawn the actual Application, the code is as follows:
void RunProcess(stringT& appName)
{ //appName is the application name
STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

if( !CreateProcess( const_cast<TCHAR*>(appName.c_str()), NULL,
NULL, NULL,FALSE, 0, NULL, NULL,&si, &pi ))
{
MessageBox(NULL,_T("Can't Creation Process"),_T("Error"),MB_OK);
}
}
The shell will exit as soon as calling Runprocess. Then the problem
comes out:that createprocess does not create a process. I thought
there must have some exception. Therefore, I placed a try-catch
structure in the shell's _tWinMain function. The catch clause does
really take effect. The curious thing is: sometimes the shell can
spawn the application without any exception.
Now,my questions are: why the CreateProcess fail to work? Moreover,
why it sometimes works?
I'll appreciate your help.
Looking forward to your response.
Alex Blekhman
2008-12-02 09:17:32 UTC
Permalink
Post by w***@gmail.com
void RunProcess(stringT& appName)
{ //appName is the application name
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( !CreateProcess( const_cast<TCHAR*>(appName.c_str()),
NULL,
^^^^^^^^^^

This should set alarm bells ringing. Why do you cast away const?
What is the call stack during the exception? What is the exception
number?

Alex
w***@gmail.com
2008-12-02 10:02:17 UTC
Permalink
      void RunProcess(stringT& appName)
  { //appName is the application name
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   ZeroMemory( &si, sizeof(si) );
   si.cb = sizeof(si);
   ZeroMemory( &pi, sizeof(pi) );
   if( !CreateProcess( const_cast<TCHAR*>(appName.c_str()),
NULL,
                         ^^^^^^^^^^
This should set alarm bells ringing. Why do you cast away const?
What is the call stack during the exception? What is the exception
number?
Alex
Hi, Alex.
At first, the argument in RunProcess was (const stringT& appName),
hence the need to cast away const.
The caught exception is Access Violation (0xc0000005). I'm not quite
sure what call stack it was during the
exception, for I registered a function to handle such unexpected
exception by using SetUnhandledExceptionFilter.
Alex Blekhman
2008-12-02 10:16:21 UTC
Permalink
Post by Alex Blekhman
Post by w***@gmail.com
void RunProcess(stringT& appName)
{ //appName is the application name
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( !CreateProcess( const_cast<TCHAR*>(appName.c_str()),
NULL,
^^^^^^^^^^
At first, the argument in RunProcess was (const stringT&
appName), hence the need to cast away const.
But first parameter of CreateProcess accepts `const TCHAR*' type,
no need to cast const away. Probably you confuse it withe the
second parameter, which indeed requires `TCHAR*' string. If you
use this parameter, then you must provide writable TCHAR buffer,
because CreateProcess wil modify it internally. You cannot use the
return value of `std::basic_string::c_str' for that, since
modifying it leads to undefined behaviour and prohibited by the
C++ standard. You need to allocate TCHAR buffer of necessary
length and copy the contents of `appName' to there.
Post by Alex Blekhman
The caught exception is Access Violation (0xc0000005). I'm not
quite sure what call stack it was during the exception, for I
registered a function to handle such unexpected exception by
using SetUnhandledExceptionFilter.
Just run you application uder debugger. When exception occurs
debugger will break in. Then you can see the call stack in stack
window.

HTH
Alex
w***@gmail.com
2008-12-02 10:48:23 UTC
Permalink
Yes, I have mixed up. When the parameter for RunProcess was "const
stringT& appName",I casted away const for the CreateProcess's second
parameter. And I got an Access Violation exception as showed above. So
I put the appName (which contained the application name) as the first
parameter of CreateProcess. Still, I got the same Access Violation
exception.
I run the application under debug model in VC 2005.
Jochen Kalmbach [MVP]
2008-12-02 10:52:51 UTC
Permalink
Hi wuguangwen734!
I got the same Access Violation exception.
The first paramerer *must* be *writable*.
So please *never ever* pass an string-literal this this parameter.

The following will fail:

void Start(LPTSTR szArg0)
{
CreateProcess(szArg0, ...);
}
Start(_T("explorer.exe"));

!!!

Please use "strdup", if you are not sure, if the passed string is writable!

Greetings
Jochen
Alex Blekhman
2008-12-02 11:16:29 UTC
Permalink
Post by Jochen Kalmbach [MVP]
The first paramerer *must* be *writable*.
So please *never ever* pass an string-literal this this
parameter.
void Start(LPTSTR szArg0)
{
CreateProcess(szArg0, ...);
}
Start(_T("explorer.exe"));
!!!
Please use "strdup", if you are not sure, if the passed string
is writable!
Are you sure about the 1st parameter? According to the signature
of CreateProcess it is second parameter that must be writable.

Alex
Jochen Kalmbach [MVP]
2008-12-02 11:22:05 UTC
Permalink
Hi Alex!
Post by Alex Blekhman
Are you sure about the 1st parameter? According to the signature
of CreateProcess it is second parameter that must be writable.
Yes, sorry... I mixed it up with the second parameter... sorry.

Greetings
Jochen
w***@gmail.com
2008-12-02 11:54:24 UTC
Permalink
I run the shell application named AutoUpdate.exe under WinDbg and got
the following information:

CommandLine: "C:\Program Files\CHNET\AutoUpdate.exe"
Symbol search path is: c:\Program Files\CHNET\
Executable search path is:
ModLoad: 00400000 00419000 AutoUpdate.exe
ModLoad: 7c920000 7c9b4000 ntdll.dll
ModLoad: 7c800000 7c91c000 C:\WINDOWS\system32\kernel32.dll
ModLoad: 77d10000 77d9f000 C:\WINDOWS\system32\USER32.dll
ModLoad: 77ef0000 77f36000 C:\WINDOWS\system32\GDI32.dll
ModLoad: 77da0000 77e49000 C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e50000 77ee1000 C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 76990000 76acc000 C:\WINDOWS\system32\ole32.dll
ModLoad: 77be0000 77c38000 C:\WINDOWS\system32\msvcrt.dll
ModLoad: 7c420000 7c4a7000 C:\WINDOWS\WinSxS
\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-
ww_6b128700\MSVCP80.dll
ModLoad: 78130000 781cb000 C:\WINDOWS\WinSxS
\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-
ww_6b128700\MSVCR80.dll
ModLoad: 77bd0000 77bd8000 C:\WINDOWS\system32\VERSION.dll
(574.5ec): Break instruction exception - code 80000003 (first chance)
eax=00251eb4 ebx=7ffd5000 ecx=00000003 edx=00000008 esi=00251f48
edi=00251eb4
eip=7c921230 esp=0012fb20 ebp=0012fc94 iopl=0 nv up ei pl nz
na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000202
*** ERROR: Symbol file could not be found. Defaulted to export
symbols for ntdll.dll -
ntdll!DbgBreakPoint:
7c921230 cc int 3

Loading...