Fix issues found by svace 3.4.
authorMikhail Kurinnoi <m.kurinnoi@samsung.com>
Mon, 28 Oct 2024 12:27:26 +0000 (15:27 +0300)
committerGleb Balykov/Advanced System SW Lab /SRR/Staff Engineer/Samsung Electronics <g.balykov@samsung.com>
Sat, 2 Nov 2024 07:34:37 +0000 (10:34 +0300)
20 files changed:
src/CMakeLists.txt
src/debugger/breakpoint_entry.cpp
src/debugger/breakpoints_interop.cpp
src/debugger/frames.cpp
src/debugger/interop_arm32_singlestep_helpers.cpp
src/debugger/interop_brk_helpers.cpp
src/debugger/interop_debugging.cpp
src/debugger/interop_mem_helpers.cpp
src/debugger/interop_riscv64_singlestep_helpers.cpp
src/debugger/interop_singlestep_helpers.cpp
src/debugger/managedcallback.cpp
src/debugger/valueprint.cpp
src/metadata/interop_libraries.cpp
src/metadata/modules_sources.cpp
src/metadata/modules_sources.h
src/protocols/cliprotocol.cpp
src/unittests/CMakeLists.txt
src/utils/err_utils.cpp [new file with mode: 0644]
src/utils/iosystem_unix.cpp
src/utils/logger.h

index 473fdf4f5627aab460a4357618199e1679188e21..b53746dc679131511936d212f4f665bd465c4d05 100644 (file)
@@ -130,6 +130,7 @@ set(netcoredbg_SRC
     buildinfo.cpp
     utils/dynlibs_unix.cpp
     utils/dynlibs_win32.cpp
+    utils/err_utils.cpp
     utils/filesystem.cpp
     utils/filesystem_unix.cpp
     utils/filesystem_win32.cpp
index be7439124ef66d2781657837ff9ba1b78a765bd8..995fb3bce434929d43f88fddb7b873c81f21c2d5 100644 (file)
@@ -56,9 +56,9 @@ static mdMethodDef GetEntryPointTokenFromFile(const std::string &path)
         corRVA = VAL32(ntHeaders64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress);\r
     }\r
 \r
-    constexpr DWORD DWORD_MAX = 4294967295;\r
-    DWORD pos = VAL32(dosHeader.e_lfanew);\r
-    if (pos > DWORD_MAX - sizeof(ntHeaders.Signature) - sizeof(ntHeaders.FileHeader) - VAL16(ntHeaders.FileHeader.SizeOfOptionalHeader))\r
+    constexpr LONG lLONG_MAX = 2147483647;\r
+    LONG pos = VAL32(dosHeader.e_lfanew);\r
+    if (pos < 0 || size_t(lLONG_MAX - pos) < sizeof(ntHeaders.Signature) + sizeof(ntHeaders.FileHeader) + VAL16(ntHeaders.FileHeader.SizeOfOptionalHeader))\r
         return mdMethodDefNil;\r
     pos += sizeof(ntHeaders.Signature) + sizeof(ntHeaders.FileHeader) + VAL16(ntHeaders.FileHeader.SizeOfOptionalHeader);\r
 \r
@@ -74,6 +74,8 @@ static mdMethodDef GetEntryPointTokenFromFile(const std::string &path)
             corRVA < VAL32(sectionHeader.VirtualAddress) + VAL32(sectionHeader.SizeOfRawData))\r
         {\r
             ULONG offset = (corRVA - VAL32(sectionHeader.VirtualAddress)) + VAL32(sectionHeader.PointerToRawData);\r
+            if (offset > (ULONG)lLONG_MAX)\r
+                return mdMethodDefNil;\r
 \r
             IMAGE_COR20_HEADER corHeader;\r
             if (fseek(pFile, offset, SEEK_SET) != 0) return mdMethodDefNil;\r
index 5daa8b0b45f038d2de9074fec28844531f1d5c92..4c6ad8469e2bc1ba8bad9988b834c21dc59004f4 100644 (file)
@@ -34,14 +34,16 @@ int InteropBreakpoints::Add(pid_t pid, std::uintptr_t brkAddr, bool isThumbCode,
         if (errno != 0)\r
         {\r
             int err_code = errno;\r
-            LOGE("Ptrace peekdata error: %s", strerror(err_code));\r
+            char buf[1024];\r
+            LOGE("Ptrace peekdata error: %s", ErrGetStr(err_code, buf, sizeof(buf)));\r
             return err_code;\r
         }\r
         dataWithBrk = EncodeBrkOpcode(savedData, isThumbCode);\r
         if (async_ptrace(PTRACE_POKEDATA, pid, (void*)brkAddr, (void*)dataWithBrk) == -1)\r
         {\r
             int err_code = errno;\r
-            LOGE("Ptrace pokedata error: %s", strerror(err_code));\r
+            char buf[1024];\r
+            LOGE("Ptrace pokedata error: %s", ErrGetStr(err_code, buf, sizeof(buf)));\r
             return err_code;\r
         }\r
 \r
@@ -75,7 +77,8 @@ int InteropBreakpoints::Remove(pid_t pid, std::uintptr_t brkAddr, std::function<
         if (errno != 0)\r
         {\r
             int err_code = errno;\r
-            LOGE("Ptrace peekdata error: %s", strerror(err_code));\r
+            char buf[1024];\r
+            LOGE("Ptrace peekdata error: %s", ErrGetStr(err_code, buf, sizeof(buf)));\r
             return err_code;\r
         }\r
         word_t restoredData = RestoredOpcode(brkData, find->second.m_savedData);\r
@@ -83,7 +86,8 @@ int InteropBreakpoints::Remove(pid_t pid, std::uintptr_t brkAddr, std::function<
         if (async_ptrace(PTRACE_POKEDATA, pid, (void*)find->first, (void*)restoredData) == -1)\r
         {\r
             int err_code = errno;\r
-            LOGW("Ptrace pokedata error: %s\n", strerror(err_code));\r
+            char buf[1024];\r
+            LOGW("Ptrace pokedata error: %s\n", ErrGetStr(err_code, buf, sizeof(buf)));\r
             return err_code;\r
         }\r
         m_currentBreakpointsInMemory.erase(find);\r
@@ -104,14 +108,16 @@ void InteropBreakpoints::RemoveAllAtDetach(pid_t pid)
             word_t brkData = async_ptrace(PTRACE_PEEKDATA, pid, (void*)entry.first, nullptr);\r
             if (errno != 0)\r
             {\r
-                LOGE("Ptrace peekdata error: %s", strerror(errno));\r
+                char buf[1024];\r
+                LOGE("Ptrace peekdata error: %s", ErrGetStr(errno, buf, sizeof(buf)));\r
                 continue;\r
             }\r
             word_t restoredData = RestoredOpcode(brkData, entry.second.m_savedData);\r
 \r
             if (async_ptrace(PTRACE_POKEDATA, pid, (void*)entry.first, (void*)restoredData) == -1)\r
             {\r
-                LOGE("Ptrace pokedata error: %s\n", strerror(errno));\r
+                char buf[1024];\r
+                LOGE("Ptrace pokedata error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));\r
             }\r
         }\r
     }\r
@@ -157,7 +163,8 @@ bool InteropBreakpoints::StepPrevToBrk(pid_t pid, std::uintptr_t brkAddr)
     iov.iov_len = sizeof(user_regs_struct);\r
     if (async_ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)\r
     {\r
-        LOGE("Ptrace getregset error: %s\n", strerror(errno));\r
+        char buf[1024];\r
+        LOGE("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));\r
         std::abort(); // Fatal error, we already logged all data about this error.\r
     }\r
 \r
@@ -165,7 +172,8 @@ bool InteropBreakpoints::StepPrevToBrk(pid_t pid, std::uintptr_t brkAddr)
 \r
     if (async_ptrace(PTRACE_SETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)\r
     {\r
-        LOGE("Ptrace setregset error: %s\n", strerror(errno));\r
+        char buf[1024];\r
+        LOGE("Ptrace setregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));\r
         std::abort(); // Fatal error, we already logged all data about this error.\r
     }\r
 \r
index 0f1e4eb735d28533afffc72e0e4e801a2d9be565..92e0a5813df3da706699f4f9544e98b13bd7fdc6 100644 (file)
@@ -124,7 +124,8 @@ static HRESULT EmptyContextForTopFrame(ICorDebugThread *pThread, WalkFramesCallb
         iov.iov_len = sizeof(user_regs_struct);
         if (InteropDebugging::async_ptrace(PTRACE_GETREGSET, threadId, (void*)NT_PRSTATUS, &iov) == -1)
         {
-            LOGW("Ptrace getregset error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGW("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         }
         else
         {
index 0e4e5fe4c87ca56ad7bfcec0046ea3df7fb8eeea..f4cfec9fd7c58a98e7c39bf868fb67e38ea23b09 100644 (file)
@@ -54,7 +54,8 @@ bool GetDataFromMemory(pid_t pid, std::uintptr_t addr, T &result)
     word_t wData = async_ptrace(PTRACE_PEEKDATA, pid, (void*)addr, nullptr);
     if (errno != 0)
     {
-        LOGE("Ptrace peekdata error: %s", strerror(errno));
+        char buf[1024];
+        LOGE("Ptrace peekdata error: %s", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -1049,7 +1050,8 @@ bool ARM32_DoSoftwareSingleStep(pid_t pid, std::vector<sw_singlestep_brk_t> &swS
     iov.iov_len = sizeof(user_regs_struct);
     if (async_ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)
     {
-        LOGW("Ptrace getregset error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGW("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -1078,7 +1080,8 @@ bool ARM32_DoSoftwareSingleStep(pid_t pid, std::vector<sw_singlestep_brk_t> &swS
         word_t nextPCData = async_ptrace(PTRACE_PEEKDATA, pid, (void*)entry.addr, nullptr);
         if (errno != 0)
         {
-            LOGE("Ptrace peekdata error: %s", strerror(errno));
+            char buf[1024];
+            LOGE("Ptrace peekdata error: %s", ErrGetStr(errno, buf, sizeof(buf)));
             return false;
         }
 
@@ -1086,7 +1089,8 @@ bool ARM32_DoSoftwareSingleStep(pid_t pid, std::vector<sw_singlestep_brk_t> &swS
 
         if (async_ptrace(PTRACE_POKEDATA, pid, (void*)entry.addr, (void*)dataWithBrk) == -1)
         {
-            LOGE("Ptrace pokedata error: %s", strerror(errno));
+            char buf[1024];
+            LOGE("Ptrace pokedata error: %s", ErrGetStr(errno, buf, sizeof(buf)));
             return false;
         }
 
index d4bd1ce36b07479c09a8de2b9032a85c3957e975..dd8cab9e2f956ba2492991197792c1dcddccddda 100644 (file)
@@ -184,7 +184,8 @@ bool StepOverBrk(pid_t pid, std::uintptr_t addr, word_t restoreData, std::functi
         iov.iov_len = sizeof(user_regs_struct);
         if (async_ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)
         {
-            LOGE("Ptrace getregset error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGE("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             return false;
         }
 
@@ -192,7 +193,8 @@ bool StepOverBrk(pid_t pid, std::uintptr_t addr, word_t restoreData, std::functi
 
         if (async_ptrace(PTRACE_SETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)
         {
-            LOGE("Ptrace setregset error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGE("Ptrace setregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             return false;
         }
     }
@@ -201,7 +203,8 @@ bool StepOverBrk(pid_t pid, std::uintptr_t addr, word_t restoreData, std::functi
     word_t brkData = async_ptrace(PTRACE_PEEKDATA, pid, (void*)addr, nullptr);
     if (errno != 0)
     {
-        LOGE("Ptrace peekdata error: %s", strerror(errno));
+        char buf[1024];
+        LOGE("Ptrace peekdata error: %s", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -210,7 +213,8 @@ bool StepOverBrk(pid_t pid, std::uintptr_t addr, word_t restoreData, std::functi
     // restore data
     if (async_ptrace(PTRACE_POKEDATA, pid, (void*)addr, (void*)restoreData) == -1)
     {
-        LOGE("Ptrace pokedata error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGE("Ptrace pokedata error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -220,7 +224,8 @@ bool StepOverBrk(pid_t pid, std::uintptr_t addr, word_t restoreData, std::functi
     // setup bp again
     if (async_ptrace(PTRACE_POKEDATA, pid, (void*)addr, (void*)brkData) == -1)
     {
-        LOGE("Ptrace pokedata error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGE("Ptrace pokedata error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
index 6125fbcea51f321f661932fc26ca579c2e56031d..e726b8a6992c872c2661ff41a71995c46fd05d21 100644 (file)
@@ -95,7 +95,8 @@ static bool DoSoftwareSingleStep(pid_t pid, std::unordered_map<pid_t, thread_sta
 
     if (async_ptrace(PTRACE_CONT, pid, nullptr, nullptr) == -1)
     {
-        LOGW("Ptrace cont error: %s", strerror(errno));
+        char buf[1024];
+        LOGW("Ptrace cont error: %s", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
     else
@@ -115,7 +116,8 @@ static bool DetectBrkForSoftwareSingleStep(pid_t pid, std::unordered_map<pid_t,
     iov.iov_len = sizeof(user_regs_struct);
     if (async_ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)
     {
-        LOGW("Ptrace getregset error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGW("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         RemoveSoftwareSingleStepBreakpoints(pid, swSingleStepBreakpoints);
         return false;
     }
@@ -177,7 +179,8 @@ bool InteropDebuggerBase::SingleStepOnBrk(pid_t pid, std::uintptr_t addr)
             else
 #endif // DEBUGGER_UNIX_ARM
             {
-                LOGE("Ptrace singlestep error: %s\n", strerror(errno));
+                char buf[1024];
+                LOGE("Ptrace singlestep error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
                 return false;
             }
         }
@@ -206,7 +209,8 @@ bool InteropDebuggerBase::SingleStepOnBrk(pid_t pid, std::uintptr_t addr)
         siginfo_t ptrace_info;
         if (async_ptrace(PTRACE_GETSIGINFO, pid, nullptr, &ptrace_info) == -1)
         {
-            LOGW("Ptrace getsiginfo error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGW("Ptrace getsiginfo error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
 #if DEBUGGER_UNIX_ARM || DEBUGGER_UNIX_RISCV64
             if (!m_HWSingleStepSupported)
                 RemoveSoftwareSingleStepBreakpoints(pid, swSingleStepBreakpoints);
@@ -248,7 +252,8 @@ bool InteropDebuggerBase::SingleStepOnBrk(pid_t pid, std::uintptr_t addr)
         siginfo_t ptrace_info;
         if (async_ptrace(PTRACE_GETSIGINFO, pid, nullptr, &ptrace_info) == -1)
         {
-            LOGW("Ptrace getsiginfo error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGW("Ptrace getsiginfo error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             return false;
         }
 
@@ -337,7 +342,10 @@ void InteropDebuggerBase::WaitThreadStop(pid_t stoppedPid, std::vector<pid_t> *s
             siginfo_t siginfo;
             bool sendByItself = false;
             if (async_ptrace(PTRACE_GETSIGINFO, pid, nullptr, &siginfo) == -1)
-                LOGW("Ptrace getsiginfo error: %s\n", strerror(errno));
+            {
+                char buf[1024];
+                LOGW("Ptrace getsiginfo error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
+            }
             else
                 sendByItself = (siginfo.si_pid == m_TGID);
 
@@ -376,7 +384,8 @@ void InteropDebuggerHelpers::StopAndDetach(pid_t tgid)
         iov.iov_len = sizeof(user_regs_struct);
         if (async_ptrace(PTRACE_GETREGSET, entry.first, (void*)NT_PRSTATUS, &iov) == -1)
         {
-            LOGW("Ptrace getregset error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGW("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             continue; // Will hope, this thread didn't stopped at breakpoint.
         }
 
@@ -393,7 +402,10 @@ void InteropDebuggerHelpers::StopAndDetach(pid_t tgid)
     for (const auto &tid : m_TIDs)
     {
         if (async_ptrace(PTRACE_DETACH, tid.first, nullptr, (void*)((word_t)tid.second.stop_signal)) == -1)
-            LOGW("Ptrace detach error: %s\n", strerror(errno));
+        {
+            char buf[1024];
+            LOGW("Ptrace detach error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
+        }
     }
 
     m_TIDs.clear();
@@ -409,7 +421,8 @@ static void StopAllRunningThreads(const std::unordered_map<pid_t, thread_status_
         if (tid.second.stat == thread_stat_e::running &&
             async_ptrace(PTRACE_INTERRUPT, tid.first, nullptr, nullptr) == -1)
         {
-            LOGW("Ptrace interrupt error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGW("Ptrace interrupt error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         }
     }
 }
@@ -464,7 +477,8 @@ static HRESULT SeizeAndInterruptAllThreads(std::unordered_map<pid_t, thread_stat
     if (!dir)
     {
         error_n = errno;
-        LOGE("opendir: %s\n", strerror(errno));
+        char buf[1024];
+        LOGE("opendir: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         return E_FAIL;
     }
 
@@ -490,7 +504,8 @@ static HRESULT SeizeAndInterruptAllThreads(std::unordered_map<pid_t, thread_stat
         if (async_ptrace(PTRACE_SEIZE, tid, nullptr, (void*)options) == -1)
         {
             error_n = errno;
-            LOGE("Ptrace seize error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGE("Ptrace seize error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             closedir(dir);
             return E_FAIL;
         }
@@ -500,7 +515,8 @@ static HRESULT SeizeAndInterruptAllThreads(std::unordered_map<pid_t, thread_stat
 
         if (async_ptrace(PTRACE_INTERRUPT, tid, nullptr, nullptr) == -1)
         {
-            LOGE("Ptrace interrupt error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGE("Ptrace interrupt error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             closedir(dir);
             exit(EXIT_FAILURE); // Fatal error, seized but failed on interrupt.
         }
@@ -508,13 +524,15 @@ static HRESULT SeizeAndInterruptAllThreads(std::unordered_map<pid_t, thread_stat
     if (errno)
     {
         error_n = errno;
-        LOGE("readdir: %s\n", strerror(errno));
+        char buf[1024];
+        LOGE("readdir: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         closedir(dir);
         return E_FAIL;
     }
     if (closedir(dir))
     {
-        LOGW("closedir: %s\n", strerror(errno));
+        char buf[1024];
+        LOGW("closedir: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
     }
 
     return S_OK;
@@ -568,7 +586,8 @@ static bool AddSignalEventForUserCode(pid_t pid, InteropLibraries *pInteropLibra
     iov.iov_len = sizeof(user_regs_struct);
     if (async_ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)
     {
-        LOGW("Ptrace getregset error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGW("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -591,7 +610,8 @@ static bool AddSignalEventForCallerInUserCode(pid_t pid, pid_t TGID, InteropLibr
     memset(&siginfo, 0, sizeof(siginfo_t));
     if (async_ptrace(PTRACE_GETSIGINFO, pid, nullptr, &siginfo) == -1)
     {
-        LOGW("Ptrace getsiginfo error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGW("Ptrace getsiginfo error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
     if (siginfo.si_pid != TGID)
@@ -669,7 +689,8 @@ void InteropDebuggerSignals::Parse_SIGILL(pid_t pid)
     siginfo_t ptrace_info;
     if (async_ptrace(PTRACE_GETSIGINFO, pid, nullptr, &ptrace_info) == -1)
     {
-        LOGW("Ptrace getsiginfo error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGW("Ptrace getsiginfo error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
     }
     else
     {
@@ -699,7 +720,10 @@ void InteropDebuggerSignals::Parse_SIGTRAP__PTRACE_EVENT_EXEC(pid_t pid)
     }
 
     if (async_ptrace(PTRACE_DETACH, pid, nullptr, nullptr) == -1)
-        LOGW("Ptrace detach at exec error: %s\n", strerror(errno));
+    {
+        char buf[1024];
+        LOGW("Ptrace detach at exec error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
+    }
     else
         m_TIDs.erase(pid);
 }
@@ -709,7 +733,8 @@ void InteropDebuggerSignals::Parse_SIGTRAP__NOT_PTRACE_EVENT(pid_t pid)
     siginfo_t ptrace_info;
     if (async_ptrace(PTRACE_GETSIGINFO, pid, nullptr, &ptrace_info) == -1)
     {
-        LOGW("Ptrace getsiginfo error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGW("Ptrace getsiginfo error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
     }
     else
     {
@@ -724,7 +749,10 @@ void InteropDebuggerSignals::Parse_SIGTRAP__NOT_PTRACE_EVENT(pid_t pid)
                 iov.iov_base = &regs;
                 iov.iov_len = sizeof(user_regs_struct);
                 if (async_ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)
-                    LOGW("Ptrace getregset error: %s\n", strerror(errno));
+                {
+                    char buf[1024];
+                    LOGW("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
+                }
 
                 std::uintptr_t brkAddr = GetBrkAddrByPC(regs);
 
@@ -865,7 +893,10 @@ void InteropDebuggerBase::ParseThreadsChanges()
             continue;
 
         if (async_ptrace(PTRACE_CONT, pid, nullptr, (void*)((word_t)m_TIDs[pid].stop_signal)) == -1)
-            LOGW("Ptrace cont error: %s", strerror(errno));
+        {
+            char buf[1024];
+            LOGW("Ptrace cont error: %s", ErrGetStr(errno, buf, sizeof(buf)));
+        }
         else
         {
             m_TIDs[pid].stat = thread_stat_e::running;
@@ -1028,7 +1059,10 @@ static void StopAllManagedThreads(std::unordered_map<pid_t, thread_status_t> &TI
             continue;
 
         if (async_ptrace(PTRACE_INTERRUPT, managedThread.first, nullptr, nullptr) == -1)
-            LOGW("Ptrace interrupt error: %s\n", strerror(errno));
+        {
+            char buf[1024];
+            LOGW("Ptrace interrupt error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
+        }
         else
             stoppedManagedTreads.emplace_back(managedThread.first);
     }
@@ -1215,7 +1249,8 @@ void InteropDebuggerBase::WaitpidWorker()
 
         if (pid == -1)
         {
-            LOGE("Waitpid error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGE("Waitpid error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             break;
         }
 
@@ -1278,7 +1313,10 @@ void InteropDebuggerBase::WaitpidWorker()
             siginfo_t siginfo;
             bool sendByItself = false;
             if (async_ptrace(PTRACE_GETSIGINFO, pid, nullptr, &siginfo) == -1)
-                LOGW("Ptrace getsiginfo error: %s\n", strerror(errno));
+            {
+                char buf[1024];
+                LOGW("Ptrace getsiginfo error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
+            }
             else
                 sendByItself = (siginfo.si_pid == m_TGID);
 
@@ -1294,7 +1332,10 @@ void InteropDebuggerBase::WaitpidWorker()
                     injectTIDs.emplace(std::make_pair(pid, injectSignalResetCountdown));
 
                 if (async_ptrace(PTRACE_CONT, pid, nullptr, (void*)((word_t)stop_signal)) == -1)
-                    LOGW("Ptrace cont error: %s", strerror(errno));
+                {
+                    char buf[1024];
+                    LOGW("Ptrace cont error: %s", ErrGetStr(errno, buf, sizeof(buf)));
+                }
                 // No need change `m_TIDs[pid].stat` and `m_TIDs[pid].stop_signal` here.
                 continue;
             }
@@ -1401,7 +1442,8 @@ void InteropDebuggerHelpers::BrkFixAllThreads(std::uintptr_t checkAddr)
         iov.iov_len = sizeof(user_regs_struct);
         if (async_ptrace(PTRACE_GETREGSET, entry.first, (void*)NT_PRSTATUS, &iov) == -1)
         {
-            LOGW("Ptrace getregset error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGW("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             continue; // Will hope, this thread didn't stopped at breakpoint.
         }
 
@@ -1605,7 +1647,10 @@ HRESULT InteropDebugger::UnwindNativeFrames(pid_t pid, bool firstFrame, std::uin
     if (tid->second.stat == thread_stat_e::running)
     {
         if (async_ptrace(PTRACE_INTERRUPT, pid, nullptr, nullptr) == -1)
-            LOGW("Ptrace interrupt error: %s\n", strerror(errno));
+        {
+            char buf[1024];
+            LOGW("Ptrace interrupt error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
+        }
         else
         {
             WaitThreadStop(pid);
index ddbf70b87d436e7d7c877efe7c18ec1fdce1ef1e..6302ef8b1babb7336a1efa946bf76b9df50c5610 100644 (file)
@@ -27,7 +27,8 @@ static T ReadFromAddr(pid_t pid, std::uintptr_t &addr)
     iovec remote_iov {(void*)addr, sizeof(T)};
     if (process_vm_readv(pid, &local_iov, 1, &remote_iov, 1, 0) == -1)
     {
-        LOGE("process_vm_readv: %s\n", strerror(errno));
+        char buf[1024];
+        LOGE("process_vm_readv: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         addr = 0;
         return t;
     }
@@ -81,7 +82,8 @@ static bool GetExecName(pid_t pid, std::string &execName)
 
     if (readlink(exeFileName, tmpName, PATH_MAX) == -1)
     {
-        LOGE("readlink error for %s file: %s\n", exeFileName, strerror(errno));
+        char buf[1024];
+        LOGE("readlink error for %s file: %s\n", exeFileName, ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -104,7 +106,8 @@ static bool GetProcData(pid_t pid, std::string &execName, std::uintptr_t &startA
     FILE *mapsFile = fopen(mapFileName, "r");
     if (mapsFile == nullptr)
     {
-        LOGE("fopen error for %s file: %s\n", mapFileName, strerror(errno));
+        char buf[1024];
+        LOGE("fopen error for %s file: %s\n", mapFileName, ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -148,7 +151,8 @@ bool ResolveRendezvous(pid_t pid, std::uintptr_t &rendezvousAddr)
     int fd = open(elfFileName.c_str(), O_RDONLY);
     if (fd == -1)
     {
-        LOGE("open error for %s file: %s\n", elfFileName.c_str(), strerror(errno));
+        char buf[1024];
+        LOGE("open error for %s file: %s\n", elfFileName.c_str(), ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
index 9344a86b6000d5a4e99892399d28cd174e04a39e..ad9147620fbd26d335333e9ad76bc89f123645a7 100644 (file)
@@ -184,7 +184,8 @@ bool RISCV64_DoSoftwareSingleStep(pid_t pid, std::vector<sw_singlestep_brk_t> &s
     iov.iov_len = sizeof(user_regs_struct);
     if (async_ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, &iov) == -1)
     {
-        LOGW("Ptrace getregset error: %s\n", strerror(errno));
+        char buf[1024];
+        LOGW("Ptrace getregset error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -192,7 +193,8 @@ bool RISCV64_DoSoftwareSingleStep(pid_t pid, std::vector<sw_singlestep_brk_t> &s
     word_t currentPCData = async_ptrace(PTRACE_PEEKDATA, pid, (void*)regs.pc, nullptr);
     if (errno != 0)
     {
-        LOGE("Ptrace peekdata error: %s", strerror(errno));
+        char buf[1024];
+        LOGE("Ptrace peekdata error: %s", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -215,7 +217,8 @@ bool RISCV64_DoSoftwareSingleStep(pid_t pid, std::vector<sw_singlestep_brk_t> &s
     word_t nextPCData = async_ptrace(PTRACE_PEEKDATA, pid, (void*)nextPC, nullptr);
     if (errno != 0)
     {
-        LOGE("Ptrace peekdata error: %s", strerror(errno));
+        char buf[1024];
+        LOGE("Ptrace peekdata error: %s", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
@@ -223,7 +226,8 @@ bool RISCV64_DoSoftwareSingleStep(pid_t pid, std::vector<sw_singlestep_brk_t> &s
 
     if (async_ptrace(PTRACE_POKEDATA, pid, (void*)nextPC, (void*)dataWithBrk) == -1)
     {
-        LOGE("Ptrace pokedata error: %s", strerror(errno));
+        char buf[1024];
+        LOGE("Ptrace pokedata error: %s", ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
index 271628444c1411aeea9d4af5f41e1576cc001e52..c1dafcd08cacc902595b05758d628cf31ab44f80 100644 (file)
@@ -23,7 +23,8 @@ bool RemoveSoftwareSingleStepBreakpoints(pid_t pid, std::vector<sw_singlestep_br
         word_t brkData = async_ptrace(PTRACE_PEEKDATA, pid, (void*)entry.bpAddr, nullptr);
         if (errno != 0)
         {
-            LOGE("Ptrace peekdata error: %s", strerror(errno));
+            char buf[1024];
+            LOGE("Ptrace peekdata error: %s", ErrGetStr(errno, buf, sizeof(buf)));
             return false;
         }
 
@@ -31,7 +32,8 @@ bool RemoveSoftwareSingleStepBreakpoints(pid_t pid, std::vector<sw_singlestep_br
 
         if (async_ptrace(PTRACE_POKEDATA, pid, (void*)entry.bpAddr, (void*)entry.restoreData) == -1)
         {
-            LOGE("Ptrace pokedata error: %s\n", strerror(errno));
+            char buf[1024];
+            LOGE("Ptrace pokedata error: %s\n", ErrGetStr(errno, buf, sizeof(buf)));
             return false;
         }
     }
index e957bfe73efac1e41d45766c32851028c3348da6..dc898af7499bb29276c6e6b70c5c0727d655a449 100644 (file)
@@ -188,7 +188,8 @@ HRESULT STDMETHODCALLTYPE ManagedCallback::CreateProcess(ICorDebugProcess *pProc
     if (m_debugger.m_interopDebugging &&
         FAILED(m_debugger.m_sharedInteropDebugger->Init((pid_t)m_debugger.m_processId, m_sharedCallbacksQueue, attach, NotifyLastThreadExited, error_n)))
     {
-        LOGE("Interop debugging disabled due to initialization fail: %s", strerror(error_n));
+        char buf[1024];
+        LOGE("Interop debugging disabled due to initialization fail: %s", ErrGetStr(error_n, buf, sizeof(buf)));
         m_debugger.pProtocol->EmitInteropDebuggingErrorEvent(error_n);
         m_debugger.m_interopDebugging = false;
     }
index 25ab7cb8998fad8f38c65e465692b83656d16bd7..81fae50f8daeb2b2ccbdaab1e7f50fe19f9fa5de 100644 (file)
@@ -431,7 +431,7 @@ static void udivrem96(uint32_t *divident, uint32_t divisor, uint32_t &remainder)
             remainder = 0;
         } else {
             divident[i] = Lo_32(partial_dividend / divisor);
-            remainder = Lo_32(partial_dividend - (divident[i] * divisor));
+            remainder = Lo_32(partial_dividend - ((uint64_t)divident[i] * divisor));
         }
     }
 }
index f8bfdbc8abe730ce10affe0cb8d9c17ae6bd39b9..9edbca2e4006d230c626e812049e30856ac126f3 100644 (file)
@@ -31,7 +31,8 @@ static bool OpenElf(const std::string &file, std::unique_ptr<elf::elf> &ef)
     int fd = open(file.c_str(), O_RDONLY);
     if (fd == -1)
     {
-        LOGI("Load elf failed at file open %s: %s\n", file.c_str(), strerror(errno));
+        char buf[1024];
+        LOGI("Load elf failed at file open %s: %s\n", file.c_str(), ErrGetStr(errno, buf, sizeof(buf)));
         return false;
     }
 
index ef4ba4ec5ca2ea28b2c3f62108b2d07bdb8fa1c1..82cf91de39bb9aa5189fadad7058e4e87390907e 100644 (file)
@@ -846,6 +846,12 @@ static HRESULT LoadLineUpdatesFile(ModulesSources *pModulesSources, const std::s
     };
     std::unordered_map<unsigned /*source fullPathIndex*/, std::vector<line_update_t>> lineUpdatesData;
 
+    // 0xfeefee is a magic number for "#line hidden" directive.
+    // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-line
+    // https://docs.microsoft.com/en-us/archive/blogs/jmstall/line-hidden-and-0xfeefee-sequence-points
+    if (sourcesCount >= 0xfeefee)
+        return E_FAIL;
+
     for (uint32_t i = 0; i < sourcesCount; i++)
     {
         uint32_t stringSize = 0;
index 9ca6fba565a46fccc9f9b888104e67f3b5171187..6d59e6d51bbe8f2ad378b042e445d6269d42a406 100644 (file)
@@ -77,7 +77,7 @@ struct method_data_t_hash
 {
     size_t operator()(const method_data_t &p) const
     {
-        return p.methodDef + (uint32_t)p.startLine * 100 + (uint32_t)p.endLine * 1000;
+        return (size_t)p.methodDef + (size_t)p.startLine * 100 + (size_t)p.endLine * 1000;
     }
 };
 
index 0697c1a1dd8323ec88d3b5ceafded763689bd566..b498420eb0f349ae08bbf1ea3e98c1416d1d1205 100644 (file)
@@ -915,7 +915,8 @@ void CLIProtocol::EmitInteropDebuggingErrorEvent(const int error_n)
 {
     LogFuncEntry();
 
-    printf("Interop debugging disabled due to initialization fail: %s\n", strerror(error_n));
+    char buf[1024];
+    printf("Interop debugging disabled due to initialization fail: %s\n", ErrGetStr(error_n, buf, sizeof(buf)));
 }
 
 // This function implements Debugger interface and called from ManagedDebugger, 
@@ -2098,14 +2099,7 @@ HRESULT CLIProtocol::doCommand<CommandTag::Source>(const std::string &, const st
     {
         output = args[0] + ": ";
         char buf[1024];
-#if defined(_MSC_VER)
-        if (strerror_s(buf, sizeof(buf), errno) == 0)
-            output += buf;
-        else
-            output += "Could not translate errno to a string";
-#else
-        output += strerror_r(errno, buf, sizeof(buf));
-#endif
+        output += ErrGetStr(errno, buf, sizeof(buf));
         return E_FAIL;
     }
 
@@ -2179,14 +2173,7 @@ HRESULT CLIProtocol::doCommand<CommandTag::SaveBreakpoints>(const std::string &,
             {
                 output = filename + ": ";
                 char buf[1024];
-#if defined(_MSC_VER)
-                if (strerror_s(buf, sizeof(buf), errno) == 0)
-                    output += buf;
-                else
-                    output += "Could not translate errno to a string";
-#else
-                output += strerror_r(errno, buf, sizeof(buf));
-#endif
+                output += ErrGetStr(errno, buf, sizeof(buf));
                 result = E_FAIL;
                 return false;
             }
index 44ee84bc75f5f97563450397cc2d64d40aba344c..c5611d300322b462c1bc7f8cebd38f87383a0ee7 100644 (file)
@@ -33,12 +33,14 @@ deftest(escaped_string ../protocols/escaped_string.cpp escaped_string_test.cpp)
 
 deftest(iosystem
     iosystem_test.cpp
+    ${PROJECT_SOURCE_DIR}/src/utils/err_utils.cpp
     ${PROJECT_SOURCE_DIR}/src/utils/iosystem_win32.cpp
     ${PROJECT_SOURCE_DIR}/src/utils/iosystem_unix.cpp
 )
 
 deftest(streams
     streams_test.cpp
+    ${PROJECT_SOURCE_DIR}/src/utils/err_utils.cpp
     ${PROJECT_SOURCE_DIR}/src/utils/streams.cpp
     ${PROJECT_SOURCE_DIR}/src/utils/iosystem_win32.cpp
     ${PROJECT_SOURCE_DIR}/src/utils/iosystem_unix.cpp
@@ -46,6 +48,7 @@ deftest(streams
 
 deftest(ioredirect
     ioredirect_test.cpp
+    ${PROJECT_SOURCE_DIR}/src/utils/err_utils.cpp
     ${PROJECT_SOURCE_DIR}/src/utils/ioredirect.cpp
     ${PROJECT_SOURCE_DIR}/src/utils/streams.cpp
     ${PROJECT_SOURCE_DIR}/src/utils/iosystem_win32.cpp
diff --git a/src/utils/err_utils.cpp b/src/utils/err_utils.cpp
new file mode 100644 (file)
index 0000000..8e779a3
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (C) 2024 Samsung Electronics Co., Ltd.
+// See the LICENSE file in the project root for more information.
+
+#include <stddef.h>
+#include <string.h>
+
+// Same as strerror_r(3) for GNU-specific strerror_r() but for all platforms (Linux, not GNU Linux (musl), Windows, Mac):
+// The GNU-specific strerror_r() returns a pointer to a string containing the error message.
+// This may be either a pointer to a string that the function stores in buf, or a pointer
+// to some (immutable) static string (in which case buf is unused).
+const char *ErrGetStr(int err_code, char buf[], size_t buf_size)
+{
+#ifdef WIN32
+    static const char errStr[] = "Unknown error";
+    bool haveErrorStr = strerror_s(buf, buf_size, err_code) == 0;
+    return haveErrorStr ? buf : errStr;
+#else
+
+#ifdef _GNU_SOURCE
+    return strerror_r(err_code, buf, buf_size);
+#else
+    static const char errStr[] = "Unknown error";
+    bool haveErrorStr = strerror_r(err_code, buf, buf_size) == 0;
+    return haveErrorStr ? buf : errStr;
+#endif //_GNU_SOURCE
+
+#endif //WIN32
+}
index 04831cc34894b74826beca2e688f38235e5fd038..0bf106f9add59a800b070acf73eccbd6a2cf5a14 100644 (file)
@@ -19,6 +19,7 @@
 #include <netinet/in.h>
 #include <stdexcept>
 #include <algorithm>
+#include "utils/logger.h"
 
 #include "iosystem_unix.h"
 
@@ -56,8 +57,9 @@ namespace
                     return {Class::IOResult::Pending, 0};
 
                 // TODO make exception class
+                char buf[1024];
                 char msg[256];
-                snprintf(msg, sizeof(msg), "select: %s", strerror(errno));
+                snprintf(msg, sizeof(msg), "select: %s", ErrGetStr(errno, buf, sizeof(buf)));
                 throw std::runtime_error(msg);
             }
 
@@ -98,8 +100,9 @@ namespace
                 if (errno == EAGAIN)
                     return {Class::IOResult::Pending, 0};
 
+                char buf[1024];
                 char msg[256];
-                snprintf(msg, sizeof(msg), "select: %s", strerror(errno));
+                snprintf(msg, sizeof(msg), "select: %s", ErrGetStr(errno, buf, sizeof(buf)));
                 throw std::runtime_error(msg);
             }
 
@@ -305,8 +308,9 @@ bool Class::async_wait(IOSystem::AsyncHandleIterator begin, IOSystem::AsyncHandl
 
     if (result < 0)
     {
+        char buf[1024];
         char msg[256];
-        snprintf(msg, sizeof(msg), "select: %s", strerror(errno));
+        snprintf(msg, sizeof(msg), "select: %s", ErrGetStr(errno, buf, sizeof(buf)));
         throw std::runtime_error(msg);
     }
 
@@ -369,15 +373,17 @@ Class::StdIOSwap::StdIOSwap(const StdFiles& files) : m_valid(true)
         m_orig_fd[n] = ::dup(oldfd[n]);
         if (m_orig_fd[n] == -1)
         {
+            char buf[1024];
             char msg[256];
-            snprintf(msg, sizeof(msg), "dup(%d): %s", oldfd[n], strerror(errno));
+            snprintf(msg, sizeof(msg), "dup(%d): %s", oldfd[n], ErrGetStr(errno, buf, sizeof(buf)));
             throw std::runtime_error(msg);
         }
 
         if (::dup2(newfd[n], oldfd[n]) == -1)
         {
+            char buf[1024];
             char msg[256];
-            snprintf(msg, sizeof(msg), "dup2(%d, %d): %s", newfd[n], oldfd[n], strerror(errno));
+            snprintf(msg, sizeof(msg), "dup2(%d, %d): %s", newfd[n], oldfd[n], ErrGetStr(errno, buf, sizeof(buf)));
             throw std::runtime_error(msg);
         }
     }
index 9f09e50b6c66572912f8803bd8042de6fb88e3dd..42dd7079db96300dba8cdd7256320e3f6e6ce0bf 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <stddef.h>
 #include <stdarg.h>
+#include <string.h>
 
 #ifdef _MSC_VER
 #include <stdio.h>
@@ -126,6 +127,8 @@ namespace DLogInternal
 #define LOGE(fmt, ...) LOG_(DLOG_ERROR, LOG_TAG, fmt, ##__VA_ARGS__)
 #define LOGF(fmt, ...) LOG_(DLOG_FATAL, LOG_TAG, fmt, ##__VA_ARGS__)
 
+extern const char *ErrGetStr(int err_code, char buf[], size_t buf_size);
+
 // This macro allows to specify priority and a tag. 
 // The macro definition is similar to original from Tizen's dlog.h
 #define LOG(priority, tag, format, ...) LOG_(D##priority, tag, format, ##__VA_ARGS__)