diff --git a/src/coreclr/binder/bindertracing.cpp b/src/coreclr/binder/bindertracing.cpp index 2da85be540dda..90e010e23e76f 100644 --- a/src/coreclr/binder/bindertracing.cpp +++ b/src/coreclr/binder/bindertracing.cpp @@ -305,7 +305,9 @@ namespace BinderTracing case FUSION_E_REF_DEF_MISMATCH: result = Result::MismatchedAssemblyName; - errorMsg.Printf(W("Requested assembly name '%s' does not match found assembly name"), m_assemblyName.GetUnicode()); + errorMsg.Append(W("Requested assembly name '")); + errorMsg.Append(m_assemblyName.GetUnicode()); + errorMsg.Append(W("' does not match found assembly name")); if (resultAssembly != nullptr) { errorMsg.Append(W(" '")); @@ -325,7 +327,7 @@ namespace BinderTracing else { result = Result::Failure; - errorMsg.Printf(W("Resolution failed with HRESULT (%08x)"), m_hr); + errorMsg.Printf("Resolution failed with HRESULT (%08x)", m_hr); } } } diff --git a/src/coreclr/binder/textualidentityparser.cpp b/src/coreclr/binder/textualidentityparser.cpp index 64de57f4399e0..32482bf74ce34 100644 --- a/src/coreclr/binder/textualidentityparser.cpp +++ b/src/coreclr/binder/textualidentityparser.cpp @@ -112,7 +112,7 @@ namespace BINDER_SPACE if (AssemblyIdentity::Have(dwIdentityFlags, AssemblyIdentity::IDENTITY_FLAG_VERSION)) { tmpString.Clear(); - tmpString.Printf(W("%d.%d.%d.%d"), + tmpString.Printf("%d.%d.%d.%d", (DWORD)(USHORT)pAssemblyIdentity->m_version.GetMajor(), (DWORD)(USHORT)pAssemblyIdentity->m_version.GetMinor(), (DWORD)(USHORT)pAssemblyIdentity->m_version.GetBuild(), diff --git a/src/coreclr/debug/di/CMakeLists.txt b/src/coreclr/debug/di/CMakeLists.txt index f45a27ac7a9d5..9d84f90b1a5c6 100644 --- a/src/coreclr/debug/di/CMakeLists.txt +++ b/src/coreclr/debug/di/CMakeLists.txt @@ -17,7 +17,6 @@ set(CORDBDI_SOURCES dbgtransportmanager.cpp hash.cpp module.cpp - nativepipeline.cpp platformspecific.cpp process.cpp rsappdomain.cpp diff --git a/src/coreclr/debug/di/eventredirectionpipeline.cpp b/src/coreclr/debug/di/eventredirectionpipeline.cpp deleted file mode 100644 index b71b613939615..0000000000000 --- a/src/coreclr/debug/di/eventredirectionpipeline.cpp +++ /dev/null @@ -1,349 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// File: EventRedirectionPipeline.cpp -// - -// -// Implement a native pipeline that redirects events. -//***************************************************************************** - -#include "stdafx.h" -#include "nativepipeline.h" -#include "sstring.h" - -#if defined(ENABLE_EVENT_REDIRECTION_PIPELINE) -#include "eventredirection.h" -#include "eventredirectionpipeline.h" - - -// Constructor -EventRedirectionPipeline::EventRedirectionPipeline() -{ - m_pBlock = NULL; - m_dwProcessId = 0; - - InitConfiguration(); -} - -// Dtor -EventRedirectionPipeline::~EventRedirectionPipeline() -{ - CloseBlock(); -} - -// Call to free up the pipeline. -void EventRedirectionPipeline::Delete() -{ - delete this; -} - -//--------------------------------------------------------------------------------------- -// -// Returns true if the Redirection is enabled. -// -// Arguments: -// szOptions - specific Create/attach options to include in the overal format string -// pidTarget - pid of real debuggeee. -// -// Return Value: -// S_OK on success. -// -// -// Notes: -// This will spin up an auxiliary debugger (windbg) and attach it to the existing -// process. If this is a create case, then we're attaching to a create-suspended process. -// -//--------------------------------------------------------------------------------------- -void EventRedirectionPipeline::InitConfiguration() -{ - // We need some config strings. See header for possible values. - m_DebuggerCmd = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DbgRedirectApplication); - m_AttachParams = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DbgRedirectAttachCmd); - m_CreateParams = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DbgRedirectCreateCmd); - m_CommonParams = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DbgRedirectCommonCmd); -} - - -// Implement INativeEventPipeline::DebugSetProcessKillOnExit -BOOL EventRedirectionPipeline::DebugSetProcessKillOnExit(bool fKillOnExit) -{ - // Not implemented for redirection pipeline. That's ok. Redirection pipeline doesn't care. - // Return success so caller can assert for other pipeline types. - return TRUE; -} - -//--------------------------------------------------------------------------------------- -// -// Attach a real debugger to the target. -// -// Arguments: -// szOptions - specific Create/attach options to include in the overal format string -// pidTarget - pid of real debuggeee. -// -// Return Value: -// S_OK on success. -// -// -// Notes: -// This will spin up an auxiliary debugger (windbg) and attach it to the existing -// process. If this is a create case, then we're attaching to a create-suspended process. -// -//--------------------------------------------------------------------------------------- -HRESULT EventRedirectionPipeline::AttachDebuggerToTarget(LPCWSTR szOptions, DWORD pidTarget) -{ - SString s; - - BOOL fRemap = false; - - LPCWSTR lpApplicationName = NULL; - LPCWSTR lpCommandLine = NULL; - - EX_TRY - { - m_pBlock = new (nothrow) RedirectionBlock(); // $$ make throwing - - ZeroMemory(m_pBlock, sizeof(RedirectionBlock)); - - // Initialize - m_pBlock->m_versionCookie = EVENT_REDIRECTION_CURRENT_VERSION; - - s.Printf(m_CommonParams, GetCurrentProcessId(), m_pBlock, szOptions, pidTarget); - lpCommandLine = s.GetUnicode(); - - - lpApplicationName = m_DebuggerCmd; // eg, something like L"c:\\debuggers_amd64\\windbg.exe"; - - // Initialize events. - const BOOL kManualResetEvent = TRUE; - const BOOL kAutoResetEvent = FALSE; - - m_pBlock->m_hEventAvailable = WszCreateEvent(NULL, kAutoResetEvent, FALSE, NULL); - m_pBlock->m_hEventConsumed = WszCreateEvent(NULL, kAutoResetEvent, FALSE, NULL); - - m_pBlock->m_hDetachEvent = WszCreateEvent(NULL, kManualResetEvent, FALSE, NULL); - - fRemap = true; - }EX_CATCH {} - EX_END_CATCH(SwallowAllExceptions) - - if (!fRemap) - { - return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); - } - - STARTUPINFO startupInfo = {0}; - startupInfo.cb = sizeof (STARTUPINFOW); - - PROCESS_INFORMATION procInfo = {0}; - - // Now create the debugger - BOOL fStatus = WszCreateProcess( - lpApplicationName, - lpCommandLine, - NULL, - NULL, - FALSE, - 0, // flags - NULL, - NULL, - &startupInfo, - &procInfo); - - if (!fStatus) - { - return HRESULT_FROM_GetLastError(); - } - - CloseHandle(procInfo.hProcess); - CloseHandle(procInfo.hThread); - - return S_OK; - -} - -//--------------------------------------------------------------------------------------- -// -// Close the event block -// -// Notes: -// This can be called multiple times. -//--------------------------------------------------------------------------------------- -void EventRedirectionPipeline::CloseBlock() -{ - if (m_pBlock == NULL) - { - return; - } - - // Close our handle to the IPC events. When server closes its handles, OS will free the events. - - // Setting the detach event signals the Server that this block is closing. - if (m_pBlock->m_hDetachEvent != NULL) - { - SetEvent(m_pBlock->m_hDetachEvent); - CloseHandle(m_pBlock->m_hDetachEvent); - } - - if (m_pBlock->m_hEventAvailable != NULL) - { - CloseHandle(m_pBlock->m_hEventAvailable); - } - - if (m_pBlock->m_hEventConsumed != NULL) - { - CloseHandle(m_pBlock->m_hEventConsumed); - } - - delete m_pBlock; - m_pBlock = NULL; -} - - -// Wait for a debug event -BOOL EventRedirectionPipeline::WaitForDebugEvent(DEBUG_EVENT * pEvent, DWORD dwTimeout, CordbProcess * pProcess) -{ - // Get debug event via Redirection from control block - DWORD res = WaitForSingleObject(m_pBlock->m_hEventAvailable, dwTimeout); - if (res == WAIT_TIMEOUT) - { - // No event is available. - return FALSE; - } - - - pEvent->dwDebugEventCode = EXCEPTION_DEBUG_EVENT; - pEvent->dwProcessId = m_pBlock->m_dwProcessId; - pEvent->dwThreadId = m_pBlock->m_dwThreadId; - pEvent->u.Exception.dwFirstChance = m_pBlock->m_dwFirstChance; - - _ASSERTE(sizeof(m_pBlock->m_record) == sizeof(pEvent->u.Exception.ExceptionRecord)); - memcpy(&pEvent->u.Exception.ExceptionRecord, &m_pBlock->m_record, sizeof(m_pBlock->m_record)); - - // We've got an event! - return TRUE; -} - -// Continue a debug event -BOOL EventRedirectionPipeline::ContinueDebugEvent( - DWORD dwProcessId, - DWORD dwThreadId, - DWORD dwContinueStatus -) -{ - m_pBlock->m_ContinuationStatus = dwContinueStatus; - m_pBlock->m_counterConsumed++; - - // Sanity check the block. If these checks fail, then the block is corrupted (perhaps a issue in the - // extension dll feeding us the events?). - - - _ASSERTE(dwProcessId == m_pBlock->m_dwProcessId); - _ASSERTE(dwThreadId == m_pBlock->m_dwThreadId); - _ASSERTE(m_pBlock->m_counterAvailable == m_pBlock->m_counterConsumed); - - SetEvent(m_pBlock->m_hEventConsumed); - - return TRUE; -} - -// Create -HRESULT EventRedirectionPipeline::CreateProcessUnderDebugger( - MachineInfo machineInfo, - LPCWSTR lpApplicationName, - LPCWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) -{ - DWORD dwRealCreationFlags = dwCreationFlags; - dwRealCreationFlags |= CREATE_SUSPENDED; - dwRealCreationFlags &= ~(DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS); - - // We must create the real process so that startup info and process information are correct. - BOOL fStatus = WszCreateProcess( - lpApplicationName, - lpCommandLine, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwRealCreationFlags, - lpEnvironment, - lpCurrentDirectory, - lpStartupInfo, - lpProcessInformation); - if (!fStatus) - { - return HRESULT_FROM_GetLastError(); - } - - // Attach the real debugger. - AttachDebuggerToTarget(m_CreateParams, lpProcessInformation->dwProcessId); - - m_dwProcessId = lpProcessInformation->dwProcessId; - - return S_OK; -} - - -// Attach -HRESULT EventRedirectionPipeline::DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor) -{ - m_dwProcessId = processDescriptor.m_Pid; - - // Use redirected pipeline - // Spin up debugger to attach to target. - return AttachDebuggerToTarget(m_AttachParams, processDescriptor.m_Pid); -} - -// Detach -HRESULT EventRedirectionPipeline::DebugActiveProcessStop(DWORD processId) -{ - // Use redirected pipeline - SetEvent(m_pBlock->m_hDetachEvent); - CloseBlock(); - - // Assume detach can't fail (true on WinXP and above) - return S_OK; -} - -// Return a handle for the debuggee process. -HANDLE EventRedirectionPipeline::GetProcessHandle() -{ - _ASSERTE(m_dwProcessId != 0); - - return ::OpenProcess(PROCESS_DUP_HANDLE | - PROCESS_QUERY_INFORMATION | - PROCESS_TERMINATE | - PROCESS_VM_OPERATION | - PROCESS_VM_READ | - PROCESS_VM_WRITE | - SYNCHRONIZE, - FALSE, - m_dwProcessId); -} - -// Terminate the debuggee process. -BOOL EventRedirectionPipeline::TerminateProcess(UINT32 exitCode) -{ - _ASSERTE(m_dwProcessId != 0); - - // Get a process handle for the process ID. - HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, m_dwProcessId); - - if (hProc == NULL) - { - return FALSE; - } - - return ::TerminateProcess(hProc, exitCode); -} - -#endif // ENABLE_EVENT_REDIRECTION_PIPELINE - - diff --git a/src/coreclr/debug/di/eventredirectionpipeline.h b/src/coreclr/debug/di/eventredirectionpipeline.h deleted file mode 100644 index cb61d34d5b364..0000000000000 --- a/src/coreclr/debug/di/eventredirectionpipeline.h +++ /dev/null @@ -1,144 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// EventRedirectionPipeline.h -// - -// -// defines native pipeline abstraction for debug-support -// for event redirection. -//***************************************************************************** - -#ifndef _EVENTREDIRECTION_PIPELINE_ -#define _EVENTREDIRECTION_PIPELINE_ - -#include "nativepipeline.h" - -struct RedirectionBlock; -//----------------------------------------------------------------------------- -// For debugging purposes, helper class to allow native debug events to get -// redirected through StrikeRS debugger extension. Only 1 OS debugger can be -// attached to a process. This allows a debugger (such as Windbg) to attach directly -// to the Left-side (and thus be used to debug the left-side). ICorDebug then does a -// "virtual attach" through this pipeline. -// -// If this is a raw native attach, all calls go right through to the native pipeline. -//----------------------------------------------------------------------------- -class EventRedirectionPipeline : - public INativeEventPipeline -{ -public: - EventRedirectionPipeline(); - ~EventRedirectionPipeline(); - - // Returns null if redirection is not enabled, else returns a new redirection pipeline. - - // - // Implementation of INativeEventPipeline - // - - // Call to free up the pipeline. - virtual void Delete(); - - // Mark what to do with outstanding debuggees when event thread is killed. - virtual BOOL DebugSetProcessKillOnExit(bool fKillOnExit); - - // Create - virtual HRESULT CreateProcessUnderDebugger( - MachineInfo machineInfo, - LPCWSTR lpApplicationName, - LPCWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation); - - // Attach - virtual HRESULT DebugActiveProcess(MachineInfo machineInfo, const ProcessDescriptor& processDescriptor); - - // Detach - virtual HRESULT DebugActiveProcessStop(DWORD processId); - - // GEt a debug event - virtual BOOL WaitForDebugEvent(DEBUG_EVENT * pEvent, DWORD dwTimeout, CordbProcess * pProcess); - - // Continue a debug event received from WaitForDebugEvent - virtual BOOL ContinueDebugEvent( - DWORD dwProcessId, - DWORD dwThreadId, - DWORD dwContinueStatus - ); - - // Return a handle for the debuggee process. - virtual HANDLE GetProcessHandle(); - - // Terminate the debuggee process. - virtual BOOL TerminateProcess(UINT32 exitCode); - -protected: - - // - // Following us support for event-redirection. - // - - - // Rediretion block, or NULL if we're using the native pipeline. - RedirectionBlock * m_pBlock; - - // Initialize configuration values. - void InitConfiguration(); - - HRESULT AttachDebuggerToTarget(LPCWSTR szOptions, DWORD pid); - void CloseBlock(); - - // - // Configuration information to launch the debugger. - // These are retrieved via the standard Config helpers. - // - - // The debugger application to launch. eg: - // c:\debuggers_amd64\windbg.exe - CLRConfigStringHolder m_DebuggerCmd; - - // The common format string for the command line. - // This will get the following printf args: - // int (%d or %x): this process's pid (the ICD Client) - // pointer (%p): the address of the control block (m_pBlock). The launched debugger will - // then use this to communicate with this process. - // extra format string (%s): args specific for either launch or attach - // target debuggee (%d or %x): pid of the debuggee. - // eg (for windbg): - // -c ".load C:\vbl\ClrDbg\ndp\clr\src\Tools\strikeRS\objc\amd64\strikeRS.dll; !watch %x %p" %s -p %d - CLRConfigStringHolder m_CommonParams; - - // Command parameters for create case. - // Note that we must always physically call CreateProcess on the debuggee so that we get the proper out-parameters - // from create-process (eg, target's handle, startup info, etc). So we always attach the auxiliary debugger - // even in the create case. Use "-pr -pb" in Windbg to attach to a create-suspended process. - // - // Common Windbg options: - // -WX disable automatic workspace loading. This guarantees the newly created windbg has a clean - // environment and is not tainted with settings that will break the extension dll. - // -pr option will tell real Debugger to resume main thread. This goes with the CREATE_SUSPENDED flag we passed to CreateProcess. - // -pb option is required when attaching to newly created suspended process. It tells the debugger - // to not create the break-in thread (which it can't do on a pre-initialized process). - // eg: - // "-WX -pb -pr" - CLRConfigStringHolder m_CreateParams; - - // command parameters for attach. The WFDE server will send a loader breakpoint. - // eg: - // "-WX" - CLRConfigStringHolder m_AttachParams; - - DWORD m_dwProcessId; -}; - - - -#endif // _EVENTREDIRECTION_PIPELINE_ - diff --git a/src/coreclr/debug/di/nativepipeline.cpp b/src/coreclr/debug/di/nativepipeline.cpp deleted file mode 100644 index 4f801aa8f3442..0000000000000 --- a/src/coreclr/debug/di/nativepipeline.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// File: NativePipeline.cpp -// - -// -//***************************************************************************** - -#include "stdafx.h" -#include "nativepipeline.h" - -#if defined(ENABLE_EVENT_REDIRECTION_PIPELINE) -#include "eventredirection.h" -#include "eventredirectionpipeline.h" -#endif - -#include "sstring.h" - -//----------------------------------------------------------------------------- -// Returns null if redirection is not enabled, else returns a new redirection pipeline. -INativeEventPipeline * CreateEventRedirectionPipelineIfEnabled() -{ -#if !defined(ENABLE_EVENT_REDIRECTION_PIPELINE) - return NULL; -#else - - BOOL fEnabled = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_DbgRedirect) != 0; - if (!fEnabled) - { - return NULL; - } - - return new (nothrow) EventRedirectionPipeline(); -#endif -} - - -//----------------------------------------------------------------------------- -// Allocate and return a pipeline object for this platform -// Has debug checks (such as for event redirection) -// -// Returns: -// newly allocated pipeline object. Caller must call delete on it. -INativeEventPipeline * NewPipelineWithDebugChecks() -{ - CONTRACTL - { - NOTHROW; - } - CONTRACTL_END; - INativeEventPipeline * pRedirection = CreateEventRedirectionPipelineIfEnabled(); - if (pRedirection != NULL) - { - return pRedirection; - } - - return NewPipelineForThisPlatform(); -} - - - - diff --git a/src/coreclr/debug/di/nativepipeline.h b/src/coreclr/debug/di/nativepipeline.h index fc03b27772474..4cc9ae551bb98 100644 --- a/src/coreclr/debug/di/nativepipeline.h +++ b/src/coreclr/debug/di/nativepipeline.h @@ -5,8 +5,7 @@ // // -// defines native pipeline abstraction, which includes debug-support -// for event redirection. +// defines native pipeline abstraction //***************************************************************************** @@ -192,15 +191,5 @@ BOOL IsExceptionEvent(const DEBUG_EVENT * pEvent, BOOL * pfFirstChance, const EX // newly allocated pipeline object. Caller must call Dispose() on it. INativeEventPipeline * NewPipelineForThisPlatform(); -//----------------------------------------------------------------------------- -// Allocate and return a pipeline object for this platform -// Has debug checks (such as for event redirection) -// -// Returns: -// newly allocated pipeline object. Caller must call Dispose() on it. -INativeEventPipeline * NewPipelineWithDebugChecks(); - - - #endif // _NATIVE_PIPELINE_H diff --git a/src/coreclr/debug/di/platformspecific.cpp b/src/coreclr/debug/di/platformspecific.cpp index 2f70acf4d9c8b..2dbdbd2a40705 100644 --- a/src/coreclr/debug/di/platformspecific.cpp +++ b/src/coreclr/debug/di/platformspecific.cpp @@ -17,7 +17,6 @@ #include "remoteeventchannel.cpp" #elif WIN32 #include "windowspipeline.cpp" -#include "eventredirectionpipeline.cpp" #include "shimlocaldatatarget.cpp" #include "localeventchannel.cpp" #endif diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 465936b2febcb..51f3e6317bd92 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -10952,7 +10952,7 @@ HRESULT CordbWin32EventThread::Init() if (m_actionTakenEvent == NULL) return HRESULT_FROM_GetLastError(); - m_pNativePipeline = NewPipelineWithDebugChecks(); + m_pNativePipeline = NewPipelineForThisPlatform(); if (m_pNativePipeline == NULL) { return E_OUTOFMEMORY; diff --git a/src/coreclr/debug/di/stdafx.h b/src/coreclr/debug/di/stdafx.h index 7286870b969be..061c576c4725b 100644 --- a/src/coreclr/debug/di/stdafx.h +++ b/src/coreclr/debug/di/stdafx.h @@ -23,17 +23,6 @@ #define RSCONTRACTS #endif - -// In case of FEATURE_DBGIPC_TRANSPORT_DI we use pipe for debugger debugee communication -// and event redirection is not needed. (won't work anyway) -#ifndef FEATURE_DBGIPC_TRANSPORT_DI -// Currently, we only can redirect exception events. Since real interop-debugging -// neeeds all events, redirection can't work in real-interop. -// However, whether we're interop-debugging is determined at runtime, so we always -// enable at compile time and then we need a runtime check later. -#define ENABLE_EVENT_REDIRECTION_PIPELINE -#endif - #include "ex.h" #include "sigparser.h" diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 7b1f76f78a9f8..db5365bbe5142 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -6792,7 +6792,7 @@ bool Debugger::GetCompleteDebuggerLaunchString(SString * pStrArgsBuf) // format because changing HKLM keys requires admin priviledge. Padding with zeros is not a security mitigation, // but rather a forward looking compatibility measure. If future versions of Windows introduces more parameters for // JIT debugger launch, it is preferrable to pass zeros than other random values for those unsupported parameters. - pStrArgsBuf->Printf(ssDebuggerString, pid, GetUnmanagedAttachEvent(), GetDebuggerLaunchJitInfo(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + pStrArgsBuf->Printf(ssDebuggerString.GetUTF8(), pid, GetUnmanagedAttachEvent(), GetDebuggerLaunchJitInfo(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); return true; #else // !TARGET_UNIX @@ -8710,25 +8710,22 @@ int Debugger::NotifyUserOfFault(bool userBreakpoint, DebuggerLaunchSetting dls) tid = GetCurrentThreadId(); DWORD flags = 0; - UINT resIDMessage = 0; + CHAR const* msg; if (userBreakpoint) { - resIDMessage = IDS_DEBUG_USER_BREAKPOINT_MSG; + msg = "Application has encountered a user-defined breakpoint.\n\nProcess ID=0x%x (%d), Thread ID=0x%x (%d).\n\nClick ABORT to terminate the application.\nClick RETRY to debug the application.\nClick IGNORE to ignore the breakpoint."; flags |= MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION; } else { - resIDMessage = IDS_DEBUG_UNHANDLED_EXCEPTION_MSG; + msg = "Application has generated an exception that could not be handled.\n\nProcess ID=0x%x (%d), Thread ID=0x%x (%d).\n\nClick OK to terminate the application.\nClick CANCEL to debug the application."; flags |= MB_OKCANCEL | MB_ICONEXCLAMATION; } - SString text; - text.LoadResource(CCompRC::Error, resIDMessage); - // Format message string using optional parameters StackSString formattedMessage; - formattedMessage.Printf((LPWSTR)text.GetUnicode(), pid, pid, tid, tid); + formattedMessage.Printf(msg, pid, pid, tid, tid); { // Another potential hang. This may get run on the helper if we have a stack overflow. diff --git a/src/coreclr/debug/ee/debuggermessagebox.cpp b/src/coreclr/debug/ee/debuggermessagebox.cpp index 6ee2311974e04..7a7d601236dfa 100644 --- a/src/coreclr/debug/ee/debuggermessagebox.cpp +++ b/src/coreclr/debug/ee/debuggermessagebox.cpp @@ -113,7 +113,9 @@ static int UtilMessageBoxNonLocalized( #if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) #ifdef HOST_UNIX StackSString message; - message.Printf(W(".NET Runtime version : %s - "), CLR_PRODUCT_VERSION_L); + message.Append(W(".NET Runtime version : ")); + message.Append(CLR_PRODUCT_VERSION_L); + message.Append(W(" - ")); message.Append(lpTitle); message.Append(lpText); diff --git a/src/coreclr/debug/inc/eventredirection.h b/src/coreclr/debug/inc/eventredirection.h deleted file mode 100644 index 6a9cd63a0e89f..0000000000000 --- a/src/coreclr/debug/inc/eventredirection.h +++ /dev/null @@ -1,83 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** - -// -// NativePipeline.h -// -// define control block for redirecting events. -//***************************************************************************** - -#ifndef _EVENTREDIRECTION_H -#define _EVENTREDIRECTION_H - -//--------------------------------------------------------------------------------------- -// Control block for redirecting events. -// Motivation here is that only 1 process can be the real OS debugger. So if we want a windbg -// attached to an ICorDebug debuggee, then that windbg is the real debugger and it forwards events -// to the mdbg process. -// -// Terminology: -// Server: a windbg extension (StrikeRS) that is the real OS debugger, and it forwards native debug -// events (just exceptions currently) to the client -// Client: ICorDebug, which gets events via shimmed call to WaitForDebugEvent, etc. -// -// Control block lives in Client's process space. All handles are valid in client. -// Sever does Read/WriteProcessMemory -struct RedirectionBlock -{ - // Version of the control block. Initialized by client, verified by server. - // Latest value is EVENT_REDIRECTION_CURRENT_VERSION - DWORD m_versionCookie; - - // - // Counters. After each WFDE/CDE pair, these counters should be in sync. - // - - // increment after WFDE - DWORD m_counterAvailable; - DWORD m_counterConsumed; - - // - // Data for WaitForDebugEvent. (Server writes; Client reads) - // - DWORD m_dwProcessId; - DWORD m_dwThreadId; - - // Different sizes on different platforms - EXCEPTION_RECORD m_record; - BOOL m_dwFirstChance; - - // - // Data for ContinueDebugEvent. (Client writes, server reads) - // - - // Continuation status argument to ContinueDebugEvent - DWORD m_ContinuationStatus; - - - // - // Coordination events. These are handles in client space; server duplicates out. - // - - // Server signals when WFDE Data is ready. - HANDLE m_hEventAvailable; - - // Server signals when CDE data is ready. - HANDLE m_hEventConsumed; - - // Client signals before it deletes this block. This corresponds to client calling DebugActiveProcessStop. - // Thus server can check if signalled to know if accessing this block (which lives in client space) is safe. - // This is Synchronized because client only detaches if the debuggee is stopped, in which case the server - // isn't in the middle of sending an event. - HANDLE m_hDetachEvent; -}; - - -// Current version. -#define EVENT_REDIRECTION_CURRENT_VERSION ((DWORD) 4) - - - -#endif // _EVENTREDIRECTION_H - diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc index b4ba942e49095..e0978db48f5d8 100644 --- a/src/coreclr/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/dlls/mscorrc/mscorrc.rc @@ -403,8 +403,6 @@ BEGIN IDS_EE_CANNOTCAST "Unable to cast object of type '%1' to type '%2'." IDS_EE_CANNOTCASTSAME "[A]%1 cannot be cast to [B]%2. %3. %4." - IDS_EE_CANNOTCAST_HELPER_PATH "Type %s originates from '%s' in the context '%s' at location '%s'" - IDS_EE_CANNOTCAST_HELPER_BYTE "Type %s originates from '%s' in the context '%s' in a byte array" IDS_EE_INVALID_VT_FOR_CUSTOM_MARHALER "Type of the VARIANT specified for a parameter with a custom marshaler is not supported by the custom marshaler." IDS_EE_BAD_COMEXTENDS_CLASS "Types extending from COM objects should override all methods of an interface implemented by the base COM class." IDS_EE_INTERFACE_NOT_DISPATCH_BASED "The interface does not support late bound calls since it does not derive from IDispatch." @@ -548,20 +546,11 @@ BEGIN IDS_ER_STACK_OVERFLOW "Description: The process was terminated due to stack overflow." IDS_ER_STACK "Stack:" IDS_ER_WORDAT "at" - IDS_ER_UNMANAGEDFAILFASTMSG "at IP 0x%1 (0x%2) with exit code 0x%3." - IDS_ER_UNHANDLEDEXCEPTIONINFO "exception code %1, exception address %2" IDS_ER_MESSAGE_TRUNCATE "The remainder of the message was truncated." IDS_ER_CODECONTRACT_FAILED "Description: The application encountered a bug. A managed code contract (precondition, postcondition, object invariant, or assert) failed." IDS_ER_CODECONTRACT_DETAILMSG "Contract details: " END -STRINGTABLE DISCARDABLE -BEGIN - IDS_DEBUG_UNHANDLED_EXCEPTION_MSG "Application has generated an exception that could not be handled.\n\nProcess ID=0x%x (%d), Thread ID=0x%x (%d).\n\nClick OK to terminate the application.\nClick CANCEL to debug the application." - IDS_DEBUG_USER_BREAKPOINT_MSG "Application has encountered a user-defined breakpoint.\n\nProcess ID=0x%x (%d), Thread ID=0x%x (%d).\n\nClick ABORT to terminate the application.\nClick RETRY to debug the application.\nClick IGNORE to ignore the breakpoint." - -END - // Verifier error messages STRINGTABLE DISCARDABLE diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h index ce94e4db354ac..1903a00a7fac9 100644 --- a/src/coreclr/dlls/mscorrc/resource.h +++ b/src/coreclr/dlls/mscorrc/resource.h @@ -175,9 +175,6 @@ #define IDS_PERFORMANCEMON_PSAPINOTFOUND 0x17bd #define IDS_PERFORMANCEMON_PSAPINOTFOUND_TITLE 0x17be -#define IDS_DEBUG_UNHANDLED_EXCEPTION_MSG 0x17c0 -#define IDS_DEBUG_USER_BREAKPOINT_MSG 0x17c1 - #define IDS_INVALID_REDIM 0x17c3 #define IDS_INVALID_PINVOKE_CALLCONV 0x17c4 #define IDS_CLASSLOAD_NSTRUCT_EXPLICIT_OFFSET 0x17c7 @@ -478,8 +475,8 @@ #define IDS_ER_STACK_OVERFLOW 0x208a #define IDS_ER_STACK 0x208b #define IDS_ER_WORDAT 0x208c -#define IDS_ER_UNMANAGEDFAILFASTMSG 0x208d -#define IDS_ER_UNHANDLEDEXCEPTIONINFO 0x208e + + #define IDS_ER_MESSAGE_TRUNCATE 0x208f #define IDS_EE_OBJECT_TO_VARIANT_NOT_SUPPORTED 0x2090 @@ -488,8 +485,6 @@ #define IDS_EE_BADMARSHALFIELD_DECIMAL 0x2099 #define IDS_EE_CANNOTCASTSAME 0x209a -#define IDS_EE_CANNOTCAST_HELPER_BYTE 0x209b -#define IDS_EE_CANNOTCAST_HELPER_PATH 0x209c // For ForwardInteropStubAttribute #ifdef FEATURE_COMINTEROP diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index 55d4d7b015c33..77887aa43285c 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -188,11 +188,6 @@ CONFIG_DWORD_INFO(INTERNAL_DbgNoOpenMDByFile, W("DbgNoOpenMDByFile"), 0, "Allows CONFIG_DWORD_INFO(INTERNAL_DbgOOBinFEEE, W("DbgOOBinFEEE"), 0, "Allows forcing oob breakpoints when a fatal error occurs") CONFIG_DWORD_INFO(INTERNAL_DbgPingInterop, W("DbgPingInterop"), 0, "Allows checking for deadlocks in interop debugging") CONFIG_DWORD_INFO(INTERNAL_DbgRace, W("DbgRace"), 0, "Allows pausing for native debug events to get hijicked") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_DbgRedirect, W("DbgRedirect"), 0, "Allows for redirecting the event pipeline") -RETAIL_CONFIG_STRING_INFO(EXTERNAL_DbgRedirectApplication, W("DbgRedirectApplication"), "Specifies the auxiliary debugger application to launch.") -RETAIL_CONFIG_STRING_INFO(EXTERNAL_DbgRedirectAttachCmd, W("DbgRedirectAttachCmd"), "Specifies command parameters for attaching the auxiliary debugger.") -RETAIL_CONFIG_STRING_INFO(EXTERNAL_DbgRedirectCommonCmd, W("DbgRedirectCommonCmd"), "Specifies a command line format string for the auxiliary debugger.") -RETAIL_CONFIG_STRING_INFO(EXTERNAL_DbgRedirectCreateCmd, W("DbgRedirectCreateCmd"), "Specifies command parameters when creating the auxiliary debugger.") CONFIG_DWORD_INFO(INTERNAL_DbgShortcutCanary, W("DbgShortcutCanary"), 0, "Allows a way to force canary to fail to be able to test failure paths") CONFIG_DWORD_INFO(INTERNAL_DbgSkipMEOnStep, W("DbgSkipMEOnStep"), 0, "Turns off MethodEnter checks") CONFIG_DWORD_INFO(INTERNAL_DbgSkipVerCheck, W("DbgSkipVerCheck"), 0, "Allows different RS and LS versions (for servicing work)") diff --git a/src/coreclr/inc/sstring.h b/src/coreclr/inc/sstring.h index c76bcdc4b757d..66a08e7df1238 100644 --- a/src/coreclr/inc/sstring.h +++ b/src/coreclr/inc/sstring.h @@ -570,8 +570,6 @@ class EMPTY_BASES_DECL SString : private SBuffer void AppendPrintf(const CHAR *format, ...); void AppendVPrintf(const CHAR *format, va_list args); - void Printf(const WCHAR *format, ...); - public: BOOL LoadResource(CCompRC::ResourceCategory eCategory, int resourceID); HRESULT LoadResourceAndReturnHR(CCompRC::ResourceCategory eCategory, int resourceID); diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index ce1dfbbbd4bbc..3daf31f22edce 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -3466,6 +3466,14 @@ class ConfigMethodSet BYTE m_inited; }; +//***************************************************************************** +// Convert a GUID into a pointer to a string +//***************************************************************************** +int GuidToLPSTR( // Return status. + GUID Guid, // [IN] The GUID to convert. + _Out_writes_ (cchGuid) LPSTR szGuid, // [OUT] String into which the GUID is stored + DWORD cchGuid); // [IN] Size in chars of szGuid + //***************************************************************************** // Convert a pointer to a string into a GUID. //***************************************************************************** diff --git a/src/coreclr/utilcode/sstring.cpp b/src/coreclr/utilcode/sstring.cpp index 49f83e176448f..6219f9cb72bf0 100644 --- a/src/coreclr/utilcode/sstring.cpp +++ b/src/coreclr/utilcode/sstring.cpp @@ -1869,82 +1869,6 @@ void SString::VPrintf(const CHAR *format, va_list args) RETURN; } -void SString::Printf(const WCHAR *format, ...) -{ - CONTRACT_VOID - { - INSTANCE_CHECK; - PRECONDITION(CheckPointer(format)); - THROWS; - GC_NOTRIGGER; - } - CONTRACT_END; - - // sprintf gives us no means to know how many characters are written - // other than guessing and trying - - if (GetRawCount() > 0) - { - // First, try to use the existing buffer - va_list args; - va_start(args, format); - int result = _vsnwprintf_s(GetRawUnicode(), GetRawCount()+1, _TRUNCATE, format, args); - va_end(args); - - if (result >= 0) - { - // succeeded - Resize(result, REPRESENTATION_UNICODE, PRESERVE); - SString sss(format); - INDEBUG(CheckForFormatStringGlobalizationIssues(sss, *this)); - RETURN; - } - } - - // Make a guess how long the result will be (note this will be doubled) - - COUNT_T guess = (COUNT_T) wcslen(format)+1; - if (guess < GetRawCount()) - guess = GetRawCount(); - if (guess < MINIMUM_GUESS) - guess = MINIMUM_GUESS; - - while (TRUE) - { - // Double the previous guess - eventually we will get enough space - guess *= 2; - Resize(guess, REPRESENTATION_UNICODE); - - // Clear errno to avoid false alarms - errno = 0; - - va_list args; - va_start(args, format); - int result = _vsnwprintf_s(GetRawUnicode(), GetRawCount()+1, _TRUNCATE, format, args); - va_end(args); - - if (result >= 0) - { - Resize(result, REPRESENTATION_UNICODE, PRESERVE); - SString sss(format); - INDEBUG(CheckForFormatStringGlobalizationIssues(sss, *this)); - RETURN; - } - - if (errno==ENOMEM) - { - ThrowOutOfMemory(); - } - else - if (errno!=0 && errno!=EBADF && errno!=ERANGE) - { - CONSISTENCY_CHECK_MSG(FALSE, "_vsnwprintf_s failed. Potential globalization bug."); - ThrowHR(HRESULT_FROM_WIN32(ERROR_NO_UNICODE_TRANSLATION)); - } - } - RETURN; -} - void SString::AppendPrintf(const CHAR *format, ...) { WRAPPER_NO_CONTRACT; diff --git a/src/coreclr/utilcode/util_nodependencies.cpp b/src/coreclr/utilcode/util_nodependencies.cpp index dbb7706f6bf8e..93f3441934b49 100644 --- a/src/coreclr/utilcode/util_nodependencies.cpp +++ b/src/coreclr/utilcode/util_nodependencies.cpp @@ -434,6 +434,27 @@ HRESULT GetDebuggerSettingInfoWorker(_Out_writes_to_opt_(*pcchDebuggerString, *p #endif //!defined(FEATURE_UTILCODE_NO_DEPENDENCIES) || defined(_DEBUG) + +//***************************************************************************** +// Convert a GUID into a pointer to a string +//***************************************************************************** +int +GuidToLPSTR( + GUID guid, // The GUID to convert. + _Out_writes_(cchGuid) LPSTR szGuid, // String into which the GUID is stored + DWORD cchGuid) // Count in chars +{ + if (cchGuid < 39) + return 0; + + return sprintf_s(szGuid, cchGuid, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], + guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], + guid.Data4[6], guid.Data4[7]) + 1; +} + //***************************************************************************** // Convert hex value into a wide string of hex digits //***************************************************************************** diff --git a/src/coreclr/vm/assemblybinder.cpp b/src/coreclr/vm/assemblybinder.cpp index a710a82bc1eb5..13a3ca30d4a61 100644 --- a/src/coreclr/vm/assemblybinder.cpp +++ b/src/coreclr/vm/assemblybinder.cpp @@ -45,30 +45,28 @@ NativeImage* AssemblyBinder::LoadNativeImage(Module* componentModule, LPCUTF8 na static void MvidMismatchFatalError(GUID mvidActual, GUID mvidExpected, LPCUTF8 simpleName, bool compositeComponent, LPCUTF8 assemblyRequirementName) { static const size_t MVID_TEXT_LENGTH = 39; - WCHAR assemblyMvidText[MVID_TEXT_LENGTH]; - StringFromGUID2(mvidActual, assemblyMvidText, MVID_TEXT_LENGTH); + CHAR assemblyMvidText[MVID_TEXT_LENGTH]; + GuidToLPSTR(mvidActual, assemblyMvidText, MVID_TEXT_LENGTH); - WCHAR componentMvidText[MVID_TEXT_LENGTH]; - StringFromGUID2(mvidExpected, componentMvidText, MVID_TEXT_LENGTH); + CHAR componentMvidText[MVID_TEXT_LENGTH]; + GuidToLPSTR(mvidExpected, componentMvidText, MVID_TEXT_LENGTH); SString message; if (compositeComponent) { - message.Printf(W("MVID mismatch between loaded assembly '%s' (MVID = %s) and an assembly with the same simple name embedded in the native image '%s' (MVID = %s)"), - SString(SString::Utf8, simpleName).GetUnicode(), + message.Printf("MVID mismatch between loaded assembly '%s' (MVID = %s) and an assembly with the same simple name embedded in the native image '%s' (MVID = %s)", + simpleName, assemblyMvidText, - SString(SString::Utf8, assemblyRequirementName).GetUnicode(), + assemblyRequirementName, componentMvidText); } else { - SString simpleNameUtf8(SString::Utf8, simpleName); - - message.Printf(W("MVID mismatch between loaded assembly '%s' (MVID = %s) and version of assembly '%s' expected by assembly '%s' (MVID = %s)"), - simpleNameUtf8.GetUnicode(), + message.Printf("MVID mismatch between loaded assembly '%s' (MVID = %s) and version of assembly '%s' expected by assembly '%s' (MVID = %s)", + simpleName, assemblyMvidText, - simpleNameUtf8.GetUnicode(), - SString(SString::Utf8, assemblyRequirementName).GetUnicode(), + simpleName, + assemblyRequirementName, componentMvidText); } diff --git a/src/coreclr/vm/clrex.cpp b/src/coreclr/vm/clrex.cpp index 976e45e1fecba..645687b28f5c6 100644 --- a/src/coreclr/vm/clrex.cpp +++ b/src/coreclr/vm/clrex.cpp @@ -1954,7 +1954,12 @@ OBJECTREF EECOMException::CreateThrowable() { // We have a non 0 help context so use it to form the help link. SString strMessage; - strMessage.Printf(W("%s#%d"), m_ED.bstrHelpFile, m_ED.dwHelpContext); + strMessage.Append(m_ED.bstrHelpFile); + + // Add the help context + WCHAR cxt[ARRAY_SIZE("#") + MaxSigned32BitDecString] = W("#"); + FormatInteger(cxt + 1, ARRAY_SIZE(cxt) - 1, "%d", m_ED.dwHelpContext); + strMessage.Append(cxt); helpStr = StringObject::NewString(strMessage); } else diff --git a/src/coreclr/vm/dllimportcallback.cpp b/src/coreclr/vm/dllimportcallback.cpp index 65d2afd7d0512..8296fd22111fe 100644 --- a/src/coreclr/vm/dllimportcallback.cpp +++ b/src/coreclr/vm/dllimportcallback.cpp @@ -305,17 +305,13 @@ VOID __fastcall UMEntryThunk::ReportViolation(UMEntryThunk* pEntryThunk) SString namespaceOrClassName; SString methodName; - SString moduleName; - pMethodDesc->GetMethodInfoNoSig(namespaceOrClassName, methodName); - moduleName.SetUTF8(pMethodDesc->GetModule()->GetSimpleName()); SString message; - - message.Printf(W("A callback was made on a garbage collected delegate of type '%s!%s::%s'."), - moduleName.GetUnicode(), - namespaceOrClassName.GetUnicode(), - methodName.GetUnicode()); + message.Printf("A callback was made on a garbage collected delegate of type '%s!%s::%s'.", + pMethodDesc->GetModule()->GetSimpleName(), + namespaceOrClassName.GetUTF8(), + methodName.GetUTF8()); EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_FAILFAST, message.GetUnicode()); } diff --git a/src/coreclr/vm/eepolicy.cpp b/src/coreclr/vm/eepolicy.cpp index 25b787e381c2c..35671c4f2ef03 100644 --- a/src/coreclr/vm/eepolicy.cpp +++ b/src/coreclr/vm/eepolicy.cpp @@ -467,13 +467,8 @@ void EEPolicy::LogFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage } else { - // Fetch the localized Fatal Execution Engine Error text or fall back on a hardcoded variant if things get dire. - InlineSString<80> ssMessage; - InlineSString<80> ssErrorFormat; - if(!ssErrorFormat.LoadResource(CCompRC::Optional, IDS_ER_UNMANAGEDFAILFASTMSG )) - ssErrorFormat.Set(W("at IP 0x%1 (0x%2) with exit code 0x%3.")); - SmallStackSString addressString; - addressString.Printf(W("%p"), pExceptionInfo? (PVOID)pExceptionInfo->ExceptionRecord->ExceptionAddress : (PVOID)address); + WCHAR addressString[MaxIntegerDecHexString + 1]; + FormatInteger(addressString, ARRAY_SIZE(addressString), "%p", pExceptionInfo ? (SIZE_T)pExceptionInfo->ExceptionRecord->ExceptionAddress : (SIZE_T)address); // We should always have the reference to the runtime's instance _ASSERTE(GetClrModuleBase() != NULL); @@ -481,14 +476,15 @@ void EEPolicy::LogFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage // Setup the string to contain the runtime's base address. Thus, when customers report FEEE with just // the event log entry containing this string, we can use the absolute and base addresses to determine // where the fault happened inside the runtime. - SmallStackSString runtimeBaseAddressString; - runtimeBaseAddressString.Printf(W("%p"), GetClrModuleBase()); + WCHAR runtimeBaseAddressString[MaxIntegerDecHexString + 1]; + FormatInteger(runtimeBaseAddressString, ARRAY_SIZE(runtimeBaseAddressString), "%p", (SIZE_T)GetClrModuleBase()); - SmallStackSString exitCodeString; - exitCodeString.Printf(W("%x"), exitCode); + WCHAR exitCodeString[MaxIntegerDecHexString + 1]; + FormatInteger(exitCodeString, ARRAY_SIZE(exitCodeString), "%x", exitCode); // Format the string - ssMessage.FormatMessage(FORMAT_MESSAGE_FROM_STRING, (LPCWSTR)ssErrorFormat, 0, 0, addressString, runtimeBaseAddressString, + InlineSString<80> ssMessage; + ssMessage.FormatMessage(FORMAT_MESSAGE_FROM_STRING, W("at IP 0x%1 (0x%2) with exit code 0x%3."), 0, 0, addressString, runtimeBaseAddressString, exitCodeString); reporter.AddDescription(ssMessage); } diff --git a/src/coreclr/vm/encee.cpp b/src/coreclr/vm/encee.cpp index 44e2a3512c398..b959e233a14a2 100644 --- a/src/coreclr/vm/encee.cpp +++ b/src/coreclr/vm/encee.cpp @@ -136,13 +136,13 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue( if (dumpChanges> 0) { SString fn; int ec; - fn.Printf(W("ApplyChanges.%d.dmeta"), m_applyChangesCount); + fn.Printf("ApplyChanges.%d.dmeta", m_applyChangesCount); FILE *fp; ec = _wfopen_s(&fp, fn.GetUnicode(), W("wb")); _ASSERTE(SUCCEEDED(ec)); fwrite(pDeltaMD, 1, cbDeltaMD, fp); fclose(fp); - fn.Printf(W("ApplyChanges.%d.dil"), m_applyChangesCount); + fn.Printf("ApplyChanges.%d.dil", m_applyChangesCount); ec = _wfopen_s(&fp, fn.GetUnicode(), W("wb")); _ASSERTE(SUCCEEDED(ec)); fwrite(pDeltaIL, 1, cbDeltaIL, fp); diff --git a/src/coreclr/vm/eventreporter.cpp b/src/coreclr/vm/eventreporter.cpp index c2a84369edfe3..1427c96cca41d 100644 --- a/src/coreclr/vm/eventreporter.cpp +++ b/src/coreclr/vm/eventreporter.cpp @@ -672,22 +672,21 @@ void DoReportForUnhandledNativeException(PEXCEPTION_POINTERS pExceptionInfo) EventReporter reporter(EventReporter::ERT_UnhandledException); EX_TRY { + WCHAR exceptionCodeString[MaxIntegerDecHexString + 1]; + FormatInteger(exceptionCodeString, ARRAY_SIZE(exceptionCodeString), "%x", pExceptionInfo->ExceptionRecord->ExceptionCode); + + WCHAR addressString[MaxIntegerDecHexString + 1]; + FormatInteger(addressString, ARRAY_SIZE(addressString), "%p", (SIZE_T)pExceptionInfo->ExceptionRecord->ExceptionAddress); + StackSString s; - InlineSString<80> ssErrorFormat; - if (!ssErrorFormat.LoadResource(CCompRC::Optional, IDS_ER_UNHANDLEDEXCEPTIONINFO)) - ssErrorFormat.Set(W("exception code %1, exception address %2")); - SmallStackSString exceptionCodeString; - exceptionCodeString.Printf(W("%x"), pExceptionInfo->ExceptionRecord->ExceptionCode); - SmallStackSString addressString; - addressString.Printf(W("%p"), (PVOID)pExceptionInfo->ExceptionRecord->ExceptionAddress); - s.FormatMessage(FORMAT_MESSAGE_FROM_STRING, (LPCWSTR)ssErrorFormat, 0, 0, exceptionCodeString, addressString); - reporter.AddDescription(s); - if (pThread) - { - LogCallstackForEventReporter(reporter); - } + s.FormatMessage(FORMAT_MESSAGE_FROM_STRING, W("exception code %1, exception address %2"), 0, 0, exceptionCodeString, addressString); + reporter.AddDescription(s); + if (pThread) + { + LogCallstackForEventReporter(reporter); + } } - EX_CATCH + EX_CATCH { // We are reporting an exception. If we throw while working on this, it is not fatal. } diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index f45288afd54c6..9f28ad781150e 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -11635,30 +11635,27 @@ VOID GetAssemblyDetailInfo(SString &sType, { WRAPPER_NO_CONTRACT; - StackSString sFormat; - StackSString sAlcName; + SString detailsUtf8; + SString sAlcName; pPEAssembly->GetAssemblyBinder()->GetNameForDiagnostics(sAlcName); - if (pPEAssembly->GetPath().IsEmpty()) { - sFormat.LoadResource(CCompRC::Debugging, IDS_EE_CANNOTCAST_HELPER_BYTE); - - sAssemblyDetailInfo.Printf(sFormat.GetUnicode(), - sType.GetUnicode(), - sAssemblyDisplayName.GetUnicode(), - sAlcName.GetUnicode()); + detailsUtf8.Printf("Type %s originates from '%s' in the context '%s' in a byte array", + sType.GetUTF8(), + sAssemblyDisplayName.GetUTF8(), + sAlcName.GetUTF8()); } else { - sFormat.LoadResource(CCompRC::Debugging, IDS_EE_CANNOTCAST_HELPER_PATH); - - sAssemblyDetailInfo.Printf(sFormat.GetUnicode(), - sType.GetUnicode(), - sAssemblyDisplayName.GetUnicode(), - sAlcName.GetUnicode(), - pPEAssembly->GetPath().GetUnicode()); + detailsUtf8.Printf("Type %s originates from '%s' in the context '%s' at location '%s'", + sType.GetUTF8(), + sAssemblyDisplayName.GetUTF8(), + sAlcName.GetUTF8(), + pPEAssembly->GetPath().GetUTF8()); } + + sAssemblyDetailInfo.Append(detailsUtf8.GetUnicode()); } VOID CheckAndThrowSameTypeAndAssemblyInvalidCastException(TypeHandle thCastFrom, diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index ef511c1814fe0..d1fc8b3734596 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -10589,9 +10589,9 @@ int CEEInfo::doAssert(const char* szFile, int iLine, const char* szExpr) { SString output; output.Printf( - W("JIT assert failed:\n") - W("%hs\n") - W(" File: %hs Line: %d\n"), + "JIT assert failed:\n" + "%s\n" + " File: %s Line: %d\n", szExpr, szFile, iLine); COMPlusThrowNonLocalized(kInvalidProgramException, output.GetUnicode()); } @@ -13707,16 +13707,14 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, else { // Verification failures are failfast events - DefineFullyQualifiedNameForClassW(); + DefineFullyQualifiedNameForClass(); SString fatalErrorString; - fatalErrorString.Printf(W("Verify_TypeLayout '%s' failed to verify type layout"), - GetFullyQualifiedNameForClassW(pMT)); + fatalErrorString.Printf("Verify_TypeLayout '%s' failed to verify type layout", + GetFullyQualifiedNameForClass(pMT)); #ifdef _DEBUG { - StackSString buf; - buf.SetAndConvertToUTF8(fatalErrorString.GetUnicode()); - _ASSERTE_MSG(false, buf.GetUTF8()); + _ASSERTE_MSG(false, fatalErrorString.GetUTF8()); // Run through the type layout logic again, after the assert, makes debugging easy TypeLayoutCheck(pMT, pBlob, /* printDiff */ TRUE); } @@ -13781,25 +13779,17 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, if ((fieldOffset != actualFieldOffset) || (baseOffset != actualBaseOffset)) { // Verification failures are failfast events - DefineFullyQualifiedNameForClassW(); - SString ssFieldName(SString::Utf8, pField->GetName()); + DefineFullyQualifiedNameForClass(); SString fatalErrorString; - fatalErrorString.Printf(W("Verify_FieldOffset '%s.%s' Field offset %d!=%d(actual) || baseOffset %d!=%d(actual)"), - GetFullyQualifiedNameForClassW(pEnclosingMT), - ssFieldName.GetUnicode(), + fatalErrorString.Printf("Verify_FieldOffset '%s.%s' Field offset %d!=%d(actual) || baseOffset %d!=%d(actual)", + GetFullyQualifiedNameForClass(pEnclosingMT), + pField->GetName(), fieldOffset, actualFieldOffset, baseOffset, actualBaseOffset); - -#ifdef _DEBUG - { - StackSString buf; - buf.SetAndConvertToUTF8(fatalErrorString.GetUnicode()); - _ASSERTE_MSG(false, buf.GetUTF8()); - } -#endif + _ASSERTE_MSG(false, fatalErrorString.GetUTF8()); EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(-1, fatalErrorString.GetUnicode()); return FALSE; @@ -13889,7 +13879,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, else { // Verification failures are failfast events - DefineFullyQualifiedNameForClassW(); + DefineFullyQualifiedNameForClass(); SString methodNameDecl; SString methodNameImplRuntime(W("(NULL)")); SString methodNameImplCompiler(W("(NULL)")); @@ -13909,19 +13899,13 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, } SString fatalErrorString; - fatalErrorString.Printf(W("Verify_VirtualFunctionOverride Decl Method '%s' on type '%s' is '%s'(actual) instead of expected '%s'(from compiler)"), - methodNameDecl.GetUnicode(), - GetFullyQualifiedNameForClassW(thImpl.GetMethodTable()), - methodNameImplRuntime.GetUnicode(), - methodNameImplCompiler.GetUnicode()); + fatalErrorString.Printf("Verify_VirtualFunctionOverride Decl Method '%s' on type '%s' is '%s'(actual) instead of expected '%s'(from compiler)", + methodNameDecl.GetUTF8(), + GetFullyQualifiedNameForClass(thImpl.GetMethodTable()), + methodNameImplRuntime.GetUTF8(), + methodNameImplCompiler.GetUTF8()); -#ifdef _DEBUG - { - StackSString buf; - buf.SetAndConvertToUTF8(fatalErrorString.GetUnicode()); - _ASSERTE_MSG(false, buf.GetUTF8()); - } -#endif + _ASSERTE_MSG(false, fatalErrorString.GetUTF8()); _ASSERTE(!IsDebuggerPresent() && "Stop on assert here instead of fatal error for ease of live debugging"); EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(-1, fatalErrorString.GetUnicode()); @@ -14047,7 +14031,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, } else { - DefineFullyQualifiedNameForClassW(); + DefineFullyQualifiedNameForClass(); SString methodName; pMDCompare->GetFullMethodInfo(methodName); void* compileTimeTypes = types.OpenRawBuffer(); @@ -14059,21 +14043,16 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, void* runtimeTypeData = pMethodMetadata != NULL ? (void*)pMethodMetadata->pTypes : (void*)NULL; SString fatalErrorString; - fatalErrorString.Printf(W("VERIFY_IL_BODY Method '%s' type '%s' does not match IL body expected DEBUGINFO MethodData {%d} {%p} RuntimeMethodData {%d} {%p} Types {%d} {%p} RuntimeTypes {%d} {%p}"), - methodName.GetUnicode(), - GetFullyQualifiedNameForClassW(pMDCompare->GetMethodTable()), + fatalErrorString.Printf("VERIFY_IL_BODY Method '%s' type '%s' does not match IL body expected DEBUGINFO MethodData {%d} {%p} RuntimeMethodData {%d} {%p} Types {%d} {%p} RuntimeTypes {%d} {%p}", + methodName.GetUTF8(), + GetFullyQualifiedNameForClass(pMDCompare->GetMethodTable()), (int)dwBlobSize, pBlobStart, runtimeMethodDataSize, runtimeMethodData, (int)cTypes, compileTimeTypes, runtimeTypeCount, runtimeTypeData ); -#ifdef _DEBUG - { - StackSString buf; - buf.SetAndConvertToUTF8(fatalErrorString.GetUnicode()); - _ASSERTE_MSG(false, buf.GetUTF8()); } -#endif + _ASSERTE_MSG(false, fatalErrorString.GetUTF8()); _ASSERTE(!IsDebuggerPresent() && "Stop on assert here instead of fatal error for ease of live debugging"); EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(-1, fatalErrorString.GetUnicode()); diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 12fc856c1d9bc..a0080a6747534 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -662,7 +662,7 @@ VOID ThrowInteropParamException(UINT resID, UINT paramIdx) if (paramIdx == 0) paramString.Set(W("return value")); else - paramString.Printf(W("parameter #%u"), paramIdx); + paramString.Printf("parameter #%u", paramIdx); SString errorString(W("Unknown error.")); errorString.LoadResource(CCompRC::Error, resID); diff --git a/src/coreclr/vm/nativelibrary.cpp b/src/coreclr/vm/nativelibrary.cpp index 3b1299986da3b..456a239211a86 100644 --- a/src/coreclr/vm/nativelibrary.cpp +++ b/src/coreclr/vm/nativelibrary.cpp @@ -515,15 +515,24 @@ namespace return hmod; } + // Enumerations for constructing lib name variations for probing + enum NameVariations + { + NameVariations_None = 0, + NameVariations_Prefix = 1, + NameVariations_Name = 2, + NameVariations_Suffix = 4, + }; + #ifdef TARGET_UNIX const int MaxVariationCount = 4; - void DetermineLibNameVariations(const WCHAR** libNameVariations, int* numberOfVariations, const SString& libName, bool libNameIsRelativePath) + void DetermineLibNameVariations(NameVariations* libNameVariations, int* numberOfVariations, const SString& libName, bool libNameIsRelativePath) { // Supported lib name variations - static auto NameFmt = W("%.0s%s%.0s"); - static auto PrefixNameFmt = W("%s%s%.0s"); - static auto NameSuffixFmt = W("%.0s%s%s"); - static auto PrefixNameSuffixFmt = W("%s%s%s"); + static auto NameFmt = (NameVariations)NameVariations_Name; + static auto PrefixNameFmt = (NameVariations)(NameVariations_Prefix | NameVariations_Name); + static auto NameSuffixFmt = (NameVariations)(NameVariations_Name | NameVariations_Suffix); + static auto PrefixNameSuffixFmt = (NameVariations)(NameVariations_Prefix | NameVariations_Name | NameVariations_Suffix); _ASSERTE(*numberOfVariations >= MaxVariationCount); @@ -578,11 +587,11 @@ namespace } #else // TARGET_UNIX const int MaxVariationCount = 2; - void DetermineLibNameVariations(const WCHAR** libNameVariations, int* numberOfVariations, const SString& libName, bool libNameIsRelativePath) + void DetermineLibNameVariations(NameVariations* libNameVariations, int* numberOfVariations, const SString& libName, bool libNameIsRelativePath) { // Supported lib name variations - static auto NameFmt = W("%.0s%s%.0s"); - static auto NameSuffixFmt = W("%.0s%s%s"); + static auto NameFmt = (NameVariations)NameVariations_Name; + static auto NameSuffixFmt = (NameVariations)(NameVariations_Name | NameVariations_Suffix); _ASSERTE(*numberOfVariations >= MaxVariationCount); @@ -654,13 +663,22 @@ namespace // even if it has one, or to leave off a prefix like "lib" even if it has one // (both of these are typically done to smooth over cross-platform differences). // We try to dlopen with such variations on the original. - const WCHAR* prefixSuffixCombinations[MaxVariationCount] = {}; + NameVariations prefixSuffixCombinations[MaxVariationCount] = {}; int numberOfVariations = ARRAY_SIZE(prefixSuffixCombinations); DetermineLibNameVariations(prefixSuffixCombinations, &numberOfVariations, wszLibName, libNameIsRelativePath); for (int i = 0; i < numberOfVariations; i++) { SString currLibNameVariation; - currLibNameVariation.Printf(prefixSuffixCombinations[i], PLATFORM_SHARED_LIB_PREFIX_W, wszLibName, PLATFORM_SHARED_LIB_SUFFIX_W); + + NameVariations const variations = prefixSuffixCombinations[i]; + if ((variations & NameVariations_Prefix) != 0) + currLibNameVariation.Append(PLATFORM_SHARED_LIB_PREFIX_W); + + _ASSERTE((variations & NameVariations_Name) != 0); + currLibNameVariation.Append(wszLibName); + + if ((variations & NameVariations_Suffix) != 0) + currLibNameVariation.Append(PLATFORM_SHARED_LIB_SUFFIX_W); // NATIVE_DLL_SEARCH_DIRECTORIES set by host is considered well known path hmod = LoadFromNativeDllSearchDirectories(currLibNameVariation, loadWithAlteredPathFlags, pErrorTracker); diff --git a/src/coreclr/vm/readytoruninfo.cpp b/src/coreclr/vm/readytoruninfo.cpp index 0abafc160adeb..46a964de2b69c 100644 --- a/src/coreclr/vm/readytoruninfo.cpp +++ b/src/coreclr/vm/readytoruninfo.cpp @@ -400,7 +400,12 @@ static void LogR2r(const char *msg, PEAssembly *pPEAssembly) { // Append process ID to the log file name, so multiple processes can log at the same time. StackSString fullname; - fullname.Printf(W("%s.%u"), wszReadyToRunLogFile.GetValue(), GetCurrentProcessId()); + fullname.Append(wszReadyToRunLogFile.GetValue()); + + WCHAR pidSuffix[ARRAY_SIZE(".") + MaxUnsigned32BitDecString] = W("."); + DWORD pid = GetCurrentProcessId(); + FormatInteger(pidSuffix + 1, ARRAY_SIZE(pidSuffix) - 1, "%u", pid); + fullname.Append(pidSuffix); r2rLogFile = _wfopen(fullname.GetUnicode(), W("w")); } else @@ -1717,7 +1722,7 @@ class NativeManifestModule : public ModuleBase if (assemblyNameLen != 0) // #: is a direct reference to a module index, #: is indirect { mdToken assemblyRef; - + IfFailThrow(GetAssemblyRefTokenOfIndirectDependency(module, assemblyNameInModuleRef, assemblyNameLen, &assemblyRef)); if (assemblyRef == mdTokenNil) { diff --git a/src/coreclr/vm/typedesc.cpp b/src/coreclr/vm/typedesc.cpp index f613addf1418c..77035a2d761b7 100644 --- a/src/coreclr/vm/typedesc.cpp +++ b/src/coreclr/vm/typedesc.cpp @@ -221,14 +221,20 @@ void TypeDesc::ConstructName(CorElementType kind, case ELEMENT_TYPE_VAR: case ELEMENT_TYPE_MVAR: + { if (kind == ELEMENT_TYPE_VAR) { - ssBuff.Printf(W("!%d"), rank); + ssBuff.Append(W('!')); } else { - ssBuff.Printf(W("!!%d"), rank); + ssBuff.Append(W("!!")); } + + WCHAR buffer[MaxSigned32BitDecString + 1]; + FormatInteger(buffer, ARRAY_SIZE(buffer), "%d", rank); + ssBuff.Append(buffer); + } break; case ELEMENT_TYPE_FNPTR: