약 한시간 가량 빡치게 만든에러..


MS 는 CreateProcess 의 버그를 고칠 생각이 없는가? 구조적으로 힘든가? 아무튼 이런 빡치는 상황이 발생하면 아래와 같이 수정하세요.


먼저 CreateProcess 를 사용하는 수천만명이 봤을 간단한 예제를 봅시다. 

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682512(v=vs.85).aspx


빨간 부분을 수정했습니다. 


#include <windows.h> #include <stdio.h> #include <tchar.h> void _tmain( int argc, TCHAR *argv[] ) { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); if( argc != 2 ) { printf("Usage: %s [cmdline]\n", argv[0]); return; } // Start the child process. if( !CreateProcess( NULL, // No module name (use command line) _T("notepad.exe"), // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { printf( "CreateProcess failed (%d).\n", GetLastError() ); return; } // Wait until child process exits. WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); }


이렇게 한 뒤에 unicode 로 빌드하면 빡치는 상황이 발생합니다. 바로 Access violation error!!!!!!!!!!!!


그 원인은 unicode 버전의 createprocess 는 lpCommandLine 파라미터를 변경시키기 때문에 const 메모리 주소를 전달하면 안됩니다. 

아래 msdn 에 설명되어 있습니다. 


lpCommandLine [in, out, optional]

The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null character. If lpApplicationName is NULL, the module name portion of lpCommandLine is limited to MAX_PATH characters.

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to bylpApplicationName as the command line.

If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string pointed to bylpApplicationName specifies the module to execute, and the null-terminated string pointed to by lpCommandLinespecifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first token in the command line.

+ Recent posts