Fix Windows 32bit related issues.
authorMikhail Kurinnoi <m.kurinnoi@samsung.com>
Wed, 18 May 2022 14:57:07 +0000 (17:57 +0300)
committerAlexander Soldatov/Platform Lab /SRR/Staff Engineer/Samsung Electronics <soldatov.a@samsung.com>
Mon, 23 May 2022 16:15:06 +0000 (19:15 +0300)
15 files changed:
fetchdeps.cmake
src/debugger/frames.cpp
src/debugger/manageddebugger.cpp
src/main.cpp
src/managed/SymbolReader.cs
src/managed/interop.cpp
src/managed/interop.h
src/metadata/modules.cpp
src/protocols/vscodeprotocol.cpp
src/utils/iosystem.h
src/utils/iosystem_win32.cpp
src/utils/streams.cpp
test-suite/MITestException/Program.cs
third_party/linenoise-ng/src/linenoise.cpp
third_party/linenoise-ng/tst/example.c

index 14198d9a748c6ee24d305e231786ca27da06e4d8..8ca6b7fe125e11d9447d4c2b00b4551d5f590822 100644 (file)
@@ -47,8 +47,13 @@ if ("${DOTNET_DIR}" STREQUAL "" AND (("${DBGSHIM_RUNTIME_DIR}" STREQUAL "") OR $
         if (NOT "${retcode}" STREQUAL "0")
             message(FATAL_ERROR "Fatal error when downloading dotnet install script")
         endif()
+        if (CLR_CMAKE_PLATFORM_ARCH_I386)
+            set(NETSDKARCH "x86")
+        elseif()
+            set(NETSDKARCH "x64")
+        endif()
         execute_process(
-            COMMAND powershell -File "${CMAKE_CURRENT_BINARY_DIR}/dotnet-install.ps1" -Channel "${DOTNET_CHANNEL}" -InstallDir "${DOTNET_DIR}" -Architecture x64 -Verbose
+            COMMAND powershell -File "${CMAKE_CURRENT_BINARY_DIR}/dotnet-install.ps1" -Channel "${DOTNET_CHANNEL}" -InstallDir "${DOTNET_DIR}" -Architecture ${NETSDKARCH} -Verbose
             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
             RESULT_VARIABLE retcode)
         if (NOT "${retcode}" STREQUAL "0")
index 1b8dc97d7a549b1b4d495f734ac58315b930aae2..744f4e735775b334778a9992120d1d7b79684de5 100644 (file)
@@ -32,7 +32,7 @@ static uint64_t GetSP(CONTEXT *context)
     return (uint64_t)(size_t)context->Sp;
 #elif defined(_TARGET_ARM64_)
     return (uint64_t)(size_t)context->Sp;
-#elif
+#else
 #error "Unsupported platform"
 #endif
 }
index 0830fce9a363f717897c7d182bcd5fc3c05878f9..5e86bd61a5a584c22461c342f6a559e9f36fb232 100644 (file)
@@ -1269,12 +1269,16 @@ static HRESULT ApplyMetadataAndILDeltas(Modules *pModules, const std::string &dl
     if (deltaILFileStream.is_open() && deltaMDFileStream.is_open())
     {
         auto deltaILSize = deltaILFileStream.tellg();
-        BYTE *deltaILMemBlock = new BYTE[deltaILSize];
+        if (deltaILSize < 0)
+            return E_FAIL;
+        BYTE *deltaILMemBlock = new BYTE[(size_t)deltaILSize];
         deltaILFileStream.seekg(0, std::ios::beg);
         deltaILFileStream.read((char*)deltaILMemBlock, deltaILSize);
 
         auto deltaMDSize = deltaMDFileStream.tellg();
-        BYTE *deltaMDMemBlock = new BYTE[deltaMDSize];
+        if (deltaMDSize < 0)
+            return E_FAIL;
+        BYTE *deltaMDMemBlock = new BYTE[(size_t)deltaMDSize];
         deltaMDFileStream.seekg(0, std::ios::beg);
         deltaMDFileStream.read((char*)deltaMDMemBlock, deltaMDSize);
 
index 502977e17e543206dba6f182824dfca832309fc1..31ec999abe82d7014af6bf85f7f88567bac6a6cd 100644 (file)
@@ -224,7 +224,11 @@ static HRESULT LaunchNewProcess(IDebugger *pDebugger, std::string &execFile, std
     return pDebugger->ConfigurationDone();
 }
 
-int main(int argc, char* argv[])
+int
+#if defined(WIN32) && defined(_TARGET_X86_)
+    __cdecl
+#endif
+            main(int argc, char* argv[])
 {
 
     DWORD pidDebuggee = 0;
index 8c962b73e9aada95dacfb9dc3d35dbbba12cccf3..6bfdc7e2e1ea786836ad817ab0926deadc75d00b 100644 (file)
@@ -512,7 +512,7 @@ namespace NetCoreDbg
         /// <param name="normalTokens">array of normal methods tokens</param>
         /// <param name="data">pointer to memory with result</param>
         /// <returns>"Ok" if information is available</returns>
-        internal static RetCode GetModuleMethodsRanges(IntPtr symbolReaderHandle, int constrNum, IntPtr constrTokens, int normalNum, IntPtr normalTokens, out IntPtr data)
+        internal static RetCode GetModuleMethodsRanges(IntPtr symbolReaderHandle, uint constrNum, IntPtr constrTokens, uint normalNum, IntPtr normalTokens, out IntPtr data)
         {
             Debug.Assert(symbolReaderHandle != IntPtr.Zero);
             data = IntPtr.Zero;
index 971983f5ef3ab8dda53fc532a2abdcd58cc4b215..25624ac84573e68f78f5e9d76ea11ca84a13bf94 100644 (file)
@@ -63,7 +63,7 @@ typedef  RetCode (*GetHoistedLocalScopes)(PVOID, int32_t, PVOID*, int32_t*);
 typedef  RetCode (*GetSequencePointByILOffsetDelegate)(PVOID, mdMethodDef, uint32_t, PVOID);
 typedef  RetCode (*GetNextSequencePointByILOffsetDelegate)(PVOID, mdMethodDef, uint32_t, uint32_t*, int32_t*);
 typedef  RetCode (*GetStepRangesFromIPDelegate)(PVOID, int32_t, mdMethodDef, uint32_t*, uint32_t*);
-typedef  RetCode (*GetModuleMethodsRangesDelegate)(PVOID, int32_t, PVOID, int32_t, PVOID, PVOID*);
+typedef  RetCode (*GetModuleMethodsRangesDelegate)(PVOID, uint32_t, PVOID, uint32_t, PVOID, PVOID*);
 typedef  RetCode (*ResolveBreakPointsDelegate)(PVOID[], int32_t, PVOID, int32_t, int32_t, int32_t*, PVOID*);
 typedef  RetCode (*GetAsyncMethodSteppingInfoDelegate)(PVOID, mdMethodDef, PVOID*, int32_t*, uint32_t*);
 typedef  RetCode (*GetSourceDelegate)(PVOID, const WCHAR*, int32_t*, PVOID*);
@@ -401,7 +401,7 @@ HRESULT CalculationDelegate(PVOID firstOp, int32_t firstType, PVOID secondOp, in
     return S_OK;
 }
 
-HRESULT GetModuleMethodsRanges(PVOID pSymbolReaderHandle, int32_t constrTokensNum, PVOID constrTokens, int32_t normalTokensNum, PVOID normalTokens, PVOID *data)
+HRESULT GetModuleMethodsRanges(PVOID pSymbolReaderHandle, uint32_t constrTokensNum, PVOID constrTokens, uint32_t normalTokensNum, PVOID normalTokens, PVOID *data)
 {
     std::unique_lock<Utility::RWLock::Reader> read_lock(CLRrwlock.reader);
     if (!getModuleMethodsRangesDelegate || !pSymbolReaderHandle || (constrTokensNum && !constrTokens) || (normalTokensNum && !normalTokens) || !data)
index aee784d1916a3d798ad89404cc5eb422e3971980..879d449420bcad0b489f11e106c930b9dda92c3c 100644 (file)
@@ -93,7 +93,7 @@ namespace Interop
                                           WCHAR *localName, ULONG localNameLen, ULONG32 *pIlStart, ULONG32 *pIlEnd);
     HRESULT GetHoistedLocalScopes(PVOID pSymbolReaderHandle, mdMethodDef methodToken, PVOID *data, int32_t &hoistedLocalScopesCount);
     HRESULT GetStepRangesFromIP(PVOID pSymbolReaderHandle, ULONG32 ip, mdMethodDef MethodToken, ULONG32 *ilStartOffset, ULONG32 *ilEndOffset);
-    HRESULT GetModuleMethodsRanges(PVOID pSymbolReaderHandle, int32_t constrTokensNum, PVOID constrTokens, int32_t normalTokensNum, PVOID normalTokens, PVOID *data);
+    HRESULT GetModuleMethodsRanges(PVOID pSymbolReaderHandle, uint32_t constrTokensNum, PVOID constrTokens, uint32_t normalTokensNum, PVOID normalTokens, PVOID *data);
     HRESULT ResolveBreakPoints(PVOID pSymbolReaderHandles[], int32_t tokenNum, PVOID Tokens, int32_t sourceLine, int32_t nestedToken, int32_t &Count, PVOID *data);
     HRESULT GetAsyncMethodSteppingInfo(PVOID pSymbolReaderHandle, mdMethodDef methodToken, std::vector<AsyncAwaitInfoBlock> &AsyncAwaitInfo, ULONG32 *ilOffset);
     HRESULT GetSource(PVOID symbolReaderHandle, const std::string fileName, PVOID *data, int32_t *length);
index 7a29b056e49f5fd07a6b714fdc11810e43d12bbd..23883129d14215ffda50fc1ab8934ad1e35a7a28 100644 (file)
@@ -1053,14 +1053,15 @@ HRESULT Modules::FillSourcesCodeLinesForModule(ICorDebugModule *pModule, IMetaDa
     }
     pMDImport->CloseEnum(fEnum);
 
-    if (constrTokens.size() > std::numeric_limits<int32_t>::max() || normalTokens.size() > std::numeric_limits<int32_t>::max())
+    if (sizeof(std::size_t) > sizeof(std::uint32_t) &&
+        (constrTokens.size() > std::numeric_limits<uint32_t>::max() || normalTokens.size() > std::numeric_limits<uint32_t>::max()))
     {
         LOGE("Too big token arrays.");
         return E_FAIL;
     }
 
     PVOID data = nullptr;
-    IfFailRet(Interop::GetModuleMethodsRanges(pSymbolReaderHandle, (int32_t)constrTokens.size(), constrTokens.data(), (int32_t)normalTokens.size(), normalTokens.data(), &data));
+    IfFailRet(Interop::GetModuleMethodsRanges(pSymbolReaderHandle, (uint32_t)constrTokens.size(), constrTokens.data(), (uint32_t)normalTokens.size(), normalTokens.data(), &data));
     if (data == nullptr)
         return S_OK;
 
@@ -1292,7 +1293,7 @@ HRESULT Modules::ResolveBreakpoint(/*in*/ CORDB_ADDRESS modAddress, /*in*/ std::
         if (info_pair == m_modulesInfo.end())
             return E_FAIL; // we must have it, since we loaded data from it
 
-        if (Tokens.size() > std::numeric_limits<int32_t>::max())
+        if ((int32_t)Tokens.size() > std::numeric_limits<int32_t>::max())
         {
             LOGE("Too big token arrays.");
             return E_FAIL;
index 4a71713d07a7305ed186bed3128b18d8496f3bc8..277a9b82f7dc1de8d728126e3179a4ab3f926f36 100644 (file)
@@ -335,7 +335,7 @@ void VSCodeProtocol::EmitOutputEvent(OutputCategory category, string_view output
     serialize_output(count, m_seqCounter, name, "", escaped_source);
 
     // compute total size of headers + text
-    size_t const total_size = count.size() + escaped_text.size();
+    auto const total_size = count.size() + escaped_text.size();
 
     // perform output
     cout << CONTENT_LENGTH << total_size << TWO_CRLF;
index 9613d8cdb9bea1ad0bb18a4dbd874acf55194f8a..acd826a1f2883eae094bdf0c9df50aa897b82635 100644 (file)
@@ -67,14 +67,23 @@ template <typename Traits> struct IOSystemImpl
         constexpr static const size_t MaxIteratorSize = sizeof(void*) * 2;
 
         const Operations& ops;
-        mutable char data alignas(alignof(std::max_align_t)) [MaxIteratorSize];
+
+        // Note, we can't use `alignas(alignof(std::max_align_t))` here, since at least MSVC 32bit (VS2019) compiler can't
+        // generate proper code and ASAN detect "ERROR: AddressSanitizer: stack - buffer - underflow on address...".
+        union data_align_t
+        {
+            std::max_align_t align_field;
+            mutable char data[MaxIteratorSize];
+        };
+        data_align_t data_align_tmp;
+        char * const data;
 
     public:
         /// Iterator might be created from any other iterator or pointer type,
         /// for which `operator*` returns reference to `AsyncHandle`.
         template <typename Iterator,
             typename = typename std::enable_if<std::is_convertible<decltype(*std::declval<Iterator>()), AsyncHandle&>::value>::type>
-        AsyncHandleIterator(Iterator it) : ops(OpsImpl<Iterator>::ops) { new (data) Iterator(it); }
+        AsyncHandleIterator(Iterator it) : ops(OpsImpl<Iterator>::ops), data(data_align_tmp.data) { new (data) Iterator(it); }
 
         ~AsyncHandleIterator() { ops.destr(data); }
 
index 861cb1e5c47b1cea9f03c5bf586b763dc7bd7d33..d206c6c2313d6f2acbf9038c72db4b5259fc5e47 100644 (file)
@@ -517,7 +517,17 @@ Class::IOResult Class::close(const FileHandle& fh)
 Class::IOSystem::StdFiles Class::get_std_files()
 {
     using Handles = std::tuple<IOSystem::FileHandle, IOSystem::FileHandle, IOSystem::FileHandle>;
-    /*thread_local*/ static alignas(alignof(Handles)) char mem[sizeof(Handles)];  // TODO
+
+    // Note, we can't use `alignas(alignof(std::max_align_t))` here, since at least MSVC 32bit (VS2019) compiler can't
+    // generate proper code and ASAN detect "ERROR: AddressSanitizer: stack - buffer - underflow on address...".
+    union mem_align_t
+    {
+        std::max_align_t align_field;
+        char mem[sizeof(Handles)];
+    };
+    mem_align_t mem_align_tmp;
+    char * const mem = mem_align_tmp.mem;
+
     Handles& handles = *new (mem) Handles {
         FileHandle(GetStdHandle(STD_INPUT_HANDLE)),
         FileHandle(GetStdHandle(STD_OUTPUT_HANDLE)),
index 95f6185bfbbb51f4bb87e66d674d24964ac264dd..ba4d18bb69818f0db8a53b8b200ffc314b6d17bf 100644 (file)
@@ -70,7 +70,7 @@ void InStreamBuf::compactify()
     {
         if (size_t(in_avail()) <= MaxMoveSize)   // tail is not too big
         {
-            memmove(eback() + UngetChars, gptr(), in_avail());
+            memmove(eback() + UngetChars, gptr(), size_t(in_avail()));
             setg(eback(), eback() + UngetChars, eback() + UngetChars + in_avail());
         }
     }
index 3265e5f2c0ec0575969f05592fc54c82feeb2509..5a40c5ca513c747921a52420cdf344124258d35b 100644 (file)
@@ -1,5 +1,6 @@
 using System;
 using System.IO;
+using System.Runtime.InteropServices;
 
 using NetcoreDbgTest;
 using NetcoreDbgTest.MI;
@@ -204,11 +205,15 @@ namespace MITestException
                 Context.WasEntryPointHit(@"__FILE__:__LINE__");
             });
 
+            bool win32detect = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && IntPtr.Size == 4; Label.Breakpoint("STEP0");
+
             P p = new P();                                      Label.Breakpoint("STEP1");
 
             Label.Checkpoint("test_steps", "try_catch", (Object context) => {
                 Context Context = (Context)context;
                 Context.StepOver(@"__FILE__:__LINE__");
+                Context.WasStep(@"__FILE__:__LINE__", "STEP0");
+                Context.StepOver(@"__FILE__:__LINE__");
                 Context.WasStep(@"__FILE__:__LINE__", "STEP1");
                 Context.StepOver(@"__FILE__:__LINE__");
                 Context.WasStep(@"__FILE__:__LINE__", "TRY1");
@@ -236,16 +241,29 @@ namespace MITestException
 
                 Label.Checkpoint("try_catch", "finish", (Object context) => {
                     Context Context = (Context)context;
+
+                    var resWin32Detect = Context.MIDebugger.Request(String.Format("-var-create - * \"win32detect\""));
+                    Assert.Equal(MIResultClass.Done, resWin32Detect.Class, @"__FILE__:__LINE__");
+                    Assert.Equal("bool", ((MIConst)resWin32Detect["type"]).CString, @"__FILE__:__LINE__");
+                    string win32detect = ((MIConst)resWin32Detect["value"]).CString;
+
                     // Check stack frames location
                     var res = Context.MIDebugger.Request("-stack-list-frames");
                     Assert.Equal(MIResultClass.Done, res.Class, @"__FILE__:__LINE__");
 
                     var stack = (MIList)res["stack"];
-
-                    Assert.Equal(3, stack.Count, @"__FILE__:__LINE__");
-                    Assert.True(Context.IsValidFrame((MIResult)stack[0], "CATCH4", 0), @"__FILE__:__LINE__");
-                    Assert.True(Context.IsValidFrame((MIResult)stack[1], "THROW1", 1), @"__FILE__:__LINE__");
-                    Assert.True(Context.IsValidFrame((MIResult)stack[2], "TRY3", 2), @"__FILE__:__LINE__");
+                    if (win32detect == "true")
+                    {
+                        Assert.Equal(1, stack.Count, @"__FILE__:__LINE__");
+                        Assert.True(Context.IsValidFrame((MIResult)stack[0], "CATCH4", 0), @"__FILE__:__LINE__");
+                    }
+                    else
+                    {
+                        Assert.Equal(3, stack.Count, @"__FILE__:__LINE__");
+                        Assert.True(Context.IsValidFrame((MIResult)stack[0], "CATCH4", 0), @"__FILE__:__LINE__");
+                        Assert.True(Context.IsValidFrame((MIResult)stack[1], "THROW1", 1), @"__FILE__:__LINE__");
+                        Assert.True(Context.IsValidFrame((MIResult)stack[2], "TRY3", 2), @"__FILE__:__LINE__");
+                    }
 
                     //Check local variables
                     res = Context.MIDebugger.Request("-stack-list-variables");
index ad7519087ed7240a0fdedff6fad58d3370a22e0f..71e91cd237110c58038d3d6de377aab2482aa456 100644 (file)
@@ -3457,7 +3457,11 @@ void linenoisePrintKeyCodes(void) {
   disableRawMode();
 }
 
-static void WindowSizeChanged(int) {
+static void
+#if defined(WIN32) && defined(_TARGET_X86_)
+            __cdecl
+#endif
+                    WindowSizeChanged(int) {
   // do nothing here but setting this flag
   gotResize = true;
 #ifdef _WIN32
index 59792f893aa6666820527abd3455bc62a9b94cf0..69b377f5c0df1a2a9a5f674777596c0472bed3f4 100644 (file)
@@ -18,7 +18,11 @@ void completionHook (char const* prefix, linenoiseCompletions* lc) {
   }
 }
 
-int main (int argc, char** argv) {
+int
+#if defined(WIN32) && defined(_TARGET_X86_)
+    __cdecl
+#endif
+            main (int argc, char** argv) {
   linenoiseInstallWindowChangeHandler();
 
   while(argc > 1) {