diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2015-06-25 22:51:16 +0200 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2015-06-25 22:51:16 +0200 |
commit | 575e0d05b748e4e11ff75d66fa085e8d976f2083 (patch) | |
tree | 4f78e7616f24d38f910eb13e6fcedc20ccf082ad | |
parent | ee26a59e352aa2beac79b2bb3b21176e9eb158cc (diff) | |
parent | 31ae12be0fe50183036a27e49fe99c6dac67e3ed (diff) | |
download | coreclr-575e0d05b748e4e11ff75d66fa085e8d976f2083.tar.gz coreclr-575e0d05b748e4e11ff75d66fa085e8d976f2083.tar.bz2 coreclr-575e0d05b748e4e11ff75d66fa085e8d976f2083.zip |
Merge pull request #1174 from mikem8361/palinit
Fixed the PAL_Initialize* order problem.
-rw-r--r-- | src/ToolBox/SOS/Strike/strike.cpp | 4 | ||||
-rw-r--r-- | src/debug/daccess/dacdbiimpl.cpp | 15 | ||||
-rw-r--r-- | src/debug/di/shimremotedatatarget.cpp | 17 | ||||
-rw-r--r-- | src/dlls/mscoree/unixinterface.cpp | 2 | ||||
-rw-r--r-- | src/pal/inc/pal.h | 10 | ||||
-rw-r--r-- | src/pal/src/debug/debug.cpp | 16 | ||||
-rw-r--r-- | src/pal/src/include/pal/module.h | 50 | ||||
-rw-r--r-- | src/pal/src/include/pal/procobj.hpp | 7 | ||||
-rw-r--r-- | src/pal/src/init/pal.cpp | 184 | ||||
-rw-r--r-- | src/pal/src/init/sxs.cpp | 22 | ||||
-rw-r--r-- | src/pal/src/loader/module.cpp | 271 | ||||
-rw-r--r-- | src/pal/src/misc/miscpalapi.cpp | 8 | ||||
-rw-r--r-- | src/pal/src/thread/process.cpp | 110 |
13 files changed, 356 insertions, 360 deletions
diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp index d9b96bfe7f..f87fa925a5 100644 --- a/src/ToolBox/SOS/Strike/strike.cpp +++ b/src/ToolBox/SOS/Strike/strike.cpp @@ -11545,6 +11545,10 @@ public: } ExtOut("=============================================================================\n"); +#ifdef FEATURE_PAL + // Temporary until we get a process exit notification plumbed from lldb + UninitCorDebugInterface(); +#endif return S_OK; } }; diff --git a/src/debug/daccess/dacdbiimpl.cpp b/src/debug/daccess/dacdbiimpl.cpp index 0535c57dec..619eb06f2d 100644 --- a/src/debug/daccess/dacdbiimpl.cpp +++ b/src/debug/daccess/dacdbiimpl.cpp @@ -5615,26 +5615,11 @@ void DacDbiInterfaceImpl::GetContext(VMPTR_Thread vmThread, DT_CONTEXT * pContex if (pFilterContext == NULL) { // If the filter context is NULL, then we use the true context of the thread. - -#ifdef FEATURE_DBGIPC_TRANSPORT_DI - // GetThreadContext() is currently not implemented in ShimRemoteDataTarget, which is used with our pipe transport - // (FEATURE_DBGIPC_TRANSPORT_DI). Pipe transport is used on POSIX system, but occasionally we can turn it on for Windows for testing, - // and then we'd like to have same behavior as on POSIX system (zero context). - // - // We don't have a good way to implement GetThreadContext() in ShimRemoteDataTarget yet, because we have no way to convert a thread ID to a - // thread handle. The function to do the conversion is OpenThread(), which is not implemented in PAL. Even if we had a handle, PAL implementation - // of GetThreadContext() is very limited and doesn't work when we're not attached with ptrace. - // Instead, we just zero out the seed CONTEXT for the stackwalk. This tells the stackwalker to - // start the stackwalk with the first explicit frame. This won't work when we do native debugging, - // but that won't happen on the POSIX systems since they don't support native debugging. - ZeroMemory(pContextBuffer, sizeof(*pContextBuffer)); -#else // DFEATURE_DBGIPC_TRANSPORT_DI pContextBuffer->ContextFlags = CONTEXT_ALL; IfFailThrow(m_pTarget->GetThreadContext(pThread->GetOSThreadId(), pContextBuffer->ContextFlags, sizeof(*pContextBuffer), reinterpret_cast<BYTE *>(pContextBuffer))); -#endif // DFEATURE_DBGIPC_TRANSPORT_DI } else { diff --git a/src/debug/di/shimremotedatatarget.cpp b/src/debug/di/shimremotedatatarget.cpp index cf60e226b7..c6036f6324 100644 --- a/src/debug/di/shimremotedatatarget.cpp +++ b/src/debug/di/shimremotedatatarget.cpp @@ -281,12 +281,27 @@ ShimRemoteDataTarget::GetThreadContext( BYTE * pContext) { ReturnFailureIfStateNotOk(); - + +#ifdef FEATURE_DBGIPC_TRANSPORT_DI + // GetThreadContext() is currently not implemented in ShimRemoteDataTarget, which is used with our pipe transport + // (FEATURE_DBGIPC_TRANSPORT_DI). Pipe transport is used on POSIX system, but occasionally we can turn it on for Windows for testing, + // and then we'd like to have same behavior as on POSIX system (zero context). + // + // We don't have a good way to implement GetThreadContext() in ShimRemoteDataTarget yet, because we have no way to convert a thread ID to a + // thread handle. The function to do the conversion is OpenThread(), which is not implemented in PAL. Even if we had a handle, PAL implementation + // of GetThreadContext() is very limited and doesn't work when we're not attached with ptrace. + // Instead, we just zero out the seed CONTEXT for the stackwalk. This tells the stackwalker to + // start the stackwalk with the first explicit frame. This won't work when we do native debugging, + // but that won't happen on the POSIX systems since they don't support native debugging. + ZeroMemory(pContext, contextSize); + return S_OK; +#else // ICorDebugDataTarget::GetThreadContext() and ICorDebugDataTarget::SetThreadContext() are currently only // required for interop-debugging and inspection of floating point registers, both of which are not // implemented on Mac. _ASSERTE(!"The remote data target doesn't know how to get a thread's CONTEXT."); return E_NOTIMPL; +#endif // DFEATURE_DBGIPC_TRANSPORT_DI } // impl of interface method ICorDebugMutableDataTarget::SetThreadContext diff --git a/src/dlls/mscoree/unixinterface.cpp b/src/dlls/mscoree/unixinterface.cpp index 1cd9d679b8..21419173e9 100644 --- a/src/dlls/mscoree/unixinterface.cpp +++ b/src/dlls/mscoree/unixinterface.cpp @@ -130,7 +130,7 @@ HRESULT ExecuteAssembly( } *exitCode = -1; - DWORD error = PAL_InitializeCoreCLR(exePath, coreClrPath, true); + DWORD error = PAL_InitializeCoreCLR(exePath); HRESULT hr = HRESULT_FROM_WIN32(error); // If PAL initialization failed, then we should return right away and avoid diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index e6c287f5d8..b9d537f654 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -478,9 +478,7 @@ PALIMPORT DWORD PALAPI PAL_InitializeCoreCLR( - const char *szExePath, - const char *szCoreCLRPath, - BOOL fStayInPAL); + const char *szExePath); PALIMPORT DWORD_PTR @@ -5877,12 +5875,6 @@ VOID PALAPI PAL_LeaveTop(); -// Returns TRUE if the argument HMODULE denotes the PAL itself. -PALIMPORT -BOOL -PALAPI -PAL_IsSelf(IN HMODULE); - #ifdef __cplusplus // // A holder to enter the PAL for a specific region of code. diff --git a/src/pal/src/debug/debug.cpp b/src/pal/src/debug/debug.cpp index 536d40a283..1e108eef4f 100644 --- a/src/pal/src/debug/debug.cpp +++ b/src/pal/src/debug/debug.cpp @@ -37,6 +37,7 @@ Revision History: #include "pal/debug.h" #include "pal/misc.h" #include "pal/malloc.hpp" +#include "pal/module.h" #include "pal/virtual.h" #include <signal.h> @@ -330,6 +331,9 @@ run_debug_command (const char *command) } #endif // ENABLE_RUN_ON_DEBUG_BREAK +#define PID_TEXT "PAL_EXE_PID=" +#define EXE_TEXT "PAL_EXE_NAME=" + static int DebugBreakCommand() @@ -337,15 +341,13 @@ DebugBreakCommand() #ifdef ENABLE_RUN_ON_DEBUG_BREAK const char *command_string = getenv (PAL_RUN_ON_DEBUG_BREAK); if (command_string) { - char pid_buf[sizeof ("PAL_EXE_PID=") + 32]; - char exe_buf[sizeof ("PAL_EXE_NAME=") + MAX_PATH + 1]; - extern char g_ExePath[MAX_PATH]; - if (snprintf (pid_buf, sizeof (pid_buf), - "PAL_EXE_PID=%d", getpid()) <= 0) { + char pid_buf[sizeof (PID_TEXT) + 32]; + char exe_buf[sizeof (EXE_TEXT) + MAX_PATH + 1]; + + if (snprintf (pid_buf, sizeof (pid_buf), PID_TEXT "%d", getpid()) <= 0) { goto FAILED; } - if (snprintf (exe_buf, sizeof (exe_buf), - "PAL_EXE_NAME=%s", g_ExePath) <= 0) { + if (snprintf (exe_buf, sizeof (exe_buf), EXE_TEXT "%ls", (wchar_t *)exe_module.lib_name) <= 0) { goto FAILED; } diff --git a/src/pal/src/include/pal/module.h b/src/pal/src/include/pal/module.h index fada2ae169..e0986de8e0 100644 --- a/src/pal/src/include/pal/module.h +++ b/src/pal/src/include/pal/module.h @@ -44,14 +44,13 @@ typedef VOID (PALAPI *PUNREGISTER_MODULE)(HINSTANCE); /* used to clean typedef struct _MODSTRUCT { - HMODULE self; /* circular reference to this module */ - void *dl_handle; /* handle returned by dlopen() */ - HINSTANCE hinstance; /* handle returned by PAL_RegisterLibrary */ - LPWSTR lib_name; /* full path of module */ - INT refcount; /* reference count */ - /* -1 means infinite reference count - module is never released */ - BOOL ThreadLibCalls; /* TRUE for DLL_THREAD_ATTACH/DETACH notifications - enabled, FALSE if they are disabled */ + HMODULE self; /* circular reference to this module */ + void *dl_handle; /* handle returned by dlopen() */ + HINSTANCE hinstance; /* handle returned by PAL_RegisterLibrary */ + LPWSTR lib_name; /* full path of module */ + INT refcount; /* reference count */ + /* -1 means infinite reference count - module is never released */ + BOOL threadLibCalls; /* TRUE for DLL_THREAD_ATTACH/DETACH notifications enabled, FALSE if they are disabled */ #if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN ino_t inode; @@ -65,26 +64,23 @@ typedef struct _MODSTRUCT struct _MODSTRUCT *prev; } MODSTRUCT; -extern MODSTRUCT pal_module; - +extern MODSTRUCT exe_module; /*++ Function : - LoadInitializeModules + LOADInitializeModules Initialize the process-wide list of modules (2 initial modules : 1 for the executable and 1 for the PAL) Parameters : - LPWSTR exe_name : full path to executable + None Return value : TRUE on success, FALSE on failure -Notes : - the module manager takes ownership of the string --*/ -BOOL LOADInitializeModules(LPWSTR exe_name); +BOOL LOADInitializeModules(); /*++ Function : @@ -183,19 +179,33 @@ Return value: BOOL PAL_LOADUnloadPEFile(void * ptr); /*++ - LOADInitCoreCLRModules + LOADInitializeCoreCLRModule - Run the initialization methods for CoreCLR modules that used to be standalone dynamic libraries (PALRT and - mscorwks). + Run the initialization methods for CoreCLR module. Parameters: - Core CLR path + None Return value: TRUE if successful FALSE if failure --*/ -BOOL LOADInitCoreCLRModules(const char *szCoreCLRPath); +BOOL LOADInitializeCoreCLRModule(); + +/*++ +Function : + LOADGetPalLibrary + + Load and initialize the PAL module. + +Parameters : + None + +Return value : + handle to loaded module + +--*/ +MODSTRUCT *LOADGetPalLibrary(); #ifdef __cplusplus } diff --git a/src/pal/src/include/pal/procobj.hpp b/src/pal/src/include/pal/procobj.hpp index c3619300a3..2e00200736 100644 --- a/src/pal/src/include/pal/procobj.hpp +++ b/src/pal/src/include/pal/procobj.hpp @@ -102,12 +102,17 @@ namespace CorUnix ); PAL_ERROR - CreateInitialProcessAndThreadObjects( + InitializeProcessCommandLine( CPalThread *pThread, LPWSTR lpwstrCmdLine, LPWSTR lpwstrFullPath ); + PAL_ERROR + CreateInitialProcessAndThreadObjects( + CPalThread *pThread + ); + extern IPalObject *g_pobjProcess; } diff --git a/src/pal/src/init/pal.cpp b/src/pal/src/init/pal.cpp index 14e5d0c984..c2e66a5d3e 100644 --- a/src/pal/src/init/pal.cpp +++ b/src/pal/src/init/pal.cpp @@ -85,6 +85,7 @@ SET_DEFAULT_DEBUG_CHANNEL(PAL); Volatile<INT> init_count = 0; Volatile<BOOL> shutdown_intent = 0; +Volatile<LONG> g_coreclrInitialized = 0; static BOOL g_fThreadDataAvailable = FALSE; static pthread_mutex_t init_critsec_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -92,8 +93,6 @@ static pthread_mutex_t init_critsec_mutex = PTHREAD_MUTEX_INITIALIZER; very first PAL_Initialize call, and is freed afterward. */ static PCRITICAL_SECTION init_critsec = NULL; -char g_szCoreCLRPath[MAX_PATH] = { 0 }; - static int Initialize(int argc, const char *const argv[], DWORD flags); static BOOL INIT_IncreaseDescriptorLimit(void); static LPWSTR INIT_FormatCommandLine (CPalThread *pThread, int argc, const char * const *argv); @@ -103,8 +102,6 @@ static LPWSTR INIT_FindEXEPath(CPalThread *pThread, LPCSTR exe_name); extern void PROCDumpThreadList(void); #endif -char g_ExePath[MAX_PATH] = { 0 }; - #if defined(__APPLE__) static bool RunningNatively() { @@ -230,19 +227,20 @@ Initialize( InternalEnterCriticalSection(pThread, init_critsec); // here pThread is always NULL - if(init_count==0) + if (init_count == 0) { // Set our pid. gPID = getpid(); fFirstTimeInit = true; + exe_module.lib_name = NULL; // Initialize the TLS lookaside cache if (FALSE == TLSInitialize()) { goto done; } - + // Initialize the environment. if (FALSE == MiscInitialize()) { @@ -263,11 +261,11 @@ Initialize( if (VIRTUAL_PAGE_SIZE != getpagesize()) { ASSERT("VIRTUAL_PAGE_SIZE is incorrect for this system!\n" - "Change include/pal/virtual.h and clr/src/inc/stdmacros.h " - "to reflect the correct page size of %d.\n", getpagesize()); + "Change include/pal/virtual.h and clr/src/inc/stdmacros.h " + "to reflect the correct page size of %d.\n", getpagesize()); } #endif // _DEBUG - + if (!INIT_IncreaseDescriptorLimit()) { ERROR("Unable to increase the file descriptor limit!\n"); @@ -276,7 +274,7 @@ Initialize( } /* initialize the shared memory infrastructure */ - if(!SHMInitialize()) + if (!SHMInitialize()) { ERROR("Shared memory initialization failed!\n"); goto CLEANUP0; @@ -373,73 +371,84 @@ Initialize( g_pSynchronizationManager = CPalSynchMgrController::CreatePalSynchronizationManager(pThread); - palError = ERROR_GEN_FAILURE; - if (NULL == g_pSynchronizationManager) { + palError = ERROR_NOT_ENOUGH_MEMORY; ERROR("Failure creating synchronization manager\n"); goto CLEANUP1c; } + } + else + { + pThread = InternalGetCurrentThread(); + } + + palError = ERROR_GEN_FAILURE; - if (argc > 0 && argv != NULL) + if (argc > 0 && argv != NULL) + { + /* build the command line */ + command_line = INIT_FormatCommandLine(pThread, argc, argv); + if (NULL == command_line) { - /* build the command line */ - command_line = INIT_FormatCommandLine(pThread, argc, argv); - if (NULL == command_line) - { - ERROR("Error building command line\n"); - goto CLEANUP1d; - } + ERROR("Error building command line\n"); + goto CLEANUP1d; + } - /* find out the application's full path */ - exe_path = INIT_FindEXEPath(pThread, argv[0]); - if (NULL == exe_path) - { - ERROR("Unable to find exe path\n"); - goto CLEANUP1e; - } + /* find out the application's full path */ + exe_path = INIT_FindEXEPath(pThread, argv[0]); + if (NULL == exe_path) + { + ERROR("Unable to find exe path\n"); + goto CLEANUP1e; + } - if (!WideCharToMultiByte(CP_ACP, 0, exe_path, -1, g_ExePath, - sizeof(g_ExePath), NULL, NULL)) - { - ERROR("Failed to store process executable path\n"); - goto CLEANUP2; - } + if (NULL == command_line || NULL == exe_path) + { + ERROR("Failed to process command-line parameters!\n"); + goto CLEANUP2; + } - if (NULL == command_line || NULL == exe_path) - { - ERROR("Failed to process command-line parameters!\n"); - goto CLEANUP2; - } + palError = InitializeProcessCommandLine( + pThread, + command_line, + exe_path); + + if (NO_ERROR != palError) + { + ERROR("Unable to initialize command line\n"); + goto CLEANUP2; + } + + // InitializeProcessCommandLine took ownership of this memory. + command_line = NULL; + + // Save the exe path in the exe module struct + InternalFree(pThread, exe_module.lib_name); + exe_module.lib_name = exe_path; #ifdef PAL_PERF - // Initialize the Profiling structure - if(FALSE == PERFInitialize(command_line, exe_path)) - { - ERROR("Performance profiling initial failed\n"); - goto done; - } - PERFAllocThreadInfo(); + // Initialize the Profiling structure + if(FALSE == PERFInitialize(command_line, exe_path)) + { + ERROR("Performance profiling initial failed\n"); + goto done; + } + PERFAllocThreadInfo(); #endif - } + } + if(init_count == 0) + { // // Create the initial process and thread objects // - - palError = CreateInitialProcessAndThreadObjects( - pThread, - command_line, - exe_path - ); - + palError = CreateInitialProcessAndThreadObjects(pThread); if (NO_ERROR != palError) { ERROR("Unable to create initial process and thread objects\n"); goto CLEANUP2; } - // CreateInitialProcessAndThreadObjects took ownership of this memory. - command_line = NULL; if (flags & PAL_INITIALIZE_SYNC_THREAD) { @@ -470,8 +479,8 @@ Initialize( goto CLEANUP6; } - /* initialize module manager */ - if (FALSE == LOADInitializeModules(exe_path)) + /* Initialize module manager */ + if (FALSE == LOADInitializeModules()) { ERROR("Unable to initialize module manager\n"); palError = GetLastError(); @@ -587,6 +596,7 @@ exit : return retval; } + /*++ Function: PAL_InitializeCoreCLR @@ -599,11 +609,6 @@ Abstract: This routine also makes sure the psuedo dynamic libraries PALRT and mscorwks have their initialization methods called. - Which PAL (if any) we're executing in the context of is a function of the return code and the fStayInPAL - argument. If an error is returned then the PAL context is that of the caller (i.e. this call doesn't switch - into the context of the PAL being initialized). Otherwise (on success) the context is remains in that of the - new PAL if and only if fStayInPAL is TRUE. - Return: ERROR_SUCCESS if successful An error code, if it failed @@ -611,59 +616,26 @@ Return: --*/ PAL_ERROR PALAPI -PAL_InitializeCoreCLR( - const char *szExePath, - const char *szCoreCLRPath, - BOOL fStayInPAL) +PAL_InitializeCoreCLR(const char *szExePath) { - // Check for a repeated call (this is a no-op). - if (g_szCoreCLRPath[0] != '\0') - { - if (fStayInPAL) - { - PAL_Enter(PAL_BoundaryTop); - } - return ERROR_SUCCESS; - } - - // Make sure it's an absolute path. - if (szCoreCLRPath[0] != '/') - { - return ERROR_INVALID_PARAMETER; - } - - // Check we can handle the length of the installation directory. - size_t cchCoreCLRPath = strlen(szCoreCLRPath); - if (cchCoreCLRPath >= sizeof(g_szCoreCLRPath)) - { - ASSERT("CoreCLR installation path is too long"); - return ERROR_BAD_PATHNAME; - } - - // Stash a copy of the CoreCLR installation path in a global variable. - // Make sure it's terminated with a slash. - if (strcpy_s(g_szCoreCLRPath, sizeof(g_szCoreCLRPath), szCoreCLRPath) != SAFECRT_SUCCESS) - { - ASSERT("strcpy_s failed!"); - return ERROR_FILENAME_EXCED_RANGE; - } - -#ifdef __APPLE__ // Fake up a command line to call PAL_Initialize with. - const char *argv[] = { "CoreCLR" }; - int result = PAL_Initialize(1, argv); -#else // __APPLE__ // Fake up a command line to call PAL_Initialize with. int result = PAL_Initialize(1, &szExePath); -#endif // __APPLE__ if (result != 0) { return GetLastError(); } + // Check for a repeated call (this is a no-op). + if (InterlockedIncrement(&g_coreclrInitialized) > 1) + { + PAL_Enter(PAL_BoundaryTop); + return ERROR_SUCCESS; + } + // Now that the PAL is initialized it's safe to call the initialization methods for the code that used to // be dynamically loaded libraries but is now statically linked into CoreCLR just like the PAL, i.e. the // PAL RT and mscorwks. - if (!LOADInitCoreCLRModules(g_szCoreCLRPath)) + if (!LOADInitializeCoreCLRModule()) { return ERROR_DLL_INIT_FAILED; } @@ -673,10 +645,6 @@ PAL_InitializeCoreCLR( return ERROR_GEN_FAILURE; } - if (!fStayInPAL) - { - PAL_Leave(PAL_BoundaryTop); - } return ERROR_SUCCESS; } diff --git a/src/pal/src/init/sxs.cpp b/src/pal/src/init/sxs.cpp index aeaa19353d..e3fed10849 100644 --- a/src/pal/src/init/sxs.cpp +++ b/src/pal/src/init/sxs.cpp @@ -25,28 +25,6 @@ SET_DEFAULT_DEBUG_CHANNEL(SXS); PAL_ERROR AllocatePalThread(CPalThread **ppThread); -/*++ -Function: - PAL_IsSelf - -Abstract: - Returns TRUE iff the argument module corresponds to this PAL. - In other words, clients should not call PAL_Leave when calling - functions obtained from this module using GetProcAddress. ---*/ -BOOL -PALAPI -PAL_IsSelf(HMODULE hModule) -{ - ENTRY("PAL_IsSelf(hModule=%p)\n", hModule); - - MODSTRUCT *module = (MODSTRUCT *) hModule; - BOOL fIsSelf = (module->dl_handle == pal_module.dl_handle); - - LOGEXIT("PAL_IsSelf returns %d\n", fIsSelf); - return fIsSelf; -} - /************************* Enter *************************/ /*++ diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp index ad61285a9f..2a7d2c4b54 100644 --- a/src/pal/src/loader/module.cpp +++ b/src/pal/src/loader/module.cpp @@ -89,7 +89,9 @@ SET_DEFAULT_DEBUG_CHANNEL(LOADER); CRITICAL_SECTION module_critsec; MODSTRUCT exe_module; /* always the first, in the in-load-order list */ -MODSTRUCT pal_module; /* always the second, in the in-load-order list */ +MODSTRUCT *pal_module = NULL; + +char g_szCoreCLRPath[MAX_PATH] = { 0 }; /* static function declarations ***********************************************/ @@ -158,14 +160,14 @@ LoadLibraryExA( (lpLibFileName)?lpLibFileName:"NULL", (lpLibFileName)?lpLibFileName:"NULL"); - if(NULL == lpLibFileName) + if (NULL == lpLibFileName) { ERROR("lpLibFileName is NULL;Exit.\n"); SetLastError(ERROR_MOD_NOT_FOUND); goto Done; } - if(lpLibFileName[0]=='\0') + if (lpLibFileName[0]=='\0') { ERROR("can't load library with NULL file name...\n"); SetLastError(ERROR_INVALID_PARAMETER); @@ -175,7 +177,7 @@ LoadLibraryExA( pThread = InternalGetCurrentThread(); /* do the Dos/Unix conversion on our own copy of the name */ lpstr = InternalStrdup(pThread, lpLibFileName); - if(!lpstr) + if (!lpstr) { ERROR("InternalStrdup failure!\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -227,14 +229,14 @@ LoadLibraryExW( lpLibFileName?lpLibFileName:W16_NULLSTRING, lpLibFileName?lpLibFileName:W16_NULLSTRING); - if(NULL == lpLibFileName) + if (NULL == lpLibFileName) { ERROR("lpLibFileName is NULL;Exit.\n"); SetLastError(ERROR_MOD_NOT_FOUND); goto done; } - if(lpLibFileName[0]==0) + if (lpLibFileName[0]==0) { ERROR("Can't load library with NULL file name...\n"); SetLastError(ERROR_INVALID_PARAMETER); @@ -245,10 +247,10 @@ LoadLibraryExW( name_length = WideCharToMultiByte(CP_ACP, 0, lpLibFileName, -1, lpstr, MAX_PATH, NULL, NULL); - if( name_length == 0 ) + if (name_length == 0) { DWORD dwLastError = GetLastError(); - if( dwLastError == ERROR_INSUFFICIENT_BUFFER ) + if (dwLastError == ERROR_INSUFFICIENT_BUFFER) { ERROR("lpLibFileName is larger than MAX_PATH (%d)!\n", MAX_PATH); } @@ -297,14 +299,14 @@ GetProcAddress( /* parameter validation */ - if( (lpProcName == NULL) || (*lpProcName == '\0') ) + if ((lpProcName == NULL) || (*lpProcName == '\0')) { TRACE("No function name given\n"); SetLastError(ERROR_INVALID_PARAMETER); goto done; } - if( !LOADValidateModule(module) ) + if (!LOADValidateModule(module)) { TRACE("Invalid module handle %p\n", hModule); SetLastError(ERROR_INVALID_HANDLE); @@ -316,7 +318,7 @@ GetProcAddress( because of the address range reserved for ordinals contain can be a valid string address on non-Windows systems */ - if( (DWORD_PTR)lpProcName < VIRTUAL_PAGE_SIZE ) + if ((DWORD_PTR)lpProcName < VIRTUAL_PAGE_SIZE) { ASSERT("Attempt to locate symbol by ordinal?!\n"); } @@ -326,7 +328,7 @@ GetProcAddress( // If we're looking for a symbol inside the PAL, we try the PAL_ variant // first because otherwise we run the risk of having the non-PAL_ // variant preferred over the PAL's implementation. - if (module->dl_handle == pal_module.dl_handle) + if (pal_module && module->dl_handle == pal_module->dl_handle) { int iLen = 4 + strlen(lpProcName) + 1; LPSTR lpPALProcName = (LPSTR) alloca(iLen); @@ -363,13 +365,13 @@ GetProcAddress( /* if we don't know the module's full name yet, this is our chance to obtain it */ - if(!module->lib_name && module->dl_handle) + if (!module->lib_name && module->dl_handle) { const char* libName = PAL_dladdr((LPVOID)ProcAddress); if (libName) { module->lib_name = UTIL_MBToWC_Alloc(libName, -1); - if(NULL == module->lib_name) + if (NULL == module->lib_name) { ERROR("MBToWC failure; can't save module's full name\n"); } @@ -424,14 +426,14 @@ FreeLibrary( goto done; } - if( !LOADValidateModule( module ) ) + if (!LOADValidateModule(module)) { TRACE("Can't free invalid module handle %p\n", hLibModule); SetLastError(ERROR_INVALID_HANDLE); goto done; } - if( module->refcount == -1 ) + if (module->refcount == -1) { /* special module - never released */ retval = TRUE; @@ -442,7 +444,7 @@ FreeLibrary( TRACE("Reference count for module %p (named %S) decreases to %d\n", module, MODNAME(module), module->refcount); - if( module->refcount != 0 ) + if (module->refcount != 0) { retval = TRUE; goto done; @@ -462,7 +464,7 @@ FreeLibrary( module->self = NULL; /* Call DllMain if the module contains one */ - if(module->pDllMain) + if (module->pDllMain) { TRACE("Calling DllMain (%p) for module %S\n", module->pDllMain, @@ -497,7 +499,7 @@ FreeLibrary( #endif /* !_NO_DEBUG_MESSAGES_ */ } - if(module->dl_handle && 0 != dlclose(module->dl_handle)) + if (module->dl_handle && 0 != dlclose(module->dl_handle)) { /* report dlclose() failure, but proceed anyway. */ WARN("dlclose() call failed! error message is \"%s\"\n", dlerror()); @@ -570,7 +572,7 @@ GetModuleFileNameA( hModule, lpFileName, nSize); LockModuleList(); - if(hModule && !LOADValidateModule((MODSTRUCT *)hModule)) + if (hModule && !LOADValidateModule((MODSTRUCT *)hModule)) { TRACE("Can't find name for invalid module handle %p\n", hModule); SetLastError(ERROR_INVALID_HANDLE); @@ -578,7 +580,7 @@ GetModuleFileNameA( } wide_name = LOADGetModuleFileName((MODSTRUCT *)hModule); - if(!wide_name) + if (!wide_name) { ASSERT("Can't find name for valid module handle %p\n", hModule); SetLastError(ERROR_INTERNAL_ERROR); @@ -589,7 +591,7 @@ GetModuleFileNameA( name_length = WideCharToMultiByte(CP_ACP, 0, wide_name, -1, lpFileName, nSize, NULL, NULL); - if( name_length==0 ) + if (name_length == 0) { TRACE("Buffer too small to copy module's file name.\n"); SetLastError(ERROR_INSUFFICIENT_BUFFER); @@ -638,7 +640,7 @@ GetModuleFileNameW( wcscpy_s(lpFileName, nSize, W("")); - if(hModule && !LOADValidateModule((MODSTRUCT *)hModule)) + if (hModule && !LOADValidateModule((MODSTRUCT *)hModule)) { TRACE("Can't find name for invalid module handle %p\n", hModule); SetLastError(ERROR_INVALID_HANDLE); @@ -646,7 +648,7 @@ GetModuleFileNameW( } wide_name = LOADGetModuleFileName((MODSTRUCT *)hModule); - if(!wide_name) + if (!wide_name) { TRACE("Can't find name for valid module handle %p\n", hModule); SetLastError(ERROR_INTERNAL_ERROR); @@ -656,7 +658,7 @@ GetModuleFileNameW( /* Copy module name into supplied buffer */ name_length = lstrlenW(wide_name); - if(name_length >= (INT)nSize) + if (name_length >= (INT)nSize) { TRACE("Buffer too small to copy module's file name.\n"); SetLastError(ERROR_INSUFFICIENT_BUFFER); @@ -692,7 +694,7 @@ PAL_RegisterModule( HINSTANCE hinstance = NULL; int err = PAL_InitializeDLL(); - if(err == 0) + if (err == 0) { PERF_ENTRY(PAL_RegisterModule); ENTRY("PAL_RegisterModule(%s)\n", lpLibFileName ? lpLibFileName : ""); @@ -838,77 +840,64 @@ Function : the executable and 1 for the PAL) Parameters : - LPWSTR exe_name : full path to executable + None -Return value: +Return value : TRUE if initialization succeedded FALSE otherwise -Notes : - the module manager takes ownership of the exe_name string --*/ extern "C" -BOOL LOADInitializeModules(LPWSTR exe_name) +BOOL LOADInitializeModules() { #if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN - LPSTR pszExeName = NULL; - CPalThread *pThread = NULL; + LPSTR pszExeName = NULL; #endif - BOOL fRetCode = FALSE; + BOOL fRetCode = FALSE; + LPWSTR lpwstr = NULL; - if(exe_module.prev) + if (exe_module.prev) { ERROR("Module manager already initialized!\n"); - SetLastError(ERROR_INTERNAL_ERROR); - goto Done; + goto exit; } InternalInitializeCriticalSection(&module_critsec); - /* initialize module for main executable */ + // Initialize module for main executable TRACE("Initializing module for main executable\n"); + exe_module.self = (HMODULE)&exe_module; exe_module.dl_handle = dlopen(NULL, RTLD_LAZY); - if(!exe_module.dl_handle) + if (!exe_module.dl_handle) { - ASSERT("Main executable module will be broken : dlopen(NULL) failed. " - "dlerror message is \"%s\" \n", dlerror()); + ERROR("Main executable module will be broken : dlopen(NULL) failed" + "dlerror message is \"%s\" \n", dlerror()); + goto exit; } - exe_module.lib_name = exe_name; exe_module.refcount = -1; - exe_module.next = &pal_module; - exe_module.prev = &pal_module; + exe_module.next = &exe_module; + exe_module.prev = &exe_module; exe_module.pDllMain = NULL; exe_module.hinstance = NULL; - exe_module.ThreadLibCalls = TRUE; - - TRACE("Initializing module for PAL library\n"); - pal_module.self = (HANDLE)&pal_module; - pal_module.lib_name = NULL; - pal_module.dl_handle = NULL; - pal_module.refcount= - 1; - pal_module.next = &exe_module; - pal_module.prev = &exe_module; - pal_module.pDllMain = NULL; - pal_module.hinstance = NULL; - pal_module.ThreadLibCalls = TRUE; + exe_module.threadLibCalls = TRUE; // For platforms where we can't trust the handle to be constant, we need to // store the inode/device pairs for the modules we just initialized. #if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN { struct stat stat_buf; - pszExeName = UTIL_WCToMB_Alloc(exe_name, -1); + pszExeName = UTIL_WCToMB_Alloc(exe_module.lib_name, -1); if (NULL == pszExeName) { ERROR("WCToMB failure, unable to get full name of exe\n"); - goto Done; + goto exit; } if ( -1 == stat(pszExeName, &stat_buf)) { SetLastError(ERROR_MOD_NOT_FOUND); - goto Done; + goto exit; } TRACE("Executable has inode %d and device %d\n", @@ -916,32 +905,29 @@ BOOL LOADInitializeModules(LPWSTR exe_name) exe_module.inode = stat_buf.st_ino; exe_module.device = stat_buf.st_dev; - if ( -1 == stat(librotor_fname, &stat_buf)) - { - SetLastError(ERROR_MOD_NOT_FOUND); - goto Done; - } - - TRACE("PAL Library has inode %d and device %d\n", - stat_buf.st_ino, stat_buf.st_dev); - - pal_module.inode = stat_buf.st_ino; - pal_module.device = stat_buf.st_dev; } #endif // If we got here, init succeeded. fRetCode = TRUE; - Done: - if (!fRetCode && GetLastError() == ERROR_SUCCESS) + +exit: + CPalThread *pThread = InternalGetCurrentThread(); + if (!fRetCode) { - ASSERT("returning failure, but last error not set\n"); + InternalFree(pThread, lpwstr); + if (GetLastError() == ERROR_SUCCESS) + { + SetLastError(ERROR_INTERNAL_ERROR); + } } #if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN - pThread = InternalGetCurrentThread(); if (pszExeName) + { InternalFree(pThread, pszExeName); + } + #endif TRACE("Module manager initialization returning %d.\n", fRetCode); return fRetCode; @@ -964,7 +950,7 @@ void LOADFreeModules(BOOL bTerminateUnconditionally) MODSTRUCT *module; CPalThread *pThread = InternalGetCurrentThread(); - if(!exe_module.prev) + if (!exe_module.prev) { ERROR("Module manager not initialized!\n"); return; @@ -980,10 +966,10 @@ void LOADFreeModules(BOOL bTerminateUnconditionally) // Call DllMain if the module contains one and if we're supposed // to call DllMains. - if( !bTerminateUnconditionally && module->pDllMain ) + if (!bTerminateUnconditionally && module->pDllMain) { /* Exception-safe call to DllMain */ - LOAD_SEH_CallDllMain( module, DLL_PROCESS_DETACH, (LPVOID)-1 ); + LOAD_SEH_CallDllMain(module, DLL_PROCESS_DETACH, (LPVOID)-1); } /* Remove the current MODSTRUCT from the list, then free its memory */ @@ -996,12 +982,12 @@ void LOADFreeModules(BOOL bTerminateUnconditionally) InternalFree( pThread, module->lib_name ); module->lib_name = NULL; - if (module != &exe_module && module != &pal_module) + if (module != &exe_module) { InternalFree( pThread, module ); } } - while( module != &exe_module ); + while (module != &exe_module); /* Flag the module manager as uninitialized */ exe_module.prev = NULL; @@ -1074,9 +1060,9 @@ void LOADCallDllMain(DWORD dwReason, LPVOID lpReserved) if (!InLoadOrder) module = module->prev; - if (module->ThreadLibCalls) + if (module->threadLibCalls) { - if(module->pDllMain) + if (module->pDllMain) { #if !_NO_DEBUG_MESSAGES_ /* reset ENTRY nesting level back to zero while inside the callback... */ @@ -1132,7 +1118,7 @@ DisableThreadLibraryCalls( LockModuleList(); module = (MODSTRUCT *) hLibModule; - if(!LOADValidateModule(module)) + if (!LOADValidateModule(module)) { // DisableThreadLibraryCalls() does nothing when given // an invalid module handle. This matches the Windows @@ -1142,7 +1128,7 @@ DisableThreadLibraryCalls( goto done; } - module->ThreadLibCalls = FALSE; + module->threadLibCalls = FALSE; ret = TRUE; done: @@ -1181,10 +1167,10 @@ static BOOL LOADValidateModule(MODSTRUCT *module) really a module (HMODULEs are actually MODSTRUCT pointers) */ do { - if(module == modlist_enum) + if (module == modlist_enum) { /* found it; check its integrity to be on the safe side */ - if(module->self != module) + if (module->self != module) { ERROR("Found corrupt module %p!\n",module); UnlockModuleList(); @@ -1224,7 +1210,7 @@ static LPWSTR LOADGetModuleFileName(MODSTRUCT *module) { LPWSTR module_name; /* special case : if module is NULL, we want the name of the executable */ - if(!module) + if (!module) { module_name = exe_module.lib_name; TRACE("Returning name of main executable\n"); @@ -1265,15 +1251,15 @@ static MODSTRUCT *LOADAllocModule(void *dl_handle, LPCSTR name) pThread = InternalGetCurrentThread(); /* no match found : try to create a new module structure */ - module=(MODSTRUCT *) InternalMalloc(pThread, sizeof(MODSTRUCT)); - if(!module) + module = (MODSTRUCT *)InternalMalloc(pThread, sizeof(MODSTRUCT)); + if (!module) { ERROR("malloc() failed! errno is %d (%s)\n", errno, strerror(errno)); return NULL; } wide_name = UTIL_MBToWC_Alloc(name, -1); - if(NULL == wide_name) + if (NULL == wide_name) { ERROR("couldn't convert name to a wide-character string\n"); InternalFree(pThread, module); @@ -1295,7 +1281,7 @@ static MODSTRUCT *LOADAllocModule(void *dl_handle, LPCSTR name) #endif // NEED_DLCOMPAT module->self = module; module->hinstance = NULL; - module->ThreadLibCalls = TRUE; + module->threadLibCalls = TRUE; module->next = NULL; module->prev = NULL; @@ -1325,6 +1311,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) MODSTRUCT *module = NULL; void *dl_handle; DWORD dwError; + DWORD retval; // Check whether we have been requested to load 'libc'. If that's the case then use the // full name of the library that is defined in <gnu/lib-names.h> by the LIBC_SO constant. @@ -1344,9 +1331,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) LockModuleList(); - /* see if file can be dlopen()ed; this should work even if it's already - loaded */ - + // See if file can be dlopen()ed; this should work even if it's already loaded { // See GetProcAddress for an explanation why we leave the PAL. PAL_LeaveHolder holder; @@ -1407,7 +1392,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) TRACE("Module doesn't exist : creating %s.\n", shortAsciiName); module = LOADAllocModule(dl_handle, shortAsciiName); - if(NULL == module) + if (NULL == module) { ERROR("couldn't create new module\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -1426,8 +1411,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) module->device = stat_buf.st_dev; #endif - /* If we get here, then we have created a new module structure. We can now - get the address of DllMain if the module contains one. We save + /* We now get the address of DllMain if the module contains one. We save the last error and restore it afterward, because our caller doesn't care about GetProcAddress failures. */ dwError = GetLastError(); @@ -1437,13 +1421,11 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) SetLastError(dwError); /* If it did contain a DllMain, call it. */ - if(module->pDllMain) + if (module->pDllMain) { - DWORD dllmain_retval = FALSE; - - TRACE("Calling DllMain (%p) for module %S\n", - module->pDllMain, - module->lib_name ? module->lib_name : W16_NULLSTRING); + TRACE("Calling DllMain (%p) for module %S\n", + module->pDllMain, + module->lib_name ? module->lib_name : W16_NULLSTRING); if (NULL == module->hinstance) { @@ -1472,7 +1454,7 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) // This module may be foreign to our PAL, so leave our PAL. // If it depends on us, it will re-enter. PAL_LeaveHolder holder; - dllmain_retval = module->pDllMain(module->hinstance, DLL_PROCESS_ATTACH, fDynamic ? NULL : (LPVOID)-1); + retval = module->pDllMain(module->hinstance, DLL_PROCESS_ATTACH, fDynamic ? NULL : (LPVOID)-1); } #if !_NO_DEBUG_MESSAGES_ @@ -1481,16 +1463,15 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) #endif /* !_NO_DEBUG_MESSAGES_ */ } - /* If DlMain(DLL_PROCESS_ATTACH) returns FALSE, we must immediately - unload the module.*/ - if(FALSE == dllmain_retval) + // If DlMain(DLL_PROCESS_ATTACH) returns FALSE, we must immediately unload the module + if (!retval) { - TRACE("DllMain returned FALSE; unloading module.\n"); + ERROR("DllMain returned FALSE; unloading module.\n"); module->pDllMain = NULL; - FreeLibrary((HMODULE) module); - ERROR("DllMain failed and returned NULL. \n"); + FreeLibrary((HMODULE)module); SetLastError(ERROR_DLL_INIT_FAILED); module = NULL; + goto done; } } else @@ -1687,44 +1668,74 @@ BOOL PAL_LOADUnloadPEFile(void * ptr) } /*++ - LOADInitCoreCLRModules + LOADInitializeCoreCLRModule - Run the initialization methods for CoreCLR modules that used to be standalone dynamic libraries (PALRT and - mscorwks). + Run the initialization methods for CoreCLR module (the module containing this PAL). Parameters: - Core CLR path + None Return value: TRUE if successful FALSE if failure --*/ -BOOL LOADInitCoreCLRModules( - const char *szCoreCLRPath) +BOOL LOADInitializeCoreCLRModule() { - TRACE("PAL library is %s\n", szCoreCLRPath); - LPWSTR lpwstr = UTIL_MBToWC_Alloc(szCoreCLRPath, -1); - if(!lpwstr) + MODSTRUCT *module = LOADGetPalLibrary(); + if (!module) { - ERROR("MBToWC failure, unable to save full name of PAL module\n"); + ERROR("Can not load the PAL module\n"); return FALSE; } - pal_module.lib_name = lpwstr; - pal_module.dl_handle = dlopen(szCoreCLRPath, RTLD_LAZY); - if(!pal_module.dl_handle) + PDLLMAIN pRuntimeDllMain = (PDLLMAIN)dlsym(module->dl_handle, "CoreDllMain"); + if (!pRuntimeDllMain) { - ERROR("PAL module will be broken : dlopen(%s) failed. dlerror message is \"%s\"\n ", - szCoreCLRPath, dlerror()); + ERROR("Can not find the CoreDllMain entry point\n"); return FALSE; } - PDLLMAIN pRuntimeDllMain = (PDLLMAIN)dlsym(pal_module.dl_handle, "CoreDllMain"); - if (!pRuntimeDllMain) + return pRuntimeDllMain(module->hinstance, DLL_PROCESS_ATTACH, NULL); +} + +/*++ +Function : + LOADGetPalLibrary + + Load and initialize the PAL module. + +Parameters : + None + +Return value : + pointer to module struct + +--*/ +MODSTRUCT *LOADGetPalLibrary() +{ + if (pal_module == NULL) { - ERROR("Can not find the CoreDllMain entry point in %s\n", szCoreCLRPath); - return FALSE; + // Initialize the pal module (the module containing LOADPalLibrary). Assumes that + // the PAL is linked into the coreclr module because we use the module name containing + // this function for the coreclr path. + TRACE("Loading module for PAL library\n"); + + Dl_info info; + if (dladdr((PVOID)&LOADGetPalLibrary, &info) == 0) + { + ERROR("LOADGetPalLibrary: dladdr() failed. dlerror message is \"%s\"\n", dlerror()); + goto exit; + } + // Stash a copy of the CoreCLR installation path in a global variable. + // Make sure it's terminated with a slash. + if (strcpy_s(g_szCoreCLRPath, sizeof(g_szCoreCLRPath), info.dli_fname) != SAFECRT_SUCCESS) + { + ERROR("LOADGetPalLibrary: strcpy_s failed!"); + goto exit; + } + pal_module = (MODSTRUCT *)LOADLoadLibrary(info.dli_fname, FALSE); } - pal_module.hinstance = (HINSTANCE)LOADLoadLibrary(szCoreCLRPath, FALSE); - return pRuntimeDllMain(pal_module.hinstance, DLL_PROCESS_ATTACH, NULL); + +exit: + return pal_module; } // Get base address of the module containing a given symbol diff --git a/src/pal/src/misc/miscpalapi.cpp b/src/pal/src/misc/miscpalapi.cpp index 88e285929a..45596a513e 100644 --- a/src/pal/src/misc/miscpalapi.cpp +++ b/src/pal/src/misc/miscpalapi.cpp @@ -68,7 +68,13 @@ PAL_GetPALDirectoryW( OUT LPWSTR lpDirectoryName, IN UINT cchDirectoryName ) PERF_ENTRY(PAL_GetPALDirectoryW); ENTRY( "PAL_GetPALDirectoryW( %p, %d )\n", lpDirectoryName, cchDirectoryName ); - lpFullPathAndName = pal_module.lib_name; + MODSTRUCT *module = LOADGetPalLibrary(); + if (!module) + { + SetLastError(ERROR_INTERNAL_ERROR); + goto EXIT; + } + lpFullPathAndName = module->lib_name; if (lpFullPathAndName == NULL) { SetLastError(ERROR_INTERNAL_ERROR); diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp index 498d05fc7d..63027d5a2f 100644 --- a/src/pal/src/thread/process.cpp +++ b/src/pal/src/thread/process.cpp @@ -121,11 +121,11 @@ CPalThread* CorUnix::pGThreadList; DWORD g_dwThreadCount; // -// The command line for the process +// The command line and app name for the process // -LPWSTR g_lpwstrCmdLine; - +LPWSTR g_lpwstrCmdLine = NULL; +LPWSTR g_lpwstrAppDir = NULL; /* Thread ID of thread that has started the ExitProcess process */ Volatile<LONG> terminator = 0; @@ -133,8 +133,6 @@ Volatile<LONG> terminator = 0; // Process ID of this process. DWORD gPID = (DWORD) -1; -LPWSTR pAppDir = NULL; - // // Key used for associating CPalThread's with the underlying pthread // (through pthread_setspecific) @@ -1631,17 +1629,19 @@ See MSDN doc. LPWSTR PALAPI GetCommandLineW( - VOID) + VOID) { PERF_ENTRY(GetCommandLineW); ENTRY("GetCommandLineW()\n"); + LPWSTR lpwstr = g_lpwstrCmdLine ? g_lpwstrCmdLine : (LPWSTR)W(""); + LOGEXIT("GetCommandLineW returns LPWSTR %p (%S)\n", g_lpwstrCmdLine, - g_lpwstrCmdLine); + lpwstr); PERF_EXIT(GetCommandLineW); - return g_lpwstrCmdLine; + return lpwstr; } /*++ @@ -2159,49 +2159,39 @@ CorUnix::InitializeProcessData( } /*++ -Function: - CreateInitialProcessAndThreadObjects +Function + InitializeProcessCommandLine Abstract - Creates the IPalObjects that represent the current process - and the initial thread + Initializes (or re-initializes) the saved command line and exe path. Parameter - pThread - the initial thread - lpwstrCmdLine - lpwstrFullPath + pThread - the initial thread + lpwstrCmdLine + lpwstrFullPath Return - PAL_ERROR + PAL_ERROR -Notes : +Notes This function takes ownership of lpwstrCmdLine, but not of lpwstrFullPath --*/ PAL_ERROR -CorUnix::CreateInitialProcessAndThreadObjects( +CorUnix::InitializeProcessCommandLine( CPalThread *pThread, LPWSTR lpwstrCmdLine, LPWSTR lpwstrFullPath - ) +) { PAL_ERROR palError = NO_ERROR; - HANDLE hThread; - IPalObject *pobjProcess = NULL; - IDataLock *pDataLock; - CProcProcessLocalData *pLocalData; - CProcSharedData *pSharedData; - CObjectAttributes oa; - HANDLE hProcess; LPWSTR initial_dir = NULL; // // Save the command line and initial directory // - g_lpwstrCmdLine = lpwstrCmdLine ? lpwstrCmdLine : (LPWSTR)W(""); - - if (lpwstrCmdLine) + if (lpwstrFullPath) { LPWSTR lpwstr = PAL_wcsrchr(lpwstrFullPath, '/'); lpwstr[0] = '\0'; @@ -2212,20 +2202,60 @@ CorUnix::CreateInitialProcessAndThreadObjects( if (NULL == initial_dir) { ERROR("malloc() failed! (initial_dir) \n"); - goto CreateInitialProcessAndThreadObjectsExit; + palError = ERROR_NOT_ENOUGH_MEMORY; + goto exit; } if (wcscpy_s(initial_dir, iLen, lpwstrFullPath) != SAFECRT_SUCCESS) { ERROR("wcscpy_s failed!\n"); + InternalFree(pThread, initial_dir); palError = ERROR_INTERNAL_ERROR; - goto CreateInitialProcessAndThreadObjectsExit; + goto exit; } lpwstr[0] = '/'; + + InternalFree(pThread, g_lpwstrAppDir); + g_lpwstrAppDir = initial_dir; } - - pAppDir = initial_dir; + + InternalFree(pThread, g_lpwstrCmdLine); + g_lpwstrCmdLine = lpwstrCmdLine; + +exit: + return palError; +} + + +/*++ +Function: + CreateInitialProcessAndThreadObjects + +Abstract + Creates the IPalObjects that represent the current process + and the initial thread + +Parameter + pThread - the initial thread + +Return + PAL_ERROR +--*/ + +PAL_ERROR +CorUnix::CreateInitialProcessAndThreadObjects( + CPalThread *pThread + ) +{ + PAL_ERROR palError = NO_ERROR; + HANDLE hThread; + IPalObject *pobjProcess = NULL; + IDataLock *pDataLock; + CProcProcessLocalData *pLocalData; + CProcSharedData *pSharedData; + CObjectAttributes oa; + HANDLE hProcess; // // Create initial thread object @@ -2329,14 +2359,6 @@ CreateInitialProcessAndThreadObjectsExit: pobjProcess->ReleaseReference(pThread); } - if (NO_ERROR != palError) - { - if (NULL != initial_dir) - { - InternalFree(pThread, initial_dir); - } - } - return palError; } @@ -2359,13 +2381,11 @@ VOID PROCCleanupInitialProcess(VOID) { CPalThread *pThread = InternalGetCurrentThread(); - LPWSTR lpwstr; InternalEnterCriticalSection(pThread, &g_csProcess); /* Free the application directory */ - lpwstr=pAppDir; - InternalFree (pThread, lpwstr); + InternalFree (pThread, g_lpwstrAppDir); /* Free the stored command line */ InternalFree (pThread, g_lpwstrCmdLine); @@ -3746,7 +3766,7 @@ getPath( } /* first look in directory from which the application loaded */ - lpwstr=pAppDir; + lpwstr = g_lpwstrAppDir; if (lpwstr) { |