From 5c482bd30da0892749c84643f974f79dfeec6c74 Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 15 Apr 2022 22:57:36 +0800 Subject: [PATCH 01/14] Support ark previewer on windows Signed-off-by: huangyu Change-Id: I7f8a6249066a10fc5b3651b342f4015315567b74 --- runtime/mem/mem_stats.h | 2 +- runtime/mem/mem_stats_additional_info.cpp | 2 +- runtime/mem/mem_stats_additional_info.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/mem/mem_stats.h b/runtime/mem/mem_stats.h index 37f9e80670..b9cdffe525 100644 --- a/runtime/mem/mem_stats.h +++ b/runtime/mem/mem_stats.h @@ -120,7 +120,7 @@ private: duration min_pause_ = duration(0); duration max_pause_ = duration(0); duration sum_pause_ = duration(0); - uint pause_count_ = 0; + uint64_t pause_count_ = 0; // make groups of different parts of the VM (JIT, interpreter, etc) std::atomic_uint64_t objects_allocated_ = 0; diff --git a/runtime/mem/mem_stats_additional_info.cpp b/runtime/mem/mem_stats_additional_info.cpp index 4012f78f81..1a276c5cef 100644 --- a/runtime/mem/mem_stats_additional_info.cpp +++ b/runtime/mem/mem_stats_additional_info.cpp @@ -65,7 +65,7 @@ void MemStatsAdditionalInfo::RecordGCPhaseEnd() os::memory::LockHolder lk(phase_lock_); ASSERT(current_phase_ != GCPhase::GC_PHASE_LAST); - uint phase_index = ToIndex(current_phase_); + uint64_t phase_index = ToIndex(current_phase_); duration phase_time = clock::now() - phase_start_time_; if (phase_count_[phase_index] != 0) { min_phase_time_[phase_index] = std::min(min_phase_time_[phase_index], phase_time); diff --git a/runtime/mem/mem_stats_additional_info.h b/runtime/mem/mem_stats_additional_info.h index 041e5b63d0..6d721c76f7 100644 --- a/runtime/mem/mem_stats_additional_info.h +++ b/runtime/mem/mem_stats_additional_info.h @@ -57,7 +57,7 @@ private: std::array min_phase_time_ = {}; std::array max_phase_time_ = {}; std::array sum_phase_time_ = {}; - std::array phase_count_ = {}; + std::array phase_count_ = {}; os::memory::Mutex phase_lock_; }; -- Gitee From 40446983891b643a12f5d4b57a853d4c03411264 Mon Sep 17 00:00:00 2001 From: huangyu Date: Sat, 16 Apr 2022 00:46:04 +0800 Subject: [PATCH 02/14] Add new files and modify 4 gn to build dll Signed-off-by: huangyu Change-Id: Ia0d134ea4fa06d926c5ee0c4a0229695d31fb48f --- assembler/BUILD.gn | 3 + disassembler/BUILD.gn | 3 + libpandabase/os/failure_retry.h | 39 ++ libpandabase/os/mem_hooks.h | 27 ++ libpandabase/os/mutex.cpp | 205 +++++++++ libpandabase/os/sighook.h | 27 ++ libpandabase/os/unique_fd.h | 102 +++++ libpandabase/os/unix/mem_hooks.cpp | 117 +++++ libpandabase/os/unix/mem_hooks.h | 58 +++ libpandabase/os/unix/sighook.cpp | 499 +++++++++++++++++++++ libpandabase/os/unix/sighook.h | 55 +++ libpandabase/os/windows/library_loader.cpp | 55 +++ libpandabase/os/windows/library_loader.h | 64 +++ libpandabase/os/windows/mem_hooks.cpp | 120 +++++ libpandabase/os/windows/mem_hooks.h | 50 +++ libpandabase/os/windows/sighook.h | 23 + libpandafile/BUILD.gn | 3 + libziparchive/BUILD.gn | 3 + 18 files changed, 1453 insertions(+) create mode 100644 libpandabase/os/failure_retry.h create mode 100644 libpandabase/os/mem_hooks.h create mode 100644 libpandabase/os/mutex.cpp create mode 100644 libpandabase/os/sighook.h create mode 100644 libpandabase/os/unique_fd.h create mode 100644 libpandabase/os/unix/mem_hooks.cpp create mode 100644 libpandabase/os/unix/mem_hooks.h create mode 100644 libpandabase/os/unix/sighook.cpp create mode 100644 libpandabase/os/unix/sighook.h create mode 100644 libpandabase/os/windows/library_loader.cpp create mode 100644 libpandabase/os/windows/library_loader.h create mode 100644 libpandabase/os/windows/mem_hooks.cpp create mode 100644 libpandabase/os/windows/mem_hooks.h create mode 100644 libpandabase/os/windows/sighook.h diff --git a/assembler/BUILD.gn b/assembler/BUILD.gn index d9e3073566..9d02b3ae8a 100644 --- a/assembler/BUILD.gn +++ b/assembler/BUILD.gn @@ -69,6 +69,9 @@ ohos_shared_library("libarkassembler") { relative_install_dir = "ark" } output_extension = "so" + if (is_mingw) { + output_extension = "dll" + } subsystem_name = "ark" part_name = "ark" } diff --git a/disassembler/BUILD.gn b/disassembler/BUILD.gn index d5f47e81ca..aa057920ab 100644 --- a/disassembler/BUILD.gn +++ b/disassembler/BUILD.gn @@ -56,6 +56,9 @@ ohos_shared_library("arkdisassembler") { relative_install_dir = "ark" } output_extension = "so" + if (is_mingw) { + output_extension = "dll" + } subsystem_name = "ark" part_name = "ark" } diff --git a/libpandabase/os/failure_retry.h b/libpandabase/os/failure_retry.h new file mode 100644 index 0000000000..b4cb0593e6 --- /dev/null +++ b/libpandabase/os/failure_retry.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_UNIX_FAILURE_RETRY_H_ +#define PANDA_LIBPANDABASE_OS_UNIX_FAILURE_RETRY_H_ + +#ifdef PANDA_TARGET_UNIX +// Mac Os' libc doesn't have this macro +#ifndef TEMP_FAILURE_RETRY +#define TEMP_FAILURE_RETRY(exp) \ + (__extension__({ \ + decltype(exp) _result; \ + do { \ + _result = (exp); \ + } while (_result == -1 && errno == EINTR); \ + _result; \ + })) +#endif + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define PANDA_FAILURE_RETRY(exp) (__extension__ TEMP_FAILURE_RETRY(exp)) +#else +// Windows Os does not support TEMP_FAILURE_RETRY macro +#define PANDA_FAILURE_RETRY(exp) (exp) +#endif // PANDA_TARGET_UNIX + +#endif // PANDA_LIBPANDABASE_OS_UNIX_FAILURE_RETRY_H_ diff --git a/libpandabase/os/mem_hooks.h b/libpandabase/os/mem_hooks.h new file mode 100644 index 0000000000..036f868324 --- /dev/null +++ b/libpandabase/os/mem_hooks.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_MEM_HOOKS_H_ +#define PANDA_LIBPANDABASE_OS_MEM_HOOKS_H_ + +#ifdef PANDA_TARGET_UNIX +#include "os/unix/mem_hooks.h" +#elif PANDA_TARGET_WINDOWS +#include "os/windows/mem_hooks.h" +#else +#error "Unsupported platform" +#endif + +#endif // PANDA_LIBPANDABASE_OS_MEM_HOOKS_H_ diff --git a/libpandabase/os/mutex.cpp b/libpandabase/os/mutex.cpp new file mode 100644 index 0000000000..929230bee2 --- /dev/null +++ b/libpandabase/os/mutex.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mutex.h" + +#include "utils/logger.h" + +#include + +#include + +namespace panda::os::unix::memory { + +const int64_t MILLISECONDS_PER_SEC = 1000; +const int64_t NANOSECONDS_PER_MILLISEC = 1000000; +const int64_t NANOSECONDS_PER_SEC = 1000000000; + +ALWAYS_INLINE inline void FatalIfError(const char *f, int rc) +{ + if (rc != 0) { + LOG(FATAL, COMMON) << f << " failed: " << Error(rc).ToString(); + } +} + +Mutex::Mutex(bool is_init) : mutex_() +{ + if (is_init) { + Init(nullptr); + } +} + +Mutex::~Mutex() +{ +#ifdef PANDA_TARGET_UNIX + int rc = pthread_mutex_destroy(&mutex_); + FatalIfError("pthread_mutex_destroy", rc); +#endif +} + +void Mutex::Init(pthread_mutexattr_t *attrs) +{ + int rc = pthread_mutex_init(&mutex_, attrs); + FatalIfError("pthread_mutex_init", rc); +} + +void Mutex::Lock() +{ + int rc = pthread_mutex_lock(&mutex_); + FatalIfError("pthread_mutex_lock", rc); +} + +bool Mutex::TryLock() +{ + int rc = pthread_mutex_trylock(&mutex_); + if (rc == EBUSY) { + return false; + } + + FatalIfError("pthread_mutex_trylock", rc); + + return true; +} + +void Mutex::Unlock() +{ + int rc = pthread_mutex_unlock(&mutex_); + FatalIfError("pthread_mutex_unlock", rc); +} + +RecursiveMutex::RecursiveMutex() : Mutex(false) +{ + pthread_mutexattr_t attrs; + pthread_mutexattr_init(&attrs); + pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE); + Init(&attrs); +} + +RWLock::RWLock() : rwlock_() +{ + int rc = pthread_rwlock_init(&rwlock_, nullptr); + FatalIfError("pthread_rwlock_init", rc); +} + +RWLock::~RWLock() +{ + int rc = pthread_rwlock_destroy(&rwlock_); + FatalIfError("pthread_rwlock_destroy", rc); +} + +void RWLock::ReadLock() +{ + int rc = pthread_rwlock_rdlock(&rwlock_); + FatalIfError("pthread_rwlock_rdlock", rc); +} + +void RWLock::WriteLock() +{ + int rc = pthread_rwlock_wrlock(&rwlock_); + FatalIfError("pthread_rwlock_wrlock", rc); +} + +bool RWLock::TryReadLock() +{ + int rc = pthread_rwlock_tryrdlock(&rwlock_); + if (rc == EBUSY) { + return false; + } + + FatalIfError("pthread_rwlock_tryrdlock", rc); + + return true; +} + +bool RWLock::TryWriteLock() +{ + int rc = pthread_rwlock_trywrlock(&rwlock_); + if (rc == EBUSY) { + return false; + } + + FatalIfError("pthread_rwlock_trywrlock", rc); + + return true; +} + +void RWLock::Unlock() +{ + int rc = pthread_rwlock_unlock(&rwlock_); + FatalIfError("pthread_rwlock_unlock", rc); +} + +ConditionVariable::ConditionVariable() : cond_() +{ + int rc = pthread_cond_init(&cond_, nullptr); + FatalIfError("pthread_cond_init", rc); +} + +ConditionVariable::~ConditionVariable() +{ + int rc = pthread_cond_destroy(&cond_); + FatalIfError("pthread_cond_destroy", rc); +} + +void ConditionVariable::Signal() +{ + int rc = pthread_cond_signal(&cond_); + FatalIfError("pthread_cond_signal", rc); +} + +void ConditionVariable::SignalAll() +{ + int rc = pthread_cond_broadcast(&cond_); + FatalIfError("pthread_cond_broadcast", rc); +} + +void ConditionVariable::Wait(Mutex *mutex) +{ + int rc = pthread_cond_wait(&cond_, &mutex->mutex_); + FatalIfError("pthread_cond_wait", rc); +} + +struct timespec ConvertTime(uint64_t ms, uint64_t ns, bool is_absolute) +{ + struct timespec abs_time = {0, 0}; + if (!is_absolute) { + clock_gettime(CLOCK_REALTIME, &abs_time); + } + auto seconds = static_cast(ms / MILLISECONDS_PER_SEC); + auto nanoseconds = static_cast((ms % MILLISECONDS_PER_SEC) * NANOSECONDS_PER_MILLISEC + ns); + abs_time.tv_sec += seconds; + abs_time.tv_nsec += nanoseconds; + if (abs_time.tv_nsec >= NANOSECONDS_PER_SEC) { + abs_time.tv_nsec -= NANOSECONDS_PER_SEC; + abs_time.tv_sec++; + } + return abs_time; +} + +bool ConditionVariable::TimedWait(Mutex *mutex, uint64_t ms, uint64_t ns, bool is_absolute /* = false */) +{ + struct timespec abs_time = ConvertTime(ms, ns, is_absolute); + int rc = pthread_cond_timedwait(&cond_, &mutex->mutex_, &abs_time); + if (rc != 0) { + if (rc == ETIMEDOUT) { + // interrupted + return true; + } + } + FatalIfError("pthread_cond_timedwait", rc); + return false; +} + +} // namespace panda::os::unix::memory diff --git a/libpandabase/os/sighook.h b/libpandabase/os/sighook.h new file mode 100644 index 0000000000..65ccc1e8ca --- /dev/null +++ b/libpandabase/os/sighook.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_SIGHOOK_H_ +#define PANDA_LIBPANDABASE_OS_SIGHOOK_H_ + +#ifdef PANDA_TARGET_UNIX +#include "os/unix/sighook.h" +#elif PANDA_TARGET_WINDOWS +#include "os/windows/sighook.h" +#else +#error "Unsupported platform" +#endif + +#endif // PANDA_LIBPANDABASE_OS_SIGHOOK_H_ diff --git a/libpandabase/os/unique_fd.h b/libpandabase/os/unique_fd.h new file mode 100644 index 0000000000..38f16acaab --- /dev/null +++ b/libpandabase/os/unique_fd.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_UNIQUE_FD_H_ +#define PANDA_LIBPANDABASE_OS_UNIQUE_FD_H_ + +#include +#include "utils/logger.h" +#include "os/failure_retry.h" + +#ifdef PANDA_TARGET_UNIX +#include +#endif + +namespace panda::os::unique_fd { + +class UniqueFd { +public: + explicit UniqueFd(int fd = -1) noexcept + { + Reset(fd); + } + + UniqueFd(const UniqueFd &other_fd) = delete; + UniqueFd &operator=(const UniqueFd &other_fd) = delete; + + UniqueFd(UniqueFd &&other_fd) noexcept + { + Reset(other_fd.Release()); + } + + UniqueFd &operator=(UniqueFd &&other_fd) noexcept + { + Reset(other_fd.Release()); + return *this; + } + + ~UniqueFd() + { + Reset(); + } + + int Release() noexcept + { + int fd = fd_; + fd_ = -1; + return fd; + } + + void Reset(int new_fd = -1) + { + if (fd_ != -1) { + ASSERT(new_fd != fd_); + DefaultCloser(fd_); + } + fd_ = new_fd; + } + + int Get() const noexcept + { + return fd_; + } + + bool IsValid() const noexcept + { + return fd_ != -1; + } + +private: + static void DefaultCloser(int fd) + { + LOG_IF(PANDA_FAILURE_RETRY(::close(fd)) != 0, FATAL, COMMON) << "Incorrect fd: " << fd; + } + + int fd_ = -1; +}; + +inline int DupCloexec([[maybe_unused]] int fd) +{ +#ifdef PANDA_TARGET_UNIX + return fcntl(fd, F_DUPFD_CLOEXEC, 0); +#else + // Unsupported on windows platform + UNREACHABLE(); +#endif +} + +} // namespace panda::os::unique_fd + +#endif // PANDA_LIBPANDABASE_OS_UNIQUE_FD_H_ diff --git a/libpandabase/os/unix/mem_hooks.cpp b/libpandabase/os/unix/mem_hooks.cpp new file mode 100644 index 0000000000..4eba650257 --- /dev/null +++ b/libpandabase/os/unix/mem_hooks.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +#include + +#include "mem_hooks.h" + +namespace panda::os::unix::mem_hooks { + +size_t PandaHooks::alloc_via_standard = 0; +void *(*volatile PandaHooks::old_malloc_hook)(size_t, const void *) = nullptr; +void *(*volatile PandaHooks::old_memalign_hook)(size_t, size_t, const void *) = nullptr; +void (*volatile PandaHooks::old_free_hook)(void *, const void *) = nullptr; + +/* static */ +void PandaHooks::SaveMemHooks() +{ +#ifndef __MUSL__ + old_malloc_hook = __malloc_hook; + old_memalign_hook = __memalign_hook; + old_free_hook = __free_hook; +#endif // __MUSL__ +} + +/* static */ +void PandaHooks::SetMemHooks() +{ +#ifndef __MUSL__ + __malloc_hook = MallocHook; + __memalign_hook = MemalignHook; + __free_hook = FreeHook; +#endif // __MUSL__ +} + +/* static */ +void *PandaHooks::MallocHook(size_t size, [[maybe_unused]] const void *caller) +{ + alloc_via_standard += size; + // tracking internal allocator is implemented by malloc, we would fail here with this option +#ifndef TRACK_INTERNAL_ALLOCATIONS + if (alloc_via_standard > MAX_ALLOC_VIA_STANDARD) { + std::cerr << "Too many usage of standard allocations" << std::endl; + abort(); + } +#endif // TRACK_INTERNAL_ALLOCATIONS + Disable(); + void *result = malloc(size); // NOLINT(cppcoreguidelines-no-malloc) + if (UNLIKELY(result == nullptr)) { + std::cerr << "Malloc error" << std::endl; + abort(); + } + SetMemHooks(); + return result; +} + +/* static */ +void *PandaHooks::MemalignHook(size_t alignment, size_t size, [[maybe_unused]] const void *caller) +{ + alloc_via_standard += size; + // tracking internal allocator is implemented by malloc, we would fail here with this option +#ifndef TRACK_INTERNAL_ALLOCATIONS + if (alloc_via_standard > MAX_ALLOC_VIA_STANDARD) { + std::cerr << "Too many usage of standard allocations" << std::endl; + abort(); + } +#endif // TRACK_INTERNAL_ALLOCATIONS + Disable(); + void *result = memalign(alignment, size); + if (UNLIKELY(result == nullptr)) { + std::cerr << "Align error" << std::endl; + abort(); + } + SetMemHooks(); + return result; +} + +/* static */ +void PandaHooks::FreeHook(void *ptr, [[maybe_unused]] const void *caller) +{ + Disable(); + free(ptr); // NOLINT(cppcoreguidelines-no-malloc) + ptr = nullptr; + SetMemHooks(); +} + +/* static */ +void PandaHooks::Enable() +{ + SaveMemHooks(); + SetMemHooks(); +} + +/* static */ +void PandaHooks::Disable() +{ +#ifndef __MUSL__ + __malloc_hook = old_malloc_hook; + __memalign_hook = old_memalign_hook; + __free_hook = old_free_hook; +#endif // __MUSL__ +} + +} // namespace panda::os::unix::mem_hooks diff --git a/libpandabase/os/unix/mem_hooks.h b/libpandabase/os/unix/mem_hooks.h new file mode 100644 index 0000000000..d1c9260c25 --- /dev/null +++ b/libpandabase/os/unix/mem_hooks.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_UNIX_MEM_HOOKS_H_ +#define PANDA_LIBPANDABASE_OS_UNIX_MEM_HOOKS_H_ + +#include "libpandabase/mem/mem.h" + +namespace panda::os::unix::mem_hooks { + +class PandaHooks { +public: + static void Enable(); + + static void Disable(); + + static size_t GetAllocViaStandard() noexcept + { + return alloc_via_standard; + } + +private: + static constexpr size_t MAX_ALLOC_VIA_STANDARD = 4_MB; + + static void SaveMemHooks(); + + static void SetMemHooks(); + + static void *(*volatile old_malloc_hook)(size_t, const void *); + static void *(*volatile old_memalign_hook)(size_t, size_t, const void *); + static void (*volatile old_free_hook)(void *, const void *); + + static void *MallocHook(size_t size, const void *caller); + static void *MemalignHook(size_t alignment, size_t size, const void *caller); + static void FreeHook(void *ptr, const void *caller); + + static size_t alloc_via_standard; +}; + +} // namespace panda::os::unix::mem_hooks + +namespace panda::os::mem_hooks { +using PandaHooks = panda::os::unix::mem_hooks::PandaHooks; +} // namespace panda::os::mem_hooks + +#endif // PANDA_LIBPANDABASE_OS_UNIX_MEM_HOOKS_H_ diff --git a/libpandabase/os/unix/sighook.cpp b/libpandabase/os/unix/sighook.cpp new file mode 100644 index 0000000000..dcfe2ce09a --- /dev/null +++ b/libpandabase/os/unix/sighook.cpp @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "os/sighook.h" + +#include "utils/logger.h" +#include +#include // NOLINTNEXTLINE(modernize-deprecated-headers) +#include // NOLINTNEXTLINE(modernize-deprecated-headers) +#include // NOLINTNEXTLINE(modernize-deprecated-headers) +#include // NOLINTNEXTLINE(modernize-deprecated-headers) +#include // NOLINTNEXTLINE(modernize-deprecated-headers) +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace panda { + +static decltype(&sigaction) real_sigaction; +static decltype(&sigprocmask) real_sigprocmask; +static bool g_is_init_really {false}; +static bool g_is_init_key_create {false}; +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects) +#if PANDA_TARGET_MACOS +__attribute__((init_priority(101))) static os::memory::Mutex real_lock; +#else +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects) +static os::memory::Mutex real_lock; +#endif +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects) +static os::memory::Mutex key_create_lock; + +static os::memory::PandaThreadKey GetHandlingSignalKey() +{ + static os::memory::PandaThreadKey key; + { + os::memory::LockHolder lock(key_create_lock); + if (!g_is_init_key_create) { + int rc = os::memory::PandaThreadKeyCreate(&key, nullptr); + if (rc != 0) { + LOG(FATAL, RUNTIME) << "Failed to create sigchain thread key: " << os::Error(rc).ToString(); + } + g_is_init_key_create = true; + } + } + return key; +} + +static bool GetHandlingSignal() +{ + void *result = os::memory::PandaGetspecific(GetHandlingSignalKey()); + return reinterpret_cast(result) != 0; +} + +static void SetHandlingSignal(bool value) +{ + os::memory::PandaSetspecific(GetHandlingSignalKey(), reinterpret_cast(static_cast(value))); +} + +class SignalHook { +public: + SignalHook() = default; + + ~SignalHook() = default; + + NO_COPY_SEMANTIC(SignalHook); + NO_MOVE_SEMANTIC(SignalHook); + + bool IsHook() const + { + return is_hook_; + } + + void HookSig(int signo) + { + if (!is_hook_) { + RegisterAction(signo); + is_hook_ = true; + } + } + + void RegisterAction(int signo) + { + struct sigaction handler_action = {}; + sigfillset(&handler_action.sa_mask); + // SIGSEGV from signal handler must be handled as well + sigdelset(&handler_action.sa_mask, SIGSEGV); + + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) + handler_action.sa_sigaction = SignalHook::Handler; + // SA_NODEFER+: do not block signals from the signal handler + // SA_ONSTACK-: call signal handler on the same stack + // NOLINTNEXTLINE(hicpp-signed-bitwise) + handler_action.sa_flags = SA_RESTART | SA_SIGINFO | SA_NODEFER; + real_sigaction(signo, nullptr, &old_action_); + real_sigaction(signo, &handler_action, &user_action_); + } + + void RegisterHookAction(const SighookAction *sa) + { + for (SighookAction &handler : hook_action_handlers_) { + if (handler.sc_sigaction == nullptr) { + handler = *sa; + return; + } + } + LOG(FATAL, RUNTIME) << "Failed to register hook action, too many handlers"; + } + + void RegisterUserAction(const struct sigaction *new_action) + { + user_action_register_ = true; + if constexpr (std::is_same_v) { + user_action_ = *new_action; + } else { + user_action_.sa_flags = new_action->sa_flags; // NOLINT + user_action_.sa_handler = new_action->sa_handler; // NOLINT +#if defined(SA_RESTORER) + user_action_.sa_restorer = new_action->sa_restorer; // NOLINT +#endif + sigemptyset(&user_action_.sa_mask); + (void)memcpy_s(&user_action_.sa_mask, sizeof(user_action_.sa_mask), &new_action->sa_mask, + std::min(sizeof(user_action_.sa_mask), sizeof(new_action->sa_mask))); + } + } + + struct sigaction GetUserAction() const + { + if constexpr (std::is_same_v) { + return user_action_; + } else { + struct sigaction result { + }; + result.sa_flags = user_action_.sa_flags; // NOLINT + result.sa_handler = user_action_.sa_handler; // NOLINT +#if defined(SA_RESTORER) + result.sa_restorer = user_action_.sa_restorer; +#endif + (void)memcpy_s(&result.sa_mask, sizeof(result.sa_mask), &user_action_.sa_mask, + std::min(sizeof(user_action_.sa_mask), sizeof(result.sa_mask))); + return result; + } + } + + static void Handler(int signo, siginfo_t *siginfo, void *ucontext_raw); + static void CallOldAction(int signo, siginfo_t *siginfo, void *ucontext_raw); + + void RemoveHookAction(bool (*action)(int, siginfo_t *, void *)) + { + for (size_t i = 0; i < HOOK_LENGTH; ++i) { + if (hook_action_handlers_[i].sc_sigaction == action) { + for (size_t j = i; j < HOOK_LENGTH - 1; ++j) { + hook_action_handlers_[j] = hook_action_handlers_[j + 1]; + } + hook_action_handlers_[HOOK_LENGTH - 1].sc_sigaction = nullptr; + return; + } + } + LOG(FATAL, RUNTIME) << "Failed to find removed hook handler"; + } + + bool IsUserActionRegister() const + { + return user_action_register_; + } + + void ClearHookActionHandlers() + { + for (SighookAction &handler : hook_action_handlers_) { + handler.sc_sigaction = nullptr; + } + } + +private: + static bool SetHandlingSignal(int signo, siginfo_t *siginfo, void *ucontext_raw); + + constexpr static const int HOOK_LENGTH = 2; + bool is_hook_ {false}; + std::array hook_action_handlers_ {}; + struct sigaction user_action_ { + }; + struct sigaction old_action_ = {}; + bool user_action_register_ {false}; +}; + +static std::array signal_hooks; + +void SignalHook::CallOldAction(int signo, siginfo_t *siginfo, void *ucontext_raw) +{ + auto handler_flags = static_cast(signal_hooks[signo].old_action_.sa_flags); + sigset_t mask = signal_hooks[signo].old_action_.sa_mask; + real_sigprocmask(SIG_SETMASK, &mask, nullptr); + + if ((handler_flags & SA_SIGINFO)) { // NOLINT + signal_hooks[signo].old_action_.sa_sigaction(signo, siginfo, ucontext_raw); // NOLINT + } else { + if (signal_hooks[signo].old_action_.sa_handler == nullptr) { // NOLINT + real_sigaction(signo, &signal_hooks[signo].old_action_, nullptr); + kill(getpid(), signo); // Send signal again + return; + } + signal_hooks[signo].old_action_.sa_handler(signo); // NOLINT + } +} + +bool SignalHook::SetHandlingSignal(int signo, siginfo_t *siginfo, void *ucontext_raw) +{ + for (const auto &handler : signal_hooks[signo].hook_action_handlers_) { + if (handler.sc_sigaction == nullptr) { + break; + } + + bool handler_noreturn = ((handler.sc_flags & SIGHOOK_ALLOW_NORETURN) != 0); + sigset_t previous_mask; + real_sigprocmask(SIG_SETMASK, &handler.sc_mask, &previous_mask); + + bool old_handle_key = GetHandlingSignal(); + if (!handler_noreturn) { + ::panda::SetHandlingSignal(true); + } + if (handler.sc_sigaction(signo, siginfo, ucontext_raw)) { + ::panda::SetHandlingSignal(old_handle_key); + return false; + } + + real_sigprocmask(SIG_SETMASK, &previous_mask, nullptr); + ::panda::SetHandlingSignal(old_handle_key); + } + + return true; +} + +void SignalHook::Handler(int signo, siginfo_t *siginfo, void *ucontext_raw) +{ + if (!GetHandlingSignal()) { + if (!SetHandlingSignal(signo, siginfo, ucontext_raw)) { + return; + } + } + + // If not set user handler, call linker handler + if (!signal_hooks[signo].IsUserActionRegister()) { + CallOldAction(signo, siginfo, ucontext_raw); + return; + } + + // Call user handler + auto handler_flags = static_cast(signal_hooks[signo].user_action_.sa_flags); + auto *ucontext = static_cast(ucontext_raw); + sigset_t mask; + sigemptyset(&mask); + constexpr size_t N = sizeof(sigset_t) * 2; + for (size_t i = 0; i < N; ++i) { + if (sigismember(&ucontext->uc_sigmask, i) == 1 || + sigismember(&signal_hooks[signo].user_action_.sa_mask, i) == 1) { + sigaddset(&mask, i); + } + } + + if ((handler_flags & SA_NODEFER) == 0) { // NOLINT + sigaddset(&mask, signo); + } + real_sigprocmask(SIG_SETMASK, &mask, nullptr); + + if ((handler_flags & SA_SIGINFO)) { // NOLINT + signal_hooks[signo].user_action_.sa_sigaction(signo, siginfo, ucontext_raw); // NOLINT + } else { + auto handler = signal_hooks[signo].user_action_.sa_handler; // NOLINT + if (handler == SIG_IGN) { // NOLINT + return; + } + if (handler == SIG_DFL) { // NOLINT + LOG(FATAL, RUNTIME) << "Actually signal:" << signo << " | register sigaction's handler == SIG_DFL"; + } + handler(signo); + } + + // If user handler does not exit, continue to call Old Action + CallOldAction(signo, siginfo, ucontext_raw); +} + +template +static bool FindRealSignal(Sigaction *real_fun, [[maybe_unused]] Sigaction hook_fun, const char *name) +{ + void *find_fun = dlsym(RTLD_NEXT, name); + if (find_fun != nullptr) { + *real_fun = reinterpret_cast(find_fun); + } else { + find_fun = dlsym(RTLD_DEFAULT, name); + if (find_fun == nullptr || reinterpret_cast(find_fun) == reinterpret_cast(hook_fun) || + reinterpret_cast(find_fun) == reinterpret_cast(sigaction)) { + LOG(ERROR, RUNTIME) << "dlsym(RTLD_DEFAULT, " << name << ") can not find really " << name; + return false; + } + *real_fun = reinterpret_cast(find_fun); + } + LOG(INFO, RUNTIME) << "Find " << name << " success"; + return true; +} + +#if PANDA_TARGET_MACOS +__attribute__((constructor(102))) static bool InitRealSignalFun() +#else +__attribute__((constructor)) static bool InitRealSignalFun() +#endif +{ + { + os::memory::LockHolder lock(real_lock); + if (!g_is_init_really) { + bool is_error = true; + is_error = is_error && FindRealSignal(&real_sigaction, sigaction, "sigaction"); + is_error = is_error && FindRealSignal(&real_sigprocmask, sigprocmask, "sigprocmask"); + if (is_error) { + g_is_init_really = true; + } + return is_error; + } + } + return true; +} + +// NOLINTNEXTLINE(readability-identifier-naming) +static int RegisterUserHandler(int signal, const struct sigaction *new_action, struct sigaction *old_action, + int (*really)(int, const struct sigaction *, struct sigaction *)) +{ + // Just hook signal in range, otherwise use libc sigaction + if (signal <= 0 || signal >= _NSIG) { + LOG(ERROR, RUNTIME) << "Illegal signal " << signal; + return -1; + } + + if (signal_hooks[signal].IsHook()) { + auto user_action = signal_hooks[signal].SignalHook::GetUserAction(); + if (new_action != nullptr) { + signal_hooks[signal].RegisterUserAction(new_action); + } + if (old_action != nullptr) { + *old_action = user_action; + } + return 0; + } + + return really(signal, new_action, old_action); +} + +int RegisterUserMask(int how, const sigset_t *new_set, sigset_t *old_set, + int (*really)(int, const sigset_t *, sigset_t *)) +{ + if (GetHandlingSignal()) { + return really(how, new_set, old_set); + } + + if (new_set == nullptr) { + return really(how, new_set, old_set); + } + + sigset_t build_sigset = *new_set; + if (how == SIG_BLOCK || how == SIG_SETMASK) { + for (int i = 1; i < _NSIG; ++i) { + if (signal_hooks[i].IsHook() && (sigismember(&build_sigset, i) != 0)) { + sigdelset(&build_sigset, i); + } + } + } + const sigset_t *build_sigset_const = &build_sigset; + return really(how, build_sigset_const, old_set); +} + +// NOTE: issue #2681 +// Using ADDRESS_SANITIZER will expose a bug. Try to define 'sigaction' which will make SIGSEGV happen +#ifdef USE_ADDRESS_SANITIZER +// NOLINTNEXTLINE(readability-identifier-naming) +extern "C" int sigaction([[maybe_unused]] int __sig, [[maybe_unused]] const struct sigaction *__restrict __act, + [[maybe_unused]] struct sigaction *__oact) // NOLINT(readability-identifier-naming) +{ + if (!InitRealSignalFun()) { + return -1; + } + return RegisterUserHandler(__sig, __act, __oact, real_sigaction); +} +#else +// NOLINTNEXTLINE(readability-identifier-naming) +extern "C" int sigactionStub([[maybe_unused]] int __sig, [[maybe_unused]] const struct sigaction *__restrict __act, + [[maybe_unused]] struct sigaction *__oact) // NOLINT(readability-identifier-naming) +{ + if (!InitRealSignalFun()) { + return -1; + } + return RegisterUserHandler(__sig, __act, __oact, real_sigaction); +} +#endif // USE_ADDRESS_SANITIZER + +// NOLINTNEXTLINE(readability-identifier-naming) +extern "C" int sigprocmask(int how, const sigset_t *new_set, sigset_t *old_set) // NOLINT +{ + if (!InitRealSignalFun()) { + return -1; + } + return RegisterUserMask(how, new_set, old_set, real_sigprocmask); +} + +extern "C" void RegisterHookHandler(int signal, const SighookAction *sa) +{ + if (!InitRealSignalFun()) { + return; + } + + if (signal <= 0 || signal >= _NSIG) { + LOG(FATAL, RUNTIME) << "Illegal signal " << signal; + } + + signal_hooks[signal].RegisterHookAction(sa); + signal_hooks[signal].HookSig(signal); +} + +extern "C" void RemoveHookHandler(int signal, bool (*action)(int, siginfo_t *, void *)) +{ + if (!InitRealSignalFun()) { + return; + } + + if (signal <= 0 || signal >= _NSIG) { + LOG(FATAL, RUNTIME) << "Illegal signal " << signal; + } + + signal_hooks[signal].RemoveHookAction(action); +} + +extern "C" void CheckOldHookHandler(int signal) +{ + if (!InitRealSignalFun()) { + return; + } + + if (signal <= 0 || signal >= _NSIG) { + LOG(FATAL, RUNTIME) << "Illegal signal " << signal; + } + + // Get old action + struct sigaction old_action { + }; + real_sigaction(signal, nullptr, &old_action); + + if (old_action.sa_sigaction != SignalHook::Handler) { // NOLINT + LOG(ERROR, RUNTIME) << "Error: check old hook handler found unexpected action " + << (old_action.sa_sigaction != nullptr); // NOLINT + signal_hooks[signal].RegisterAction(signal); + } +} + +extern "C" void AddSpecialSignalHandlerFn(int signal, SigchainAction *sa) +{ + LOG(DEBUG, RUNTIME) << "Panda sighook RegisterHookHandler is used, signal:" << signal << " action:" << sa; + RegisterHookHandler(signal, reinterpret_cast(sa)); +} + +extern "C" void RemoveSpecialSignalHandlerFn(int signal, bool (*fn)(int, siginfo_t *, void *)) +{ + LOG(DEBUG, RUNTIME) << "Panda sighook RemoveHookHandler is used, signal:" + << "sigaction"; + RemoveHookHandler(signal, fn); +} + +extern "C" void EnsureFrontOfChain(int signal) +{ + LOG(DEBUG, RUNTIME) << "Panda sighook CheckOldHookHandler is used, signal:" << signal; + CheckOldHookHandler(signal); +} + +void ClearSignalHooksHandlersArray() +{ + g_is_init_really = false; + g_is_init_key_create = false; + for (int i = 1; i < _NSIG; i++) { + signal_hooks[i].ClearHookActionHandlers(); + } +} + +} // namespace panda diff --git a/libpandabase/os/unix/sighook.h b/libpandabase/os/unix/sighook.h new file mode 100644 index 0000000000..e56ae7da83 --- /dev/null +++ b/libpandabase/os/unix/sighook.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_UNIX_SIGHOOK_H_ +#define PANDA_LIBPANDABASE_OS_UNIX_SIGHOOK_H_ + +#include // NOLINTNEXTLINE(modernize-deprecated-headers) +#include // NOLINTNEXTLINE(modernize-deprecated-headers) + +namespace panda { + +#if PANDA_TARGET_MACOS && !defined _NSIG +#define _NSIG NSIG +#endif + +static constexpr uint64_t SIGHOOK_ALLOW_NORETURN = 0x1UL; + +struct SighookAction { + bool (*sc_sigaction)(int, siginfo_t *, void *); + sigset_t sc_mask; + uint64_t sc_flags; +}; + +extern "C" void RegisterHookHandler(int signal, const SighookAction *sa); +extern "C" void RemoveHookHandler(int signal, bool (*action)(int, siginfo_t *, void *)); +extern "C" void CheckOldHookHandler(int signal); +void ClearSignalHooksHandlersArray(); + +// actually use sigchain, here provide sigchain stub to make sure complier success +// the real used function is in libsigchain.a +struct SigchainAction { + bool (*sc_sigaction)(int, siginfo_t *, void *); + sigset_t sc_mask; + uint64_t sc_flags; +}; + +extern "C" void AddSpecialSignalHandlerFn(int signal, SigchainAction *sa); +extern "C" void RemoveSpecialSignalHandlerFn(int signal, bool (*fn)(int, siginfo_t *, void *)); +extern "C" void EnsureFrontOfChain(int signal); + +} // namespace panda + +#endif // PANDA_LIBPANDABASE_OS_UNIX_SIGHOOK_H_ diff --git a/libpandabase/os/windows/library_loader.cpp b/libpandabase/os/windows/library_loader.cpp new file mode 100644 index 0000000000..a9dded0063 --- /dev/null +++ b/libpandabase/os/windows/library_loader.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "os/library_loader.h" + +#include + +namespace panda::os::library_loader { + +Expected Load(std::string_view filename) +{ + HMODULE module = LoadLibrary(filename.data()); + void *handle = reinterpret_cast(module); + if (handle != nullptr) { + return LibraryHandle(handle); + } + return Unexpected(Error(std::string("Failed to load library ") + filename.data() + std::string(", error code ") + + std::to_string(GetLastError()))); +} + +Expected ResolveSymbol(const LibraryHandle &handle, std::string_view name) +{ + HMODULE module = reinterpret_cast(handle.GetNativeHandle()); + void *p = reinterpret_cast(GetProcAddress(module, name.data())); + if (p != nullptr) { + return p; + } + return Unexpected(Error(std::string("Failed to resolve symbol ") + name.data() + std::string(", error code ") + + std::to_string(GetLastError()))); +} + +} // namespace panda::os::library_loader + +namespace panda::os::windows::library_loader { + +LibraryHandle::~LibraryHandle() +{ + if (handle_ != nullptr) { + FreeLibrary(reinterpret_cast(handle_)); + } +} + +} // namespace panda::os::windows::library_loader diff --git a/libpandabase/os/windows/library_loader.h b/libpandabase/os/windows/library_loader.h new file mode 100644 index 0000000000..9a82abc9e4 --- /dev/null +++ b/libpandabase/os/windows/library_loader.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_WINDOWS_LIBRARY_LOADER_H_ +#define PANDA_LIBPANDABASE_OS_WINDOWS_LIBRARY_LOADER_H_ + +#include "macros.h" + +namespace panda::os::windows::library_loader { + +class LibraryHandle { +public: + explicit LibraryHandle(void *handle) : handle_(handle) {} + + LibraryHandle(LibraryHandle &&handle) noexcept + { + handle_ = handle.handle_; + handle.handle_ = nullptr; + } + + LibraryHandle &operator=(LibraryHandle &&handle) noexcept + { + handle_ = handle.handle_; + handle.handle_ = nullptr; + return *this; + } + + bool IsValid() const + { + return handle_ != nullptr; + } + + void *GetNativeHandle() const + { + return handle_; + } + + ~LibraryHandle(); + +private: + void *handle_; + + NO_COPY_SEMANTIC(LibraryHandle); +}; + +} // namespace panda::os::windows::library_loader + +namespace panda::os::library_loader { +using LibraryHandle = panda::os::windows::library_loader::LibraryHandle; +} // namespace panda::os::library_loader + +#endif // PANDA_LIBPANDABASE_OS_WINDOWS_LIBRARY_LOADER_H_ diff --git a/libpandabase/os/windows/mem_hooks.cpp b/libpandabase/os/windows/mem_hooks.cpp new file mode 100644 index 0000000000..48d2bd9c45 --- /dev/null +++ b/libpandabase/os/windows/mem_hooks.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mem_hooks.h" + +#include +#include + +namespace panda::os::windows::mem_hooks { + +volatile bool enable = false; +static bool first = true; + +static const char *GetAllocTypeName(int at) +{ + switch (at) { + case _HOOK_ALLOC: + return "_HOOK_ALLOC"; + case _HOOK_REALLOC: + return "_HOOK_REALLOC"; + case _HOOK_FREE: + return "_HOOK_FREE"; + default: + return "unknown AllocType"; + } +} + +static const char *GetBlockTypeName(int bt) +{ + switch (bt) { + case _CRT_BLOCK: + return "_CRT_BLOCK"; + case _NORMAL_BLOCK: + return "_NORMAL_BLOCK"; + case _FREE_BLOCK: + return "_FREE_BLOCK"; + default: + return "unknown BlockType"; + } +} + +int PandaAllocHook(int alloctype, void *data, std::size_t size, + int blocktype, long request, + const unsigned char *filename, int linenumber) +{ + if (!enable) { + return true; + } + + /* Ignoring internal allocations made by C run-time library functions, + * or else it may trap the program in an endless loop. + */ + if (blocktype == _CRT_BLOCK) { + return true; + } + + constexpr int ALIGN_SIZE = 32; + + if (first) { + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "alloc type"; + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "block type"; + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "size"; + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "filename"; + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << "linenumber" << std::endl; + first = false; + } + + const char* alloctype_name = GetAllocTypeName(alloctype); + const char* blocktype_name = GetBlockTypeName(blocktype); + + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << alloctype_name; + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << blocktype_name; + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << (int)size; + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << filename; + std::cout << std::left << std::setfill(' ') << std::setw(ALIGN_SIZE) << linenumber << std::endl; + + return true; +} + +/* static */ +void PandaHooks::Enable() +{ + enable = true; + + _CrtSetAllocHook(PandaAllocHook); + _CrtMemCheckpoint(&begin); + _CrtMemDumpAllObjectsSince(&begin); + + return; +} + +/* static */ +void PandaHooks::Disable() +{ + enable = false; + + _CrtMemCheckpoint(&end); + _CrtMemDumpAllObjectsSince(&end); + + if (_CrtMemDifference(&out, &begin, &end)) { + std::cerr << "Memory leak detected:" << std::endl; + _CrtDumpMemoryLeaks(); + } + + return; +} + +} // namespace panda::os::windows::mem_hooks diff --git a/libpandabase/os/windows/mem_hooks.h b/libpandabase/os/windows/mem_hooks.h new file mode 100644 index 0000000000..a497462390 --- /dev/null +++ b/libpandabase/os/windows/mem_hooks.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_WINDOWS_MEM_HOOKS_H_ +#define PANDA_LIBPANDABASE_OS_WINDOWS_MEM_HOOKS_H_ + +#include +#include + +namespace panda::os::windows::mem_hooks { + +class PandaHooks { +public: + static void Enable(); + + static void Disable(); + +private: + /* + * "PandaAllocHook" is an allocation hook function, following a prototype described in + * https://docs.microsoft.com/en-us/visualstudio/debugger/allocation-hook-functions. + * Installed it using "_CrtSetAllocHook", then it will be called every time memory is + * allocated, reallocated, or freed. + */ + static int PandaAllocHook(int alloctype, void *data, std::size_t size, + int blocktype, long request, + const unsigned char *filename, int linenumber); + + static _CrtMemState begin, end, out; +}; + +} // namespace panda::os::windows::mem_hooks + +namespace panda::os::mem_hooks { +using PandaHooks = panda::os::windows::mem_hooks::PandaHooks; +} // namespace panda::os::mem_hooks + +#endif // PANDA_LIBPANDABASE_OS_WINDOWS_MEM_HOOKS_H_ diff --git a/libpandabase/os/windows/sighook.h b/libpandabase/os/windows/sighook.h new file mode 100644 index 0000000000..b297935e85 --- /dev/null +++ b/libpandabase/os/windows/sighook.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_WINDOWS_SIGHOOK_H_ +#define PANDA_LIBPANDABASE_OS_WINDOWS_SIGHOOK_H_ + +#ifndef siginfo_t +#define siginfo_t void +#endif + +#endif // PANDA_LIBPANDABASE_OS_WINDOWS_SIGHOOK_H_ diff --git a/libpandafile/BUILD.gn b/libpandafile/BUILD.gn index 7668c90834..fda5097424 100644 --- a/libpandafile/BUILD.gn +++ b/libpandafile/BUILD.gn @@ -79,6 +79,9 @@ ohos_shared_library("libarkfile") { relative_install_dir = "ark" } output_extension = "so" + if (is_mingw) { + output_extension = "dll" + } subsystem_name = "ark" part_name = "ark" } diff --git a/libziparchive/BUILD.gn b/libziparchive/BUILD.gn index c180e40953..8f52906935 100644 --- a/libziparchive/BUILD.gn +++ b/libziparchive/BUILD.gn @@ -53,6 +53,9 @@ ohos_shared_library("libarkziparchive") { relative_install_dir = "ark" } output_extension = "so" + if (is_mingw) { + output_extension = "dll" + } subsystem_name = "ark" part_name = "ark" } -- Gitee From 9874c5f903c8ee9ba87352cd82fb8c5953f48f7e Mon Sep 17 00:00:00 2001 From: huangyu Date: Sat, 16 Apr 2022 10:35:37 +0800 Subject: [PATCH 03/14] Add ARM related changes Signed-off-by: huangyu Change-Id: I63f0bb90217eee118ada6ed88ab11cb52ef4118f --- runtime/arch/amd64/interpreter_support.S | 2 ++ runtime/arch/asm_support.cpp | 2 ++ .../arch/amd64/compiled_code_to_interpreter_bridge_amd64.S | 2 ++ .../amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S | 2 ++ .../bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S | 4 ++++ .../arch/amd64/interpreter_to_compiled_code_bridge_amd64.S | 4 ++++ .../amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S | 4 ++++ 7 files changed, 20 insertions(+) diff --git a/runtime/arch/amd64/interpreter_support.S b/runtime/arch/amd64/interpreter_support.S index 5e3a7888aa..b9867a9c7d 100644 --- a/runtime/arch/amd64/interpreter_support.S +++ b/runtime/arch/amd64/interpreter_support.S @@ -13,7 +13,9 @@ * limitations under the License. */ +#ifndef PANDA_TARGET_WINDOWS .type ExecuteImplStub, @function +#endif .global ExecuteImplStub .balign 16 ExecuteImplStub: diff --git a/runtime/arch/asm_support.cpp b/runtime/arch/asm_support.cpp index 08690cd0c1..0922484a63 100644 --- a/runtime/arch/asm_support.cpp +++ b/runtime/arch/asm_support.cpp @@ -38,10 +38,12 @@ static_assert(FRAME_SLOT_OFFSET == 80U); static_assert(FRAME_TAG_OFFSET == 88U); #endif +#ifndef PANDA_TARGET_WINDOWS extern "C" ManagedThread *GetCurrentThread() { return ManagedThread::GetCurrent(); } +#endif extern "C" void AsmUnreachable() { diff --git a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S index ac09c1abb0..acae8d6d0b 100644 --- a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S +++ b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S @@ -30,7 +30,9 @@ .extern IncrementHotnessCounter .global CompiledCodeToInterpreterBridge +#ifndef PANDA_TARGET_WINDOWS .type CompiledCodeToInterpreterBridge, %function +#endif CompiledCodeToInterpreterBridge: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S index f01a1ded7a..6f3c8fe01a 100644 --- a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S +++ b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S @@ -29,7 +29,9 @@ // CompiledCodeToInterpreterBridgeDyn(Method* method, uint32_t num_args, int64_t func_obj, int64_t func_tag, int64_t arg_i, int64_t tag_i, ...) .global CompiledCodeToInterpreterBridgeDyn +#ifndef PANDA_TARGET_WINDOWS .type CompiledCodeToInterpreterBridgeDyn, %function +#endif CompiledCodeToInterpreterBridgeDyn: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S b/runtime/bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S index ffcef6b6dc..ccb1189820 100644 --- a/runtime/bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S +++ b/runtime/bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S @@ -17,7 +17,9 @@ .macro ENTRYPOINT name, entry, paramsnum .global \name +#ifndef PANDA_TARGET_WINDOWS .type \name, %function +#endif \name: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) @@ -65,7 +67,9 @@ #include "entrypoints_bridge_asm_macro.inl" .global AbstractMethodStub +#ifndef PANDA_TARGET_WINDOWS .type AbstractMethodStub, %function +#endif AbstractMethodStub: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_amd64.S b/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_amd64.S index e706973469..74ed70ce4f 100644 --- a/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_amd64.S +++ b/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_amd64.S @@ -261,7 +261,9 @@ // void InterpreterToCompiledCodeBridge(const BytecodeInstruction* insn, const Frame *iframe, const Method *method, ManagedThread* thread) .global InterpreterToCompiledCodeBridge +#ifndef PANDA_TARGET_WINDOWS .type InterpreterToCompiledCodeBridge, %function +#endif InterpreterToCompiledCodeBridge: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) @@ -450,7 +452,9 @@ InterpreterToCompiledCodeBridge: // DecodedTaggedValue InvokeCompiledCodeWithArguments(const int64_t* args, const Frame *iframe, const Method *method, ManagedThread* thread) .global InvokeCompiledCodeWithArgArray +#ifndef PANDA_TARGET_WINDOWS .type InvokeCompiledCodeWithArgArray, %function +#endif InvokeCompiledCodeWithArgArray: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S b/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S index e85b501dd2..0c898a30b5 100644 --- a/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S +++ b/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S @@ -21,7 +21,9 @@ // const Method*, %rdx // ManagedThread* thread) %rcx .global InterpreterToCompiledCodeBridgeDyn +#ifndef PANDA_TARGET_WINDOWS .type InterpreterToCompiledCodeBridgeDyn, %function +#endif InterpreterToCompiledCodeBridgeDyn: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) @@ -125,7 +127,9 @@ InterpreterToCompiledCodeBridgeDyn: // const Method*, %rcx // ManagedThread* thread) %r8 .global InvokeCompiledCodeWithArgArrayDyn +#ifndef PANDA_TARGET_WINDOWS .type InvokeCompiledCodeWithArgArrayDyn, %function +#endif InvokeCompiledCodeWithArgArrayDyn: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) -- Gitee From 7b50de1d3a67b6ff1ba7900c82c2b089da338659 Mon Sep 17 00:00:00 2001 From: huangyu Date: Sat, 16 Apr 2022 12:10:14 +0800 Subject: [PATCH 04/14] Add pandafile related changes Signed-off-by: huangyu Change-Id: I4aeae195c7071ea99a26a72b35333d5229444f92 --- libpandafile/file.cpp | 29 ++++++++++++++++++++++++++--- libpandafile/file.h | 2 +- libpandafile/file_writer.h | 2 -- libpandafile/panda_cache.h | 35 ++++++++++++++++++++++++++++------- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/libpandafile/file.cpp b/libpandafile/file.cpp index 972e6bfed1..0b78467c57 100644 --- a/libpandafile/file.cpp +++ b/libpandafile/file.cpp @@ -26,9 +26,7 @@ #include "utils/span.h" #include "zip_archive.h" #include "trace/trace.h" -#if !PANDA_TARGET_WINDOWS #include "securec.h" -#endif #include #include @@ -56,6 +54,30 @@ const std::array File::MAGIC {'P', 'A', 'N', 'D', 'A' // NOLINTNEXTLINE(readability-identifier-naming, modernize-avoid-c-arrays) const char *ANONMAPNAME_PERFIX = "panda-"; +os::file::Mode GetMode(panda_file::File::OpenMode open_mode) +{ + os::file::Mode mode; + switch (open_mode) { + case File::READ_WRITE: { + mode = os::file::Mode::READWRITE; + break; + } + case File::READ_ONLY: { + mode = os::file::Mode::READONLY; + break; + } + case File::WRITE_ONLY: { + mode = os::file::Mode::WRITEONLY; + break; + } + default: { + UNREACHABLE(); + break; + } + } + return mode; +} + static uint32_t GetProt(panda_file::File::OpenMode mode) { uint32_t prot = os::mem::MMAP_PROT_READ; @@ -417,7 +439,8 @@ inline std::string VersionToString(const std::array std::unique_ptr File::Open(std::string_view filename, OpenMode open_mode) { trace::ScopedTrace scoped_trace("Open panda file " + std::string(filename)); - os::file::File file = os::file::Open(filename, os::file::Mode::READONLY); + os::file::Mode mode = GetMode(open_mode); + os::file::File file = os::file::Open(filename, mode); if (!file.IsValid()) { PLOG(ERROR, PANDAFILE) << "Failed to open panda file '" << filename << "'"; diff --git a/libpandafile/file.h b/libpandafile/file.h index b3121d553e..004dcb7596 100644 --- a/libpandafile/file.h +++ b/libpandafile/file.h @@ -121,7 +121,7 @@ public: uint32_t offset_ {0}; }; - enum OpenMode { READ_ONLY, READ_WRITE }; + enum OpenMode { READ_ONLY, READ_WRITE, WRITE_ONLY }; StringData GetStringData(EntityId id) const; EntityId GetLiteralArraysId() const; diff --git a/libpandafile/file_writer.h b/libpandafile/file_writer.h index 45e2afbb4b..ef8d39aec4 100644 --- a/libpandafile/file_writer.h +++ b/libpandafile/file_writer.h @@ -20,9 +20,7 @@ #include "utils/span.h" #include "utils/type_helpers.h" #include "utils/leb128.h" -#if !PANDA_TARGET_WINDOWS #include "securec.h" -#endif #include #include diff --git a/libpandafile/panda_cache.h b/libpandafile/panda_cache.h index 420ddd7e60..b27d25d6b7 100644 --- a/libpandafile/panda_cache.h +++ b/libpandafile/panda_cache.h @@ -77,8 +77,10 @@ public: return panda::helpers::math::PowerOfTwoTableSlot(id.GetOffset(), CLASS_CACHE_SIZE); } - inline Method *GetMethodFromCache(File::EntityId id) const + inline Method *GetMethodFromCache([[maybe_unused]] File::EntityId id) const { +// the os platform macro should be removed when "atomic" symbol is provided in mingw +#ifdef PANDA_TARGET_UNIX uint32_t index = GetMethodIndex(id); auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(method_cache_[index]))); @@ -87,11 +89,14 @@ public: if (pair.id_ == id) { return pair.ptr_; } +#endif // PANDA_TARGET_UNIX return nullptr; } - inline void SetMethodCache(File::EntityId id, Method *method) + inline void SetMethodCache([[maybe_unused]] File::EntityId id, [[maybe_unused]] Method *method) { +// the os platform macro should be removed when "atomic" symbol is provided in mingw +#ifdef PANDA_TARGET_UNIX MethodCachePair pair; pair.id_ = id; pair.ptr_ = method; @@ -100,10 +105,13 @@ public: reinterpret_cast *>(reinterpret_cast(&(method_cache_[index]))); TSAN_ANNOTATE_HAPPENS_BEFORE(pair_ptr); pair_ptr->store(pair, std::memory_order_release); +#endif // PANDA_TARGET_UNIX } - inline Field *GetFieldFromCache(File::EntityId id) const + inline Field *GetFieldFromCache([[maybe_unused]] File::EntityId id) const { +// the os platform macro should be removed when "atomic" symbol is provided in mingw +#ifdef PANDA_TARGET_UNIX uint32_t index = GetFieldIndex(id); auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(field_cache_[index]))); @@ -112,11 +120,14 @@ public: if (pair.id_ == id) { return pair.ptr_; } +#endif // PANDA_TARGET_UNIX return nullptr; } - inline void SetFieldCache(File::EntityId id, Field *field) + inline void SetFieldCache([[maybe_unused]] File::EntityId id, [[maybe_unused]] Field *field) { +// the os platform macro should be removed when "atomic" symbol is provided in mingw +#ifdef PANDA_TARGET_UNIX uint32_t index = GetFieldIndex(id); auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(field_cache_[index]))); @@ -125,10 +136,13 @@ public: pair.ptr_ = field; TSAN_ANNOTATE_HAPPENS_BEFORE(pair_ptr); pair_ptr->store(pair, std::memory_order_release); +#endif // PANDA_TARGET_UNIX } - inline Class *GetClassFromCache(File::EntityId id) const + inline Class *GetClassFromCache([[maybe_unused]] File::EntityId id) const { +// the os platform macro should be removed when "atomic" symbol is provided in mingw +#ifdef PANDA_TARGET_UNIX uint32_t index = GetClassIndex(id); auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(class_cache_[index]))); @@ -137,11 +151,14 @@ public: if (pair.id_ == id) { return pair.ptr_; } +#endif // PANDA_TARGET_UNIX return nullptr; } - inline void SetClassCache(File::EntityId id, Class *clazz) + inline void SetClassCache([[maybe_unused]] File::EntityId id, [[maybe_unused]] Class *clazz) { +// the os platform macro should be removed when "atomic" symbol is provided in mingw +#ifdef PANDA_TARGET_UNIX ClassCachePair pair; pair.id_ = id; pair.ptr_ = clazz; @@ -150,11 +167,14 @@ public: reinterpret_cast *>(reinterpret_cast(&(class_cache_[index]))); TSAN_ANNOTATE_HAPPENS_BEFORE(pair_ptr); pair_ptr->store(pair, std::memory_order_release); +#endif // PANDA_TARGET_UNIX } template - bool EnumerateCachedClasses(const Callback &cb) + bool EnumerateCachedClasses([[maybe_unused]] const Callback &cb) { +// the os platform macro should be removed when "atomic" symbol is provided in mingw +#ifdef PANDA_TARGET_UNIX for (uint32_t i = 0; i < CLASS_CACHE_SIZE; i++) { auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(class_cache_[i]))); @@ -166,6 +186,7 @@ public: } } } +#endif // PANDA_TARGET_UNIX return true; } -- Gitee From b70a898ac6f8e57c97a5e76ddd3b7f3b45828f01 Mon Sep 17 00:00:00 2001 From: huangyu Date: Sat, 16 Apr 2022 13:42:25 +0800 Subject: [PATCH 05/14] Check if open mode affect target Signed-off-by: huangyu Change-Id: If872ea46b28777e303757725963b11e90702fe11 --- libpandafile/file.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libpandafile/file.cpp b/libpandafile/file.cpp index 0b78467c57..8bb960c9f5 100644 --- a/libpandafile/file.cpp +++ b/libpandafile/file.cpp @@ -439,8 +439,9 @@ inline std::string VersionToString(const std::array std::unique_ptr File::Open(std::string_view filename, OpenMode open_mode) { trace::ScopedTrace scoped_trace("Open panda file " + std::string(filename)); - os::file::Mode mode = GetMode(open_mode); - os::file::File file = os::file::Open(filename, mode); + os::file::File file = os::file::Open(filename, os::file::Mode::READONLY); + /* os::file::Mode mode = GetMode(open_mode); */ + /* os::file::File file = os::file::Open(filename, mode); */ if (!file.IsValid()) { PLOG(ERROR, PANDAFILE) << "Failed to open panda file '" << filename << "'"; -- Gitee From e5c198d6ad6b97311162f1cc1c72bc2cea9e57b5 Mon Sep 17 00:00:00 2001 From: huangyu Date: Sun, 17 Apr 2022 16:11:37 +0800 Subject: [PATCH 06/14] Add the rest all changes Signed-off-by: huangyu Change-Id: Iffabc3a1deb900c523b2db4969d0ea36a8504748 --- dprof/daemon/main.cpp | 14 +- dprof/libdprof/dprof/ipc/ipc_unix_socket.cpp | 20 +- dprof/libdprof/dprof/ipc/ipc_unix_socket.h | 6 +- dprof/libdprof/dprof/profiling_data.cpp | 2 +- libpandabase/BUILD.gn | 19 +- libpandabase/CMakeLists.txt | 16 +- libpandabase/macros.h | 4 + libpandabase/mem/malloc_mem_pool-inl.h | 8 +- libpandabase/os/dfx_option.h | 7 +- libpandabase/os/filesystem.cpp | 3 + libpandabase/os/filesystem.h | 3 +- libpandabase/os/library_loader.h | 6 +- libpandabase/os/mem.h | 19 +- libpandabase/os/native_stack.h | 4 +- libpandabase/os/thread.h | 10 + libpandabase/os/time.cpp | 49 +- libpandabase/os/time.h | 11 +- libpandabase/os/unix/exec.cpp | 2 +- libpandabase/os/unix/failure_retry.h | 34 -- libpandabase/os/unix/library_loader.h | 4 + libpandabase/os/unix/mem.cpp | 31 +- libpandabase/os/unix/mutex.cpp | 203 -------- libpandabase/os/unix/pipe.cpp | 2 +- libpandabase/os/unix/pipe.h | 4 +- libpandabase/os/unix/sighooklib/sighook.cpp | 499 ------------------- libpandabase/os/unix/sighooklib/sighook.h | 55 -- libpandabase/os/unix/thread.cpp | 42 +- libpandabase/os/unix/time_unix.cpp | 56 --- libpandabase/os/unix/time_unix.h | 39 -- libpandabase/os/unix/unique_fd.h | 94 ---- libpandabase/os/windows/mem.cpp | 84 +++- libpandabase/os/windows/thread.cpp | 32 ++ libpandabase/os/windows/windows_mem.h | 1 + libpandabase/tests/dfx_test.cpp | 11 +- libpandabase/tests/hash_test.cpp | 3 +- libpandabase/tests/mem_range_test.cpp | 10 +- libpandabase/tests/mmap_fixed_test.cpp | 10 +- libpandabase/tests/mmap_mem_pool_test.cpp | 1 - libpandabase/tests/unique_fd_test.cpp | 6 +- runtime/BUILD.gn | 14 +- runtime/CMakeLists.txt | 1 - runtime/dprofiler/dprofiler.h | 8 + runtime/include/runtime.h | 4 +- runtime/interpreter/interpreter-inl.h | 1 - runtime/mem/gc/bitmap.h | 13 +- runtime/mem/malloc-proxy-allocator-inl.h | 6 +- runtime/mem/mem_hooks.cpp | 117 ----- runtime/mem/mem_hooks.h | 54 -- runtime/runtime.cpp | 10 +- runtime/signal_handler.cpp | 3 - runtime/signal_handler.h | 5 + verification/debug/config_load.cpp | 2 - 52 files changed, 327 insertions(+), 1335 deletions(-) delete mode 100644 libpandabase/os/unix/failure_retry.h delete mode 100644 libpandabase/os/unix/mutex.cpp delete mode 100644 libpandabase/os/unix/sighooklib/sighook.cpp delete mode 100644 libpandabase/os/unix/sighooklib/sighook.h delete mode 100644 libpandabase/os/unix/time_unix.cpp delete mode 100644 libpandabase/os/unix/time_unix.h delete mode 100644 libpandabase/os/unix/unique_fd.h delete mode 100644 runtime/mem/mem_hooks.cpp delete mode 100644 runtime/mem/mem_hooks.h diff --git a/dprof/daemon/main.cpp b/dprof/daemon/main.cpp index b7b2dfd9ea..2b1ccc66ae 100644 --- a/dprof/daemon/main.cpp +++ b/dprof/daemon/main.cpp @@ -30,7 +30,7 @@ #include "generated/daemon_options.h" namespace panda::dprof { -bool CheckVersion(const os::unix::UniqueFd &sock) +bool CheckVersion(const os::unique_fd::UniqueFd &sock) { // Get version ipc::Message msg; @@ -54,7 +54,7 @@ bool CheckVersion(const os::unix::UniqueFd &sock) return true; } -static std::unique_ptr ProcessingConnect(const os::unix::UniqueFd &sock) +static std::unique_ptr ProcessingConnect(const os::unique_fd::UniqueFd &sock) { if (!CheckVersion(sock)) { return nullptr; @@ -106,7 +106,7 @@ static std::unique_ptr ProcessingConnect(const os::unix::UniqueFd &sock class Worker { public: - void EnqueueClientSocket(os::unix::UniqueFd clientSock) + void EnqueueClientSocket(os::unique_fd::UniqueFd clientSock) { os::memory::LockHolder lock(queue_lock_); queue_.push(std::move(clientSock)); @@ -130,7 +130,7 @@ public: void DoRun(AppDataStorage *storage) { while (!done_) { - os::unix::UniqueFd clientSock; + os::unique_fd::UniqueFd clientSock; { os::memory::LockHolder lock(queue_lock_); while (queue_.empty() && !done_) { @@ -157,7 +157,7 @@ public: private: std::thread thread_; os::memory::Mutex queue_lock_; - std::queue queue_; + std::queue queue_; os::memory::ConditionVariable cond_ GUARDED_BY(queue_lock_); bool done_ = false; }; @@ -245,7 +245,7 @@ static int Main(panda::Span args) } // Create server socket - os::unix::UniqueFd sock(ipc::CreateUnixServerSocket(MAX_PENDING_CONNECTIONS_QUEUE)); + os::unique_fd::UniqueFd sock(ipc::CreateUnixServerSocket(MAX_PENDING_CONNECTIONS_QUEUE)); if (!sock.IsValid()) { LOG(FATAL, DPROF) << "Cannot create socket"; return -1; @@ -257,7 +257,7 @@ static int Main(panda::Span args) LOG(INFO, DPROF) << "Daemon is ready for connections"; // Main loop while (!g_done) { - os::unix::UniqueFd clientSock(::accept4(sock.Get(), nullptr, nullptr, SOCK_CLOEXEC)); + os::unique_fd::UniqueFd clientSock(::accept4(sock.Get(), nullptr, nullptr, SOCK_CLOEXEC)); if (!clientSock.IsValid()) { if (errno == EINTR) { continue; diff --git a/dprof/libdprof/dprof/ipc/ipc_unix_socket.cpp b/dprof/libdprof/dprof/ipc/ipc_unix_socket.cpp index 8055315d52..e17c7306a7 100644 --- a/dprof/libdprof/dprof/ipc/ipc_unix_socket.cpp +++ b/dprof/libdprof/dprof/ipc/ipc_unix_socket.cpp @@ -15,7 +15,7 @@ #include "ipc_unix_socket.h" -#include "os/unix/failure_retry.h" +#include "os/failure_retry.h" #include "utils/logger.h" #include "securec.h" @@ -29,14 +29,14 @@ namespace panda::dprof::ipc { constexpr char SOCKET_NAME[] = "\0dprof.socket"; // NOLINT(modernize-avoid-c-arrays) static_assert(sizeof(SOCKET_NAME) <= sizeof(static_cast(nullptr)->sun_path), "Socket name too large"); -os::unix::UniqueFd CreateUnixServerSocket(int backlog) +os::unique_fd::UniqueFd CreateUnixServerSocket(int backlog) { - os::unix::UniqueFd sock(PANDA_FAILURE_RETRY(::socket(AF_UNIX, SOCK_STREAM, 0))); + os::unique_fd::UniqueFd sock(PANDA_FAILURE_RETRY(::socket(AF_UNIX, SOCK_STREAM, 0))); int opt = 1; if (PANDA_FAILURE_RETRY(::setsockopt(sock.Get(), SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) == -1) { PLOG(ERROR, DPROF) << "setsockopt() failed"; - return os::unix::UniqueFd(); + return os::unique_fd::UniqueFd(); } struct sockaddr_un serverAddr { @@ -53,23 +53,23 @@ os::unix::UniqueFd CreateUnixServerSocket(int backlog) if (PANDA_FAILURE_RETRY(::bind(sock.Get(), reinterpret_cast(&serverAddr), sizeof(serverAddr))) == -1) { PLOG(ERROR, DPROF) << "bind() failed"; - return os::unix::UniqueFd(); + return os::unique_fd::UniqueFd(); } if (::listen(sock.Get(), backlog) == -1) { PLOG(ERROR, DPROF) << "listen() failed"; - return os::unix::UniqueFd(); + return os::unique_fd::UniqueFd(); } return sock; } -os::unix::UniqueFd CreateUnixClientSocket() +os::unique_fd::UniqueFd CreateUnixClientSocket() { - os::unix::UniqueFd sock(PANDA_FAILURE_RETRY(::socket(AF_UNIX, SOCK_STREAM, 0))); + os::unique_fd::UniqueFd sock(PANDA_FAILURE_RETRY(::socket(AF_UNIX, SOCK_STREAM, 0))); if (!sock.IsValid()) { PLOG(ERROR, DPROF) << "socket() failed"; - return os::unix::UniqueFd(); + return os::unique_fd::UniqueFd(); } struct sockaddr_un serverAddr { @@ -86,7 +86,7 @@ os::unix::UniqueFd CreateUnixClientSocket() if (PANDA_FAILURE_RETRY( ::connect(sock.Get(), reinterpret_cast(&serverAddr), sizeof(serverAddr))) == -1) { PLOG(ERROR, DPROF) << "connect() failed"; - return os::unix::UniqueFd(); + return os::unique_fd::UniqueFd(); } return sock; diff --git a/dprof/libdprof/dprof/ipc/ipc_unix_socket.h b/dprof/libdprof/dprof/ipc/ipc_unix_socket.h index 17b5568089..2e7a1e6dbe 100644 --- a/dprof/libdprof/dprof/ipc/ipc_unix_socket.h +++ b/dprof/libdprof/dprof/ipc/ipc_unix_socket.h @@ -16,11 +16,11 @@ #ifndef PANDA_DPROF_LIBDPROF_DPROF_IPC_IPC_UNIX_SOCKET_H_ #define PANDA_DPROF_LIBDPROF_DPROF_IPC_IPC_UNIX_SOCKET_H_ -#include "os/unix/unique_fd.h" +#include "os/unique_fd.h" namespace panda::dprof::ipc { -os::unix::UniqueFd CreateUnixServerSocket(int backlog); -os::unix::UniqueFd CreateUnixClientSocket(); +os::unique_fd::UniqueFd CreateUnixServerSocket(int backlog); +os::unique_fd::UniqueFd CreateUnixClientSocket(); bool WaitDataTimeout(int fd, int timeoutMs); bool SendAll(int fd, const void *buf, int len); diff --git a/dprof/libdprof/dprof/profiling_data.cpp b/dprof/libdprof/dprof/profiling_data.cpp index 3953d2f5b5..018c82599b 100644 --- a/dprof/libdprof/dprof/profiling_data.cpp +++ b/dprof/libdprof/dprof/profiling_data.cpp @@ -35,7 +35,7 @@ bool ProfilingData::SetFeatureDate(const std::string &featureName, std::vectorGetSize() << " at addr = " << std::hex << arena; arena->~Arena(); -#ifdef PANDA_TARGET_WINDOWS - // std::free can not work with _aligned_malloc. it will lead to some weird crash - _aligned_free(arena); -#else - std::free(arena); // NOLINT(cppcoreguidelines-no-malloc) -#endif - + os::mem::AlignedFree(arena); LOG_MALLOC_MEM_POOL(DEBUG) << "Free arena call finished"; } diff --git a/libpandabase/os/dfx_option.h b/libpandabase/os/dfx_option.h index 474b1cca4c..6cfa126c12 100644 --- a/libpandabase/os/dfx_option.h +++ b/libpandabase/os/dfx_option.h @@ -41,8 +41,9 @@ namespace panda::os::dfx_option { DFX_OPTION_ELEM(D, END_FLAG, "end-flag") #else // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DFX_OPTION_LIST(D) \ - DFX_OPTION_ELEM(D, DFXLOG, "dfx-log") \ +#define DFX_OPTION_LIST(D) \ + DFX_OPTION_ELEM(D, REFERENCE_DUMP, "reference-dump") \ + DFX_OPTION_ELEM(D, DFXLOG, "dfx-log") \ DFX_OPTION_ELEM(D, END_FLAG, "end-flag") #endif // PANDA_TARGET_UNIX @@ -51,7 +52,6 @@ public: enum DfxOptionId : uint8_t { #ifdef PANDA_TARGET_UNIX COMPILER_NULLCHECK_ID, - REFERENCE_DUMP_ID, SIGNAL_CATCHER_ID, SIGNAL_HANDLER_ID, ARK_SIGQUIT_ID, @@ -59,6 +59,7 @@ public: ARK_SIGUSR2_ID, MOBILE_LOG_ID, #endif // PANDA_TARGET_UNIX + REFERENCE_DUMP_ID, DFXLOG_ID, END_FLAG_ID, }; diff --git a/libpandabase/os/filesystem.cpp b/libpandabase/os/filesystem.cpp index fe4c92f8f6..6c6bb124b3 100644 --- a/libpandabase/os/filesystem.cpp +++ b/libpandabase/os/filesystem.cpp @@ -19,6 +19,9 @@ defined PANDA_TARGET_ARM64 #include #endif +#if defined(PANDA_TARGET_WINDOWS) +#include +#endif namespace panda::os { diff --git a/libpandabase/os/filesystem.h b/libpandabase/os/filesystem.h index 6e2ced6a78..36ca777b2e 100644 --- a/libpandabase/os/filesystem.h +++ b/libpandabase/os/filesystem.h @@ -20,7 +20,6 @@ #include #if defined(PANDA_TARGET_WINDOWS) -#include #ifndef NAME_MAX constexpr size_t NAME_MAX = 255; #endif // NAME_MAX @@ -28,7 +27,7 @@ constexpr size_t NAME_MAX = 255; #include #else #include -#endif +#endif // PANDA_TARGET_WINDOWS namespace panda::os { diff --git a/libpandabase/os/library_loader.h b/libpandabase/os/library_loader.h index 456fd85ace..9e60ddf26e 100644 --- a/libpandabase/os/library_loader.h +++ b/libpandabase/os/library_loader.h @@ -18,6 +18,8 @@ #ifdef PANDA_TARGET_UNIX #include "os/unix/library_loader.h" +#elif PANDA_TARGET_WINDOWS +#include "os/windows/library_loader.h" #else #error "Unsupported platform" #endif @@ -29,10 +31,6 @@ namespace panda::os::library_loader { -#ifdef PANDA_TARGET_UNIX -using LibraryHandle = panda::os::unix::library_loader::LibraryHandle; -#endif - Expected Load(std::string_view filename); Expected ResolveSymbol(const LibraryHandle &handle, std::string_view name); diff --git a/libpandabase/os/mem.h b/libpandabase/os/mem.h index 88ee21ecd3..403f7afe59 100644 --- a/libpandabase/os/mem.h +++ b/libpandabase/os/mem.h @@ -40,6 +40,15 @@ namespace panda::os::mem { void MmapDeleter(std::byte *ptr, size_t size) noexcept; +/** + * \brief Make memory region \param mem with size \param size with protection flags \param prot + * @param mem Pointer to memory region (should be aligned to page size) + * @param size Size of memory region + * @param prot Memory protection flags, a combination of MMAP_PROT_XXX values + * @return Error object if any errors occur + */ +std::optional MakeMemWithProtFlag(void *mem, size_t size, int prot); + /** * \brief Make memory region \param mem with size \param size readable and executable * @param mem Pointer to memory region (should be aligned to page size) @@ -72,12 +81,20 @@ std::optional MakeMemReadOnly(void *mem, size_t size); uintptr_t AlignDownToPageSize(uintptr_t addr); /** + * \brief Allocated aligned memory with alignment \param alignment_in_bytes and + * with size \param size. Use AlignedFree to free this memory. * @param alignment_in_bytes - alignment in bytes * @param size - min required size in bytes * @return */ void *AlignedAlloc(size_t alignment_in_bytes, size_t size); +/** + * \brief Free memory, allocated by AlignedAlloc. + * @param mem - Pointer to memory, allocated by AlignedAlloc + */ +void AlignedFree(void *mem); + template class MapRange { public: @@ -348,7 +365,7 @@ inline void ReleasePages([[maybe_unused]] uintptr_t pages_start, [[maybe_unused] #ifdef PANDA_TARGET_UNIX madvise(ToVoidPtr(pages_start), pages_end - pages_start, MADV_DONTNEED); #else - UNREACHABLE(); + // On windows systems we can't do anything #endif } diff --git a/libpandabase/os/native_stack.h b/libpandabase/os/native_stack.h index 8b0ee2d366..694e145f06 100644 --- a/libpandabase/os/native_stack.h +++ b/libpandabase/os/native_stack.h @@ -16,17 +16,19 @@ #ifndef PANDA_LIBPANDABASE_OS_NATIVE_STACK_H_ #define PANDA_LIBPANDABASE_OS_NATIVE_STACK_H_ +#include "os/thread.h" #if defined(PANDA_TARGET_UNIX) #include "os/unix/native_stack.h" #endif // PANDA_TARGET_UNIX + #include #include #include // NOLINTNEXTLINE(modernize-deprecated-headers) namespace panda::os::native_stack { -const auto g_PandaThreadSigmask = pthread_sigmask; // NOLINT(readability-identifier-naming) #if defined(PANDA_TARGET_UNIX) +const auto g_PandaThreadSigmask = pthread_sigmask; // NOLINT(readability-identifier-naming) using DumpUnattachedThread = panda::os::unix::native_stack::DumpUnattachedThread; const auto DumpKernelStack = panda::os::unix::native_stack::DumpKernelStack; // NOLINT(readability-identifier-naming) const auto GetNativeThreadNameForFile = // NOLINT(readability-identifier-naming) diff --git a/libpandabase/os/thread.h b/libpandabase/os/thread.h index 00010fe5c1..eb91e2ed2f 100644 --- a/libpandabase/os/thread.h +++ b/libpandabase/os/thread.h @@ -22,11 +22,13 @@ #include #include #include +#include namespace panda::os::thread { using ThreadId = uint32_t; using native_handle_type = std::thread::native_handle_type; +using HANDLE = void *; ThreadId GetCurrentThreadId(); int SetPriority(int thread_id, int prio); @@ -108,7 +110,11 @@ static void *ProxyFunc(void *args) template native_handle_type ThreadStart(Func *func, Args... args) { +#ifdef PANDA_TARGET_UNIX native_handle_type tid; +#else + pthread_t tid; +#endif auto args_tuple = std::make_tuple(func, std::move(args)...); internal::SharedPtrStruct *ptr = nullptr; { @@ -124,7 +130,11 @@ native_handle_type ThreadStart(Func *func, Args... args) pthread_create(&tid, nullptr, &internal::ProxyFunc::value>, static_cast(ptr)); +#ifdef PANDA_TARGET_UNIX return tid; +#else + return reinterpret_cast(tid); +#endif } } // namespace panda::os::thread diff --git a/libpandabase/os/time.cpp b/libpandabase/os/time.cpp index 8c3173225c..780743ecab 100644 --- a/libpandabase/os/time.cpp +++ b/libpandabase/os/time.cpp @@ -15,21 +15,60 @@ #include "os/time.h" +#include + +#ifdef PANDA_TARGET_WINDOWS +#include +#endif + namespace panda::os::time { -#if !defined(PANDA_TARGET_UNIX) -uint64_t GetClockTimeInMicro() + +#ifdef PANDA_TARGET_UNIX +template +static uint64_t GetClockTime(clockid_t clock) +{ + struct timespec time = {0, 0}; + if (clock_gettime(clock, &time) != -1) { + auto duration = std::chrono::seconds {time.tv_sec} + std::chrono::nanoseconds {time.tv_nsec}; + return std::chrono::duration_cast(duration).count(); + } + return 0; +} +#else +template +static uint64_t GetClockTime(clockid_t clock) { + struct timeval time = {0, 0}; + if (gettimeofday(&time, nullptr) != -1) { + auto duration = std::chrono::seconds {time.tv_sec} + std::chrono::microseconds {time.tv_usec}; + return std::chrono::duration_cast(duration).count(); + } return 0; } +#endif // PANDA_TARGET_UNIX +/** + * Return current time in nanoseconds + */ +uint64_t GetClockTimeInMicro() +{ + return GetClockTime(CLOCK_MONOTONIC); +} + +/** + * Return current time in milliseconds + */ uint64_t GetClockTimeInMilli() { - return 0; + return GetClockTime(CLOCK_MONOTONIC); } +/** + * Return thread CPU time in nanoseconds + */ uint64_t GetClockTimeInThreadCpuTime() { - return 0; + return GetClockTime(CLOCK_THREAD_CPUTIME_ID); } -#endif // PANDA_TARGET_UNIX + } // namespace panda::os::time diff --git a/libpandabase/os/time.h b/libpandabase/os/time.h index 594dd88fc0..f9390ebcb4 100644 --- a/libpandabase/os/time.h +++ b/libpandabase/os/time.h @@ -16,22 +16,13 @@ #ifndef PANDA_LIBPANDABASE_OS_TIME_H_ #define PANDA_LIBPANDABASE_OS_TIME_H_ -#if defined(PANDA_TARGET_UNIX) -#include "os/unix/time_unix.h" -#endif // PANDA_TARGET_UNIX #include namespace panda::os::time { -#if defined(PANDA_TARGET_UNIX) -const auto GetClockTimeInMicro = panda::os::unix::time::GetClockTimeInMicro; // NOLINT(readability-identifier-naming) -const auto GetClockTimeInMilli = panda::os::unix::time::GetClockTimeInMilli; // NOLINT(readability-identifier-naming) -const auto GetClockTimeInThreadCpuTime = // NOLINT(readability-identifier-naming) - panda::os::unix::time::GetClockTimeInThreadCpuTime; -#else + uint64_t GetClockTimeInMicro(); uint64_t GetClockTimeInMilli(); uint64_t GetClockTimeInThreadCpuTime(); -#endif // PANDA_TARGET_UNIX } // namespace panda::os::time diff --git a/libpandabase/os/unix/exec.cpp b/libpandabase/os/unix/exec.cpp index 1bdd8e1bd2..aad9ae5ff6 100644 --- a/libpandabase/os/unix/exec.cpp +++ b/libpandabase/os/unix/exec.cpp @@ -17,7 +17,7 @@ #include #include -#include "os/unix/failure_retry.h" +#include "os/failure_retry.h" #include "sys/wait.h" namespace panda::os::exec { diff --git a/libpandabase/os/unix/failure_retry.h b/libpandabase/os/unix/failure_retry.h deleted file mode 100644 index 011f2fc7f9..0000000000 --- a/libpandabase/os/unix/failure_retry.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PANDA_LIBPANDABASE_OS_UNIX_FAILURE_RETRY_H_ -#define PANDA_LIBPANDABASE_OS_UNIX_FAILURE_RETRY_H_ - -// Mac Os' libc doesn't have this macro -#ifndef TEMP_FAILURE_RETRY -#define TEMP_FAILURE_RETRY(exp) \ - (__extension__({ \ - decltype(exp) _result; \ - do { \ - _result = (exp); \ - } while (_result == -1 && errno == EINTR); \ - _result; \ - })) -#endif - -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define PANDA_FAILURE_RETRY(exp) (__extension__ TEMP_FAILURE_RETRY(exp)) - -#endif // PANDA_LIBPANDABASE_OS_UNIX_FAILURE_RETRY_H_ diff --git a/libpandabase/os/unix/library_loader.h b/libpandabase/os/unix/library_loader.h index 55cc70d0f5..a20f17d773 100644 --- a/libpandabase/os/unix/library_loader.h +++ b/libpandabase/os/unix/library_loader.h @@ -64,4 +64,8 @@ private: } // namespace panda::os::unix::library_loader +namespace panda::os::library_loader { +using LibraryHandle = panda::os::unix::library_loader::LibraryHandle; +} // namespace panda::os::library_loader + #endif // PANDA_LIBPANDABASE_OS_UNIX_LIBRARY_LOADER_H_ diff --git a/libpandabase/os/unix/mem.cpp b/libpandabase/os/unix/mem.cpp index 7b13ecf362..70757b0359 100644 --- a/libpandabase/os/unix/mem.cpp +++ b/libpandabase/os/unix/mem.cpp @@ -65,36 +65,30 @@ BytePtr MapExecuted(size_t size) return BytePtr(static_cast(result), (result == nullptr) ? 0 : size, MmapDeleter); } -std::optional MakeMemReadExec(void *mem, size_t size) +std::optional MakeMemWithProtFlag(void *mem, size_t size, int prot) { - // NOLINTNEXTLINE(hicpp-signed-bitwise) - int r = mprotect(mem, size, PROT_EXEC | PROT_READ); + int r = mprotect(mem, size, prot); if (r != 0) { return Error(errno); } return {}; } -std::optional MakeMemReadWrite(void *mem, size_t size) +std::optional MakeMemReadExec(void *mem, size_t size) { // NOLINTNEXTLINE(hicpp-signed-bitwise) - int r = mprotect(mem, size, PROT_WRITE | PROT_READ); - if (r != 0) { - return Error(errno); - } - - return {}; + return MakeMemWithProtFlag(mem, size, PROT_EXEC | PROT_READ); } -std::optional MakeMemReadOnly(void *mem, size_t size) +std::optional MakeMemReadWrite(void *mem, size_t size) { // NOLINTNEXTLINE(hicpp-signed-bitwise) - int r = mprotect(mem, size, PROT_READ); - if (r != 0) { - return Error(errno); - } + return MakeMemWithProtFlag(mem, size, PROT_WRITE | PROT_READ); +} - return {}; +std::optional MakeMemReadOnly(void *mem, size_t size) +{ + return MakeMemWithProtFlag(mem, size, PROT_READ); } uintptr_t AlignDownToPageSize(uintptr_t addr) @@ -121,6 +115,11 @@ void *AlignedAlloc(size_t alignment_in_bytes, size_t size) return ret; } +void AlignedFree(void *mem) +{ + std::free(mem); // NOLINT(cppcoreguidelines-no-malloc) +} + static uint32_t GetPageSizeFromOs() { // NOLINTNEXTLINE(google-runtime-int) diff --git a/libpandabase/os/unix/mutex.cpp b/libpandabase/os/unix/mutex.cpp deleted file mode 100644 index b98ecad2b8..0000000000 --- a/libpandabase/os/unix/mutex.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "mutex.h" - -#include "utils/logger.h" - -#include - -#include - -namespace panda::os::unix::memory { - -const int64_t MILLISECONDS_PER_SEC = 1000; -const int64_t NANOSECONDS_PER_MILLISEC = 1000000; -const int64_t NANOSECONDS_PER_SEC = 1000000000; - -ALWAYS_INLINE inline void FatalIfError(const char *f, int rc) -{ - if (rc != 0) { - LOG(FATAL, COMMON) << f << " failed: " << Error(rc).ToString(); - } -} - -Mutex::Mutex(bool is_init) : mutex_() -{ - if (is_init) { - Init(nullptr); - } -} - -Mutex::~Mutex() -{ - int rc = pthread_mutex_destroy(&mutex_); - FatalIfError("pthread_mutex_destroy", rc); -} - -void Mutex::Init(pthread_mutexattr_t *attrs) -{ - int rc = pthread_mutex_init(&mutex_, attrs); - FatalIfError("pthread_mutex_init", rc); -} - -void Mutex::Lock() -{ - int rc = pthread_mutex_lock(&mutex_); - FatalIfError("pthread_mutex_lock", rc); -} - -bool Mutex::TryLock() -{ - int rc = pthread_mutex_trylock(&mutex_); - if (rc == EBUSY) { - return false; - } - - FatalIfError("pthread_mutex_trylock", rc); - - return true; -} - -void Mutex::Unlock() -{ - int rc = pthread_mutex_unlock(&mutex_); - FatalIfError("pthread_mutex_unlock", rc); -} - -RecursiveMutex::RecursiveMutex() : Mutex(false) -{ - pthread_mutexattr_t attrs; - pthread_mutexattr_init(&attrs); - pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE); - Init(&attrs); -} - -RWLock::RWLock() : rwlock_() -{ - int rc = pthread_rwlock_init(&rwlock_, nullptr); - FatalIfError("pthread_rwlock_init", rc); -} - -RWLock::~RWLock() -{ - int rc = pthread_rwlock_destroy(&rwlock_); - FatalIfError("pthread_rwlock_destroy", rc); -} - -void RWLock::ReadLock() -{ - int rc = pthread_rwlock_rdlock(&rwlock_); - FatalIfError("pthread_rwlock_rdlock", rc); -} - -void RWLock::WriteLock() -{ - int rc = pthread_rwlock_wrlock(&rwlock_); - FatalIfError("pthread_rwlock_wrlock", rc); -} - -bool RWLock::TryReadLock() -{ - int rc = pthread_rwlock_tryrdlock(&rwlock_); - if (rc == EBUSY) { - return false; - } - - FatalIfError("pthread_rwlock_tryrdlock", rc); - - return true; -} - -bool RWLock::TryWriteLock() -{ - int rc = pthread_rwlock_trywrlock(&rwlock_); - if (rc == EBUSY) { - return false; - } - - FatalIfError("pthread_rwlock_trywrlock", rc); - - return true; -} - -void RWLock::Unlock() -{ - int rc = pthread_rwlock_unlock(&rwlock_); - FatalIfError("pthread_rwlock_unlock", rc); -} - -ConditionVariable::ConditionVariable() : cond_() -{ - int rc = pthread_cond_init(&cond_, nullptr); - FatalIfError("pthread_cond_init", rc); -} - -ConditionVariable::~ConditionVariable() -{ - int rc = pthread_cond_destroy(&cond_); - FatalIfError("pthread_cond_destroy", rc); -} - -void ConditionVariable::Signal() -{ - int rc = pthread_cond_signal(&cond_); - FatalIfError("pthread_cond_signal", rc); -} - -void ConditionVariable::SignalAll() -{ - int rc = pthread_cond_broadcast(&cond_); - FatalIfError("pthread_cond_broadcast", rc); -} - -void ConditionVariable::Wait(Mutex *mutex) -{ - int rc = pthread_cond_wait(&cond_, &mutex->mutex_); - FatalIfError("pthread_cond_wait", rc); -} - -struct timespec ConvertTime(uint64_t ms, uint64_t ns, bool is_absolute) -{ - struct timespec abs_time = {0, 0}; - if (!is_absolute) { - clock_gettime(CLOCK_REALTIME, &abs_time); - } - auto seconds = static_cast(ms / MILLISECONDS_PER_SEC); - auto nanoseconds = static_cast((ms % MILLISECONDS_PER_SEC) * NANOSECONDS_PER_MILLISEC + ns); - abs_time.tv_sec += seconds; - abs_time.tv_nsec += nanoseconds; - if (abs_time.tv_nsec >= NANOSECONDS_PER_SEC) { - abs_time.tv_nsec -= NANOSECONDS_PER_SEC; - abs_time.tv_sec++; - } - return abs_time; -} - -bool ConditionVariable::TimedWait(Mutex *mutex, uint64_t ms, uint64_t ns, bool is_absolute /* = false */) -{ - struct timespec abs_time = ConvertTime(ms, ns, is_absolute); - int rc = pthread_cond_timedwait(&cond_, &mutex->mutex_, &abs_time); - if (rc != 0) { - if (rc == ETIMEDOUT) { - // interrupted - return true; - } - } - FatalIfError("pthread_cond_timedwait", rc); - return false; -} - -} // namespace panda::os::unix::memory diff --git a/libpandabase/os/unix/pipe.cpp b/libpandabase/os/unix/pipe.cpp index efd173fbea..1fd2e788a4 100644 --- a/libpandabase/os/unix/pipe.cpp +++ b/libpandabase/os/unix/pipe.cpp @@ -15,7 +15,7 @@ #include "pipe.h" -#include "failure_retry.h" +#include "os/failure_retry.h" #include #include diff --git a/libpandabase/os/unix/pipe.h b/libpandabase/os/unix/pipe.h index 1c4158bd6d..4467b5581d 100644 --- a/libpandabase/os/unix/pipe.h +++ b/libpandabase/os/unix/pipe.h @@ -16,15 +16,17 @@ #ifndef PANDA_LIBPANDABASE_OS_UNIX_PIPE_H_ #define PANDA_LIBPANDABASE_OS_UNIX_PIPE_H_ -#include "unique_fd.h" #include "utils/expected.h" #include "os/error.h" +#include "os/unique_fd.h" #include #include namespace panda::os::unix { +using UniqueFd = panda::os::unique_fd::UniqueFd; + std::pair CreatePipe(); int SetFdNonblocking(const UniqueFd &fd); diff --git a/libpandabase/os/unix/sighooklib/sighook.cpp b/libpandabase/os/unix/sighooklib/sighook.cpp deleted file mode 100644 index f408f06a62..0000000000 --- a/libpandabase/os/unix/sighooklib/sighook.cpp +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sighook.h" - -#include "utils/logger.h" -#include -#include // NOLINTNEXTLINE(modernize-deprecated-headers) -#include // NOLINTNEXTLINE(modernize-deprecated-headers) -#include // NOLINTNEXTLINE(modernize-deprecated-headers) -#include // NOLINTNEXTLINE(modernize-deprecated-headers) -#include // NOLINTNEXTLINE(modernize-deprecated-headers) -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace panda { - -static decltype(&sigaction) real_sigaction; -static decltype(&sigprocmask) real_sigprocmask; -static bool g_is_init_really {false}; -static bool g_is_init_key_create {false}; -// NOLINTNEXTLINE(fuchsia-statically-constructed-objects) -#if PANDA_TARGET_MACOS -__attribute__((init_priority(101))) static os::memory::Mutex real_lock; -#else -// NOLINTNEXTLINE(fuchsia-statically-constructed-objects) -static os::memory::Mutex real_lock; -#endif -// NOLINTNEXTLINE(fuchsia-statically-constructed-objects) -static os::memory::Mutex key_create_lock; - -static os::memory::PandaThreadKey GetHandlingSignalKey() -{ - static os::memory::PandaThreadKey key; - { - os::memory::LockHolder lock(key_create_lock); - if (!g_is_init_key_create) { - int rc = os::memory::PandaThreadKeyCreate(&key, nullptr); - if (rc != 0) { - LOG(FATAL, RUNTIME) << "Failed to create sigchain thread key: " << os::Error(rc).ToString(); - } - g_is_init_key_create = true; - } - } - return key; -} - -static bool GetHandlingSignal() -{ - void *result = os::memory::PandaGetspecific(GetHandlingSignalKey()); - return reinterpret_cast(result) != 0; -} - -static void SetHandlingSignal(bool value) -{ - os::memory::PandaSetspecific(GetHandlingSignalKey(), reinterpret_cast(static_cast(value))); -} - -class SignalHook { -public: - SignalHook() = default; - - ~SignalHook() = default; - - NO_COPY_SEMANTIC(SignalHook); - NO_MOVE_SEMANTIC(SignalHook); - - bool IsHook() const - { - return is_hook_; - } - - void HookSig(int signo) - { - if (!is_hook_) { - RegisterAction(signo); - is_hook_ = true; - } - } - - void RegisterAction(int signo) - { - struct sigaction handler_action = {}; - sigfillset(&handler_action.sa_mask); - // SIGSEGV from signal handler must be handled as well - sigdelset(&handler_action.sa_mask, SIGSEGV); - - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access) - handler_action.sa_sigaction = SignalHook::Handler; - // SA_NODEFER+: do not block signals from the signal handler - // SA_ONSTACK-: call signal handler on the same stack - // NOLINTNEXTLINE(hicpp-signed-bitwise) - handler_action.sa_flags = SA_RESTART | SA_SIGINFO | SA_NODEFER; - real_sigaction(signo, nullptr, &old_action_); - real_sigaction(signo, &handler_action, &user_action_); - } - - void RegisterHookAction(const SighookAction *sa) - { - for (SighookAction &handler : hook_action_handlers_) { - if (handler.sc_sigaction == nullptr) { - handler = *sa; - return; - } - } - LOG(FATAL, RUNTIME) << "Failed to register hook action, too many handlers"; - } - - void RegisterUserAction(const struct sigaction *new_action) - { - user_action_register_ = true; - if constexpr (std::is_same_v) { - user_action_ = *new_action; - } else { - user_action_.sa_flags = new_action->sa_flags; // NOLINT - user_action_.sa_handler = new_action->sa_handler; // NOLINT -#if defined(SA_RESTORER) - user_action_.sa_restorer = new_action->sa_restorer; // NOLINT -#endif - sigemptyset(&user_action_.sa_mask); - (void)memcpy_s(&user_action_.sa_mask, sizeof(user_action_.sa_mask), &new_action->sa_mask, - std::min(sizeof(user_action_.sa_mask), sizeof(new_action->sa_mask))); - } - } - - struct sigaction GetUserAction() const - { - if constexpr (std::is_same_v) { - return user_action_; - } else { - struct sigaction result { - }; - result.sa_flags = user_action_.sa_flags; // NOLINT - result.sa_handler = user_action_.sa_handler; // NOLINT -#if defined(SA_RESTORER) - result.sa_restorer = user_action_.sa_restorer; -#endif - (void)memcpy_s(&result.sa_mask, sizeof(result.sa_mask), &user_action_.sa_mask, - std::min(sizeof(user_action_.sa_mask), sizeof(result.sa_mask))); - return result; - } - } - - static void Handler(int signo, siginfo_t *siginfo, void *ucontext_raw); - static void CallOldAction(int signo, siginfo_t *siginfo, void *ucontext_raw); - - void RemoveHookAction(bool (*action)(int, siginfo_t *, void *)) - { - for (size_t i = 0; i < HOOK_LENGTH; ++i) { - if (hook_action_handlers_[i].sc_sigaction == action) { - for (size_t j = i; j < HOOK_LENGTH - 1; ++j) { - hook_action_handlers_[j] = hook_action_handlers_[j + 1]; - } - hook_action_handlers_[HOOK_LENGTH - 1].sc_sigaction = nullptr; - return; - } - } - LOG(FATAL, RUNTIME) << "Failed to find removed hook handler"; - } - - bool IsUserActionRegister() const - { - return user_action_register_; - } - - void ClearHookActionHandlers() - { - for (SighookAction &handler : hook_action_handlers_) { - handler.sc_sigaction = nullptr; - } - } - -private: - static bool SetHandlingSignal(int signo, siginfo_t *siginfo, void *ucontext_raw); - - constexpr static const int HOOK_LENGTH = 2; - bool is_hook_ {false}; - std::array hook_action_handlers_ {}; - struct sigaction user_action_ { - }; - struct sigaction old_action_ = {}; - bool user_action_register_ {false}; -}; - -static std::array signal_hooks; - -void SignalHook::CallOldAction(int signo, siginfo_t *siginfo, void *ucontext_raw) -{ - auto handler_flags = static_cast(signal_hooks[signo].old_action_.sa_flags); - sigset_t mask = signal_hooks[signo].old_action_.sa_mask; - real_sigprocmask(SIG_SETMASK, &mask, nullptr); - - if ((handler_flags & SA_SIGINFO)) { // NOLINT - signal_hooks[signo].old_action_.sa_sigaction(signo, siginfo, ucontext_raw); // NOLINT - } else { - if (signal_hooks[signo].old_action_.sa_handler == nullptr) { // NOLINT - real_sigaction(signo, &signal_hooks[signo].old_action_, nullptr); - kill(getpid(), signo); // Send signal again - return; - } - signal_hooks[signo].old_action_.sa_handler(signo); // NOLINT - } -} - -bool SignalHook::SetHandlingSignal(int signo, siginfo_t *siginfo, void *ucontext_raw) -{ - for (const auto &handler : signal_hooks[signo].hook_action_handlers_) { - if (handler.sc_sigaction == nullptr) { - break; - } - - bool handler_noreturn = ((handler.sc_flags & SIGHOOK_ALLOW_NORETURN) != 0); - sigset_t previous_mask; - real_sigprocmask(SIG_SETMASK, &handler.sc_mask, &previous_mask); - - bool old_handle_key = GetHandlingSignal(); - if (!handler_noreturn) { - ::panda::SetHandlingSignal(true); - } - if (handler.sc_sigaction(signo, siginfo, ucontext_raw)) { - ::panda::SetHandlingSignal(old_handle_key); - return false; - } - - real_sigprocmask(SIG_SETMASK, &previous_mask, nullptr); - ::panda::SetHandlingSignal(old_handle_key); - } - - return true; -} - -void SignalHook::Handler(int signo, siginfo_t *siginfo, void *ucontext_raw) -{ - if (!GetHandlingSignal()) { - if (!SetHandlingSignal(signo, siginfo, ucontext_raw)) { - return; - } - } - - // If not set user handler, call linker handler - if (!signal_hooks[signo].IsUserActionRegister()) { - CallOldAction(signo, siginfo, ucontext_raw); - return; - } - - // Call user handler - auto handler_flags = static_cast(signal_hooks[signo].user_action_.sa_flags); - auto *ucontext = static_cast(ucontext_raw); - sigset_t mask; - sigemptyset(&mask); - constexpr size_t N = sizeof(sigset_t) * 2; - for (size_t i = 0; i < N; ++i) { - if (sigismember(&ucontext->uc_sigmask, i) == 1 || - sigismember(&signal_hooks[signo].user_action_.sa_mask, i) == 1) { - sigaddset(&mask, i); - } - } - - if ((handler_flags & SA_NODEFER) == 0) { // NOLINT - sigaddset(&mask, signo); - } - real_sigprocmask(SIG_SETMASK, &mask, nullptr); - - if ((handler_flags & SA_SIGINFO)) { // NOLINT - signal_hooks[signo].user_action_.sa_sigaction(signo, siginfo, ucontext_raw); // NOLINT - } else { - auto handler = signal_hooks[signo].user_action_.sa_handler; // NOLINT - if (handler == SIG_IGN) { // NOLINT - return; - } - if (handler == SIG_DFL) { // NOLINT - LOG(FATAL, RUNTIME) << "Actually signal:" << signo << " | register sigaction's handler == SIG_DFL"; - } - handler(signo); - } - - // If user handler does not exit, continue to call Old Action - CallOldAction(signo, siginfo, ucontext_raw); -} - -template -static bool FindRealSignal(Sigaction *real_fun, [[maybe_unused]] Sigaction hook_fun, const char *name) -{ - void *find_fun = dlsym(RTLD_NEXT, name); - if (find_fun != nullptr) { - *real_fun = reinterpret_cast(find_fun); - } else { - find_fun = dlsym(RTLD_DEFAULT, name); - if (find_fun == nullptr || reinterpret_cast(find_fun) == reinterpret_cast(hook_fun) || - reinterpret_cast(find_fun) == reinterpret_cast(sigaction)) { - LOG(ERROR, RUNTIME) << "dlsym(RTLD_DEFAULT, " << name << ") can not find really " << name; - return false; - } - *real_fun = reinterpret_cast(find_fun); - } - LOG(INFO, RUNTIME) << "Find " << name << " success"; - return true; -} - -#if PANDA_TARGET_MACOS -__attribute__((constructor(102))) static bool InitRealSignalFun() -#else -__attribute__((constructor)) static bool InitRealSignalFun() -#endif -{ - { - os::memory::LockHolder lock(real_lock); - if (!g_is_init_really) { - bool is_error = true; - is_error = is_error && FindRealSignal(&real_sigaction, sigaction, "sigaction"); - is_error = is_error && FindRealSignal(&real_sigprocmask, sigprocmask, "sigprocmask"); - if (is_error) { - g_is_init_really = true; - } - return is_error; - } - } - return true; -} - -// NOLINTNEXTLINE(readability-identifier-naming) -static int RegisterUserHandler(int signal, const struct sigaction *new_action, struct sigaction *old_action, - int (*really)(int, const struct sigaction *, struct sigaction *)) -{ - // Just hook signal in range, otherwise use libc sigaction - if (signal <= 0 || signal >= _NSIG) { - LOG(ERROR, RUNTIME) << "Illegal signal " << signal; - return -1; - } - - if (signal_hooks[signal].IsHook()) { - auto user_action = signal_hooks[signal].SignalHook::GetUserAction(); - if (new_action != nullptr) { - signal_hooks[signal].RegisterUserAction(new_action); - } - if (old_action != nullptr) { - *old_action = user_action; - } - return 0; - } - - return really(signal, new_action, old_action); -} - -int RegisterUserMask(int how, const sigset_t *new_set, sigset_t *old_set, - int (*really)(int, const sigset_t *, sigset_t *)) -{ - if (GetHandlingSignal()) { - return really(how, new_set, old_set); - } - - if (new_set == nullptr) { - return really(how, new_set, old_set); - } - - sigset_t build_sigset = *new_set; - if (how == SIG_BLOCK || how == SIG_SETMASK) { - for (int i = 1; i < _NSIG; ++i) { - if (signal_hooks[i].IsHook() && (sigismember(&build_sigset, i) != 0)) { - sigdelset(&build_sigset, i); - } - } - } - const sigset_t *build_sigset_const = &build_sigset; - return really(how, build_sigset_const, old_set); -} - -// NOTE: issue #2681 -// Using ADDRESS_SANITIZER will expose a bug. Try to define 'sigaction' which will make SIGSEGV happen -#ifdef USE_ADDRESS_SANITIZER -// NOLINTNEXTLINE(readability-identifier-naming) -extern "C" int sigaction([[maybe_unused]] int __sig, [[maybe_unused]] const struct sigaction *__restrict __act, - [[maybe_unused]] struct sigaction *__oact) // NOLINT(readability-identifier-naming) -{ - if (!InitRealSignalFun()) { - return -1; - } - return RegisterUserHandler(__sig, __act, __oact, real_sigaction); -} -#else -// NOLINTNEXTLINE(readability-identifier-naming) -extern "C" int sigactionStub([[maybe_unused]] int __sig, [[maybe_unused]] const struct sigaction *__restrict __act, - [[maybe_unused]] struct sigaction *__oact) // NOLINT(readability-identifier-naming) -{ - if (!InitRealSignalFun()) { - return -1; - } - return RegisterUserHandler(__sig, __act, __oact, real_sigaction); -} -#endif // USE_ADDRESS_SANITIZER - -// NOLINTNEXTLINE(readability-identifier-naming) -extern "C" int sigprocmask(int how, const sigset_t *new_set, sigset_t *old_set) // NOLINT -{ - if (!InitRealSignalFun()) { - return -1; - } - return RegisterUserMask(how, new_set, old_set, real_sigprocmask); -} - -extern "C" void RegisterHookHandler(int signal, const SighookAction *sa) -{ - if (!InitRealSignalFun()) { - return; - } - - if (signal <= 0 || signal >= _NSIG) { - LOG(FATAL, RUNTIME) << "Illegal signal " << signal; - } - - signal_hooks[signal].RegisterHookAction(sa); - signal_hooks[signal].HookSig(signal); -} - -extern "C" void RemoveHookHandler(int signal, bool (*action)(int, siginfo_t *, void *)) -{ - if (!InitRealSignalFun()) { - return; - } - - if (signal <= 0 || signal >= _NSIG) { - LOG(FATAL, RUNTIME) << "Illegal signal " << signal; - } - - signal_hooks[signal].RemoveHookAction(action); -} - -extern "C" void CheckOldHookHandler(int signal) -{ - if (!InitRealSignalFun()) { - return; - } - - if (signal <= 0 || signal >= _NSIG) { - LOG(FATAL, RUNTIME) << "Illegal signal " << signal; - } - - // Get old action - struct sigaction old_action { - }; - real_sigaction(signal, nullptr, &old_action); - - if (old_action.sa_sigaction != SignalHook::Handler) { // NOLINT - LOG(ERROR, RUNTIME) << "Error: check old hook handler found unexpected action " - << (old_action.sa_sigaction != nullptr); // NOLINT - signal_hooks[signal].RegisterAction(signal); - } -} - -extern "C" void AddSpecialSignalHandlerFn(int signal, SigchainAction *sa) -{ - LOG(DEBUG, RUNTIME) << "Panda sighook RegisterHookHandler is used, signal:" << signal << " action:" << sa; - RegisterHookHandler(signal, reinterpret_cast(sa)); -} - -extern "C" void RemoveSpecialSignalHandlerFn(int signal, bool (*fn)(int, siginfo_t *, void *)) -{ - LOG(DEBUG, RUNTIME) << "Panda sighook RemoveHookHandler is used, signal:" - << "sigaction"; - RemoveHookHandler(signal, fn); -} - -extern "C" void EnsureFrontOfChain(int signal) -{ - LOG(DEBUG, RUNTIME) << "Panda sighook CheckOldHookHandler is used, signal:" << signal; - CheckOldHookHandler(signal); -} - -void ClearSignalHooksHandlersArray() -{ - g_is_init_really = false; - g_is_init_key_create = false; - for (int i = 1; i < _NSIG; i++) { - signal_hooks[i].ClearHookActionHandlers(); - } -} - -} // namespace panda diff --git a/libpandabase/os/unix/sighooklib/sighook.h b/libpandabase/os/unix/sighooklib/sighook.h deleted file mode 100644 index 096ea39bb0..0000000000 --- a/libpandabase/os/unix/sighooklib/sighook.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PANDA_LIBPANDABASE_OS_UNIX_SIGHOOKLIB_SIGHOOK_H_ -#define PANDA_LIBPANDABASE_OS_UNIX_SIGHOOKLIB_SIGHOOK_H_ - -#include // NOLINTNEXTLINE(modernize-deprecated-headers) -#include // NOLINTNEXTLINE(modernize-deprecated-headers) - -namespace panda { - -#if PANDA_TARGET_MACOS && !defined _NSIG -#define _NSIG NSIG -#endif - -static constexpr uint64_t SIGHOOK_ALLOW_NORETURN = 0x1UL; - -struct SighookAction { - bool (*sc_sigaction)(int, siginfo_t *, void *); - sigset_t sc_mask; - uint64_t sc_flags; -}; - -extern "C" void RegisterHookHandler(int signal, const SighookAction *sa); -extern "C" void RemoveHookHandler(int signal, bool (*action)(int, siginfo_t *, void *)); -extern "C" void CheckOldHookHandler(int signal); -void ClearSignalHooksHandlersArray(); - -// actually use sigchain, here provide sigchain stub to make sure complier success -// the real used function is in libsigchain.a -struct SigchainAction { - bool (*sc_sigaction)(int, siginfo_t *, void *); - sigset_t sc_mask; - uint64_t sc_flags; -}; - -extern "C" void AddSpecialSignalHandlerFn(int signal, SigchainAction *sa); -extern "C" void RemoveSpecialSignalHandlerFn(int signal, bool (*fn)(int, siginfo_t *, void *)); -extern "C" void EnsureFrontOfChain(int signal); - -} // namespace panda - -#endif // PANDA_LIBPANDABASE_OS_UNIX_SIGHOOKLIB_SIGHOOK_H_ diff --git a/libpandabase/os/unix/thread.cpp b/libpandabase/os/unix/thread.cpp index 87fc09a53b..8c8d82c923 100644 --- a/libpandabase/os/unix/thread.cpp +++ b/libpandabase/os/unix/thread.cpp @@ -16,10 +16,8 @@ #include "os/thread.h" #include -#ifdef PANDA_TARGET_UNIX #include #include -#endif #include namespace panda::os::thread { @@ -33,30 +31,20 @@ ThreadId GetCurrentThreadId() uint64_t tid64; pthread_threadid_np(NULL, &tid64); return static_cast(tid64); -#elif defined(PANDA_TARGET_UNIX) +#else // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) return static_cast(syscall(SYS_gettid)); -#else -#error "Unsupported platform" #endif } int SetPriority(int thread_id, int prio) { -#if defined(PANDA_TARGET_UNIX) return setpriority(PRIO_PROCESS, thread_id, prio); -#else -#error "Unsupported platform" -#endif } int GetPriority(int thread_id) { -#if defined(PANDA_TARGET_UNIX) return getpriority(PRIO_PROCESS, thread_id); -#else -#error "Unsupported platform" -#endif } int SetThreadName(native_handle_type pthread_id, const char *name) @@ -64,65 +52,39 @@ int SetThreadName(native_handle_type pthread_id, const char *name) ASSERT(pthread_id != 0); #if defined(PANDA_TARGET_MACOS) return pthread_setname_np(name); -#elif defined(PANDA_TARGET_UNIX) - return pthread_setname_np(pthread_id, name); #else -#error "Unsupported platform" + return pthread_setname_np(pthread_id, name); #endif } native_handle_type GetNativeHandle() { -#if defined(PANDA_TARGET_UNIX) return pthread_self(); -#else -#error "Unsupported platform" -#endif } void Yield() { -#if defined(PANDA_TARGET_UNIX) std::this_thread::yield(); -#else -#error "Unsupported platform" -#endif } void NativeSleep(unsigned int ms) { -#if defined(PANDA_TARGET_UNIX) std::this_thread::sleep_for(std::chrono::milliseconds(ms)); -#else -#error "Unsupported platform" -#endif } void ThreadDetach(native_handle_type pthread_id) { -#if defined(PANDA_TARGET_UNIX) pthread_detach(pthread_id); -#else -#error "Unsupported platform" -#endif } void ThreadExit(void *retval) { -#if defined(PANDA_TARGET_UNIX) pthread_exit(retval); -#else -#error "Unsupported platform" -#endif } void ThreadJoin(native_handle_type pthread_id, void **retval) { -#if defined(PANDA_TARGET_UNIX) pthread_join(pthread_id, retval); -#else -#error "Unsupported platform" -#endif } } // namespace panda::os::thread diff --git a/libpandabase/os/unix/time_unix.cpp b/libpandabase/os/unix/time_unix.cpp deleted file mode 100644 index 0e687cbb87..0000000000 --- a/libpandabase/os/unix/time_unix.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "time.h" // NOLINTNEXTLINE(modernize-deprecated-headers, hicpp-deprecated-headers) -#include - -namespace panda::os::unix::time { - -template -static uint64_t GetClockTime(clockid_t clock) -{ - struct timespec time = {0, 0}; - if (clock_gettime(clock, &time) != -1) { - auto duration = std::chrono::seconds {time.tv_sec} + std::chrono::nanoseconds {time.tv_nsec}; - return std::chrono::duration_cast(duration).count(); - } - return 0; -} - -/** - * Return current time in nanoseconds - */ -uint64_t GetClockTimeInMicro() -{ - return GetClockTime(CLOCK_MONOTONIC); -} - -/** - * Return current time in milliseconds - */ -uint64_t GetClockTimeInMilli() -{ - return GetClockTime(CLOCK_MONOTONIC); -} - -/** - * Return thread CPU time in nanoseconds - */ -uint64_t GetClockTimeInThreadCpuTime() -{ - return GetClockTime(CLOCK_THREAD_CPUTIME_ID); -} - -} // namespace panda::os::unix::time diff --git a/libpandabase/os/unix/time_unix.h b/libpandabase/os/unix/time_unix.h deleted file mode 100644 index 9560911828..0000000000 --- a/libpandabase/os/unix/time_unix.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PANDA_LIBPANDABASE_OS_UNIX_TIME_UNIX_H_ -#define PANDA_LIBPANDABASE_OS_UNIX_TIME_UNIX_H_ - -#include - -namespace panda::os::unix::time { - -/** - * Return current time in nanoseconds - */ -uint64_t GetClockTimeInMicro(); -/** - * Return current time in milliseconds - */ -uint64_t GetClockTimeInMilli(); - -/** - * Thread Cpu Time in nanoseconds - */ -uint64_t GetClockTimeInThreadCpuTime(); - -} // namespace panda::os::unix::time - -#endif // PANDA_LIBPANDABASE_OS_UNIX_TIME_UNIX_H_ diff --git a/libpandabase/os/unix/unique_fd.h b/libpandabase/os/unix/unique_fd.h deleted file mode 100644 index 3c3533247d..0000000000 --- a/libpandabase/os/unix/unique_fd.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ -#define PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ - -#include -#include -#include "utils/logger.h" -#include "os/unix/failure_retry.h" - -namespace panda::os::unix { - -class UniqueFd { -public: - explicit UniqueFd(int fd = -1) noexcept - { - Reset(fd); - } - - UniqueFd(const UniqueFd &other_fd) = delete; - UniqueFd &operator=(const UniqueFd &other_fd) = delete; - - UniqueFd(UniqueFd &&other_fd) noexcept - { - Reset(other_fd.Release()); - } - - UniqueFd &operator=(UniqueFd &&other_fd) noexcept - { - Reset(other_fd.Release()); - return *this; - } - - ~UniqueFd() - { - Reset(); - } - - int Release() noexcept - { - int fd = fd_; - fd_ = -1; - return fd; - } - - void Reset(int new_fd = -1) - { - if (fd_ != -1) { - ASSERT(new_fd != fd_); - DefaultCloser(fd_); - } - fd_ = new_fd; - } - - int Get() const noexcept - { - return fd_; - } - - bool IsValid() const noexcept - { - return fd_ != -1; - } - -private: - static void DefaultCloser(int fd) - { - LOG_IF(PANDA_FAILURE_RETRY(::close(fd)) != 0, FATAL, COMMON) << "Incorrect fd: " << fd; - } - - int fd_ = -1; -}; - -inline int DupCloexec(int fd) -{ - return fcntl(fd, F_DUPFD_CLOEXEC, 0); -} - -} // namespace panda::os::unix - -#endif // PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ diff --git a/libpandabase/os/windows/mem.cpp b/libpandabase/os/windows/mem.cpp index 850ce2384f..fde47555ed 100644 --- a/libpandabase/os/windows/mem.cpp +++ b/libpandabase/os/windows/mem.cpp @@ -14,7 +14,6 @@ */ #include "os/mem.h" -#include "windows_mem.h" #include "utils/type_helpers.h" #include "utils/asan_interface.h" @@ -24,6 +23,7 @@ #include #include +#include #include #define MAP_FAILED (reinterpret_cast(-1)) @@ -51,7 +51,7 @@ static DWORD mem_protection_flags_for_page(const int prot) return flags; } -static DWORD mem_protection_flags_for_file(const int prot) +static DWORD mem_protection_flags_for_file(const int prot, const uint32_t map_flags) { DWORD flags = 0; @@ -59,6 +59,15 @@ static DWORD mem_protection_flags_for_file(const int prot) return flags; } + /* Notice that only single FILE_MAP_COPY flag can ensure a copy-on-write mapping which + * MMAP_FLAG_PRIVATE needs. It can't be bitwise OR'ed with FLAG_MAP_ALL_ACCESS, FILE_MAP_READ + * or FLAG_MAP_WRITE. Or else it will be converted to PAGE_READONLY or PAGE_READWRITE, and make + * the changes synced back to the original file. + */ + if ((map_flags & MMAP_FLAG_PRIVATE) != 0) { + return FILE_MAP_COPY; + } + if ((static_cast(prot) & MMAP_PROT_READ) != 0) { flags |= FILE_MAP_READ; } @@ -115,7 +124,7 @@ void *mmap([[maybe_unused]] void *addr, size_t len, int prot, uint32_t flags, in return MAP_FAILED; } - const auto prot_file = mem_protection_flags_for_file(prot); + const auto prot_file = mem_protection_flags_for_file(prot, flags); const auto file_off_low = mem_select_lower_bound(off); const auto file_off_high = mem_select_upper_bound(off); void *map = MapViewOfFile(fm, prot_file, file_off_high, file_off_low, len); @@ -158,6 +167,46 @@ BytePtr MapFile(file::File file, uint32_t prot, uint32_t flags, size_t size, siz return BytePtr(static_cast(result) + offset, size, MmapDeleter); } +BytePtr MapExecuted(size_t size) +{ + // By design caller should pass valid size, so don't do any additional checks except ones that + // mmap do itself + // NOLINTNEXTLINE(hicpp-signed-bitwise) + void *result = mmap(nullptr, size, MMAP_PROT_EXEC | MMAP_PROT_WRITE, MMAP_FLAG_SHARED | MMAP_FLAG_ANONYMOUS, -1, 0); + if (result == reinterpret_cast(-1)) { + result = nullptr; + } + + return BytePtr(static_cast(result), (result == nullptr) ? 0 : size, MmapDeleter); +} + +std::optional MakeMemWithProtFlag(void *mem, size_t size, int prot) +{ + PDWORD old = nullptr; + int r = VirtualProtect(mem, size, prot, old); + if (r != 0) { + return Error(GetLastError()); + } + return {}; +} + +std::optional MakeMemReadExec(void *mem, size_t size) +{ + // NOLINTNEXTLINE(hicpp-signed-bitwise) + return MakeMemWithProtFlag(mem, size, MMAP_PROT_EXEC | MMAP_PROT_READ); +} + +std::optional MakeMemReadWrite(void *mem, size_t size) +{ + // NOLINTNEXTLINE(hicpp-signed-bitwise) + return MakeMemWithProtFlag(mem, size, MMAP_PROT_WRITE | MMAP_PROT_READ); +} + +std::optional MakeMemReadOnly(void *mem, size_t size) +{ + return MakeMemWithProtFlag(mem, size, MMAP_PROT_READ); +} + uint32_t GetPageSize() { constexpr size_t PAGE_SIZE = 4096; @@ -194,19 +243,18 @@ void *MapRWAnonymousWithAlignmentRaw(size_t size, size_t aligment_in_bytes, bool uintptr_t aligned_mem = (allocated_mem & ~(aligment_in_bytes - 1U)) + ((allocated_mem % aligment_in_bytes) != 0U ? aligment_in_bytes : 0U); ASSERT(aligned_mem >= allocated_mem); - size_t unused_in_start = aligned_mem - allocated_mem; - ASSERT(unused_in_start <= aligment_in_bytes); - size_t unused_in_end = aligment_in_bytes - unused_in_start; - if (unused_in_start != 0) { - UnmapRaw(result, unused_in_start); - } - if (unused_in_end != 0) { - auto end_part = reinterpret_cast(aligned_mem + size); - UnmapRaw(end_part, unused_in_end); - } return reinterpret_cast(aligned_mem); } +uintptr_t AlignDownToPageSize(uintptr_t addr) +{ + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + const size_t SYS_PAGE_SIZE = sysInfo.dwPageSize; + addr &= ~(SYS_PAGE_SIZE - 1); + return addr; +} + void *AlignedAlloc(size_t alignment_in_bytes, size_t size) { size_t aligned_size = (size + alignment_in_bytes - 1) & ~(alignment_in_bytes - 1); @@ -217,6 +265,11 @@ void *AlignedAlloc(size_t alignment_in_bytes, size_t size) return ret; } +void AlignedFree(void *mem) +{ + _aligned_free(mem); +} + std::optional UnmapRaw(void *mem, size_t size) { ASAN_UNPOISON_MEMORY_REGION(mem, size); @@ -234,4 +287,9 @@ std::optional TagAnonymousMemory([[maybe_unused]] const void *mem, [[mayb return {}; } +size_t GetNativeBytesFromMallinfo() +{ + return DEFAULT_NATIVE_BYTES_FROM_MALLINFO; +} + } // namespace panda::os::mem diff --git a/libpandabase/os/windows/thread.cpp b/libpandabase/os/windows/thread.cpp index 40f3a56b31..1dca1e5559 100644 --- a/libpandabase/os/windows/thread.cpp +++ b/libpandabase/os/windows/thread.cpp @@ -16,6 +16,7 @@ #include "os/thread.h" #include +#include namespace panda::os::thread { @@ -24,4 +25,35 @@ ThreadId GetCurrentThreadId() return static_cast(std::hash()(std::this_thread::get_id())); } +int SetPriority([[maybe_unused]] int thread_id, int prio) +{ + return SetThreadPriority(GetCurrentThread(), prio); +} + +int GetPriority([[maybe_unused]] int thread_id) +{ + return GetThreadPriority(GetCurrentThread()); +} + +int SetThreadName([[maybe_unused]] native_handle_type pthread_id, const char *name) +{ + ASSERT(pthread_id != 0); + return pthread_setname_np(pthread_self(), name); +} + +void Yield() +{ + std::this_thread::yield(); +} + +void NativeSleep(unsigned int ms) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); +} + +void ThreadJoin(native_handle_type pthread_id, void **retval) +{ + pthread_join(reinterpret_cast(pthread_id), retval); +} + } // namespace panda::os::thread diff --git a/libpandabase/os/windows/windows_mem.h b/libpandabase/os/windows/windows_mem.h index 95a051d5c3..e781ed4272 100644 --- a/libpandabase/os/windows/windows_mem.h +++ b/libpandabase/os/windows/windows_mem.h @@ -23,6 +23,7 @@ static constexpr uint32_t MMAP_PROT_READ = 1; static constexpr uint32_t MMAP_PROT_WRITE = 2; static constexpr uint32_t MMAP_PROT_EXEC = 4; +static constexpr uint32_t MMAP_FLAG_SHARED = 1; static constexpr uint32_t MMAP_FLAG_PRIVATE = 2; static constexpr uint32_t MMAP_FLAG_FIXED = 0x10; static constexpr uint32_t MMAP_FLAG_ANONYMOUS = 0x20; diff --git a/libpandabase/tests/dfx_test.cpp b/libpandabase/tests/dfx_test.cpp index 7390dbe104..688c5e55ed 100644 --- a/libpandabase/tests/dfx_test.cpp +++ b/libpandabase/tests/dfx_test.cpp @@ -39,12 +39,15 @@ TEST(DfxController, Initialization) for (auto option = DfxOptionHandler::DfxOption(0); option < DfxOptionHandler::END_FLAG; option = DfxOptionHandler::DfxOption(option + 1)) { switch (option) { +#ifdef PANDA_TARGET_UNIX case DfxOptionHandler::COMPILER_NULLCHECK: option_map[DfxOptionHandler::COMPILER_NULLCHECK] = 1; break; +#endif case DfxOptionHandler::REFERENCE_DUMP: option_map[DfxOptionHandler::REFERENCE_DUMP] = 1; break; +#ifdef PANDA_TARGET_UNIX case DfxOptionHandler::SIGNAL_CATCHER: option_map[DfxOptionHandler::SIGNAL_CATCHER] = 1; break; @@ -63,6 +66,7 @@ TEST(DfxController, Initialization) case DfxOptionHandler::MOBILE_LOG: option_map[DfxOptionHandler::MOBILE_LOG] = 1; break; +#endif case DfxOptionHandler::DFXLOG: option_map[DfxOptionHandler::DFXLOG] = 0; break; @@ -117,17 +121,20 @@ TEST(DfxController, TestPrintDfxOptionValues) #ifdef PANDA_TARGET_UNIX std::string res = helpers::string::Format( "[TID %06x] E/dfx: DFX option: compiler-nullcheck, option values: 1\n" - "[TID %06x] E/dfx: DFX option: reference-dump, option values: 1\n" "[TID %06x] E/dfx: DFX option: signal-catcher, option values: 1\n" "[TID %06x] E/dfx: DFX option: signal-handler, option values: 1\n" "[TID %06x] E/dfx: DFX option: sigquit, option values: 1\n" "[TID %06x] E/dfx: DFX option: sigusr1, option values: 1\n" "[TID %06x] E/dfx: DFX option: sigusr2, option values: 1\n" "[TID %06x] E/dfx: DFX option: mobile-log, option values: 1\n" + "[TID %06x] E/dfx: DFX option: reference-dump, option values: 1\n" "[TID %06x] E/dfx: DFX option: dfx-log, option values: 0\n", tid, tid, tid, tid, tid, tid, tid, tid, tid, tid); #else - std::string res = helpers::string::Format("[TID %06x] E/dfx: DFX option: dfx-log, option values: 0\n", tid, tid); + std::string res = helpers::string::Format( + //TODO(huangyu): check for gtest + "[TID %06x] E/dfx: DFX option: reference-dump, option values: 1\n" + "[TID %06x] E/dfx: DFX option: dfx-log, option values: 0\n", tid, tid, tid); #endif EXPECT_EQ(err, res); diff --git a/libpandabase/tests/hash_test.cpp b/libpandabase/tests/hash_test.cpp index b8b02fe352..b768bbe73d 100644 --- a/libpandabase/tests/hash_test.cpp +++ b/libpandabase/tests/hash_test.cpp @@ -21,7 +21,6 @@ #include "mem/mem.h" #include "os/mem.h" #include "utils/asan_interface.h" -#include namespace panda { @@ -120,7 +119,7 @@ void HashTest::EndOfPageStringHashTest() const constexpr size_t ALLOC_SIZE = PAGE_SIZE * 2; void *mem = panda::os::mem::MapRWAnonymousRaw(ALLOC_SIZE); ASAN_UNPOISON_MEMORY_REGION(mem, ALLOC_SIZE); - mprotect(reinterpret_cast(reinterpret_cast(mem) + PAGE_SIZE), PAGE_SIZE, PROT_NONE); + MakeMemWithProtFlag(reinterpret_cast(reinterpret_cast(mem) + PAGE_SIZE), PAGE_SIZE, PROT_NONE); char *string = reinterpret_cast((reinterpret_cast(mem) + PAGE_SIZE) - sizeof(char) * string_size); string[0] = 'O'; diff --git a/libpandabase/tests/mem_range_test.cpp b/libpandabase/tests/mem_range_test.cpp index ce0584c7ff..726ab944e5 100644 --- a/libpandabase/tests/mem_range_test.cpp +++ b/libpandabase/tests/mem_range_test.cpp @@ -26,8 +26,8 @@ namespace panda::test::mem_range { constexpr uintptr_t MAX_PTR = std::numeric_limits::max(); -constexpr uint NUM_RANDOM_TESTS = 100; -constexpr uint NUM_ITER_PER_TEST = 1000; +constexpr uint64_t NUM_RANDOM_TESTS = 100; +constexpr uint64_t NUM_ITER_PER_TEST = 1000; constexpr uintptr_t RANDOM_AREA_SIZE = 100000; std::default_random_engine g_generator; @@ -133,13 +133,13 @@ TEST(MemRangeTest, IntersectTest) } // function to conduct num_iter random tests with addresses in given bounds -static void randomTestInBounds(uintptr_t from, uintptr_t to, uint num_iter = NUM_ITER_PER_TEST) +static void randomTestInBounds(uintptr_t from, uintptr_t to, uint64_t num_iter = NUM_ITER_PER_TEST) { ASSERT(from < to); panda::mem::MemRange mem_range_1(0, 1), mem_range_2(0, 1); // check intersection via cycle - for (uint iter = 0; iter < num_iter; iter++) { + for (uint64_t iter = 0; iter < num_iter; iter++) { mem_range_1 = randomMemRange(from, to); mem_range_2 = randomMemRange(from, to); @@ -196,7 +196,7 @@ TEST(MemRangeTest, RandomIntersectTest) // tests in random ranges uintptr_t position; - for (uint i = 0; i < NUM_RANDOM_TESTS; i++) { + for (uint64_t i = 0; i < NUM_RANDOM_TESTS; i++) { position = random_uintptr(); if (position > RANDOM_AREA_SIZE) { randomTestInBounds(position - RANDOM_AREA_SIZE, position); diff --git a/libpandabase/tests/mmap_fixed_test.cpp b/libpandabase/tests/mmap_fixed_test.cpp index 9889d60bc6..26ee7d141c 100644 --- a/libpandabase/tests/mmap_fixed_test.cpp +++ b/libpandabase/tests/mmap_fixed_test.cpp @@ -14,12 +14,14 @@ */ #include "os/mem.h" #include "mem/mem.h" -#include #include "utils/asan_interface.h" +#ifdef PANDA_TARGET_WINDOWS +#include "os/windows/mem.cpp" +#endif #include "gtest/gtest.h" -namespace panda { +namespace panda::os::mem { class MMapFixedTest : public testing::Test { protected: @@ -45,7 +47,7 @@ TEST_F(MMapFixedTest, MMapAsanTest) uintptr_t end_addr = panda::os::mem::MMAP_FIXED_MAGIC_ADDR_FOR_ASAN; end_addr = AlignUp(end_addr, sizeof(uint64_t)); void *result = // NOLINTNEXTLINE(hicpp-signed-bitwise) - mmap(ToVoidPtr(cur_addr), MMAP_ALLOC_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, + mmap(ToVoidPtr(cur_addr), MMAP_ALLOC_SIZE, MMAP_PROT_READ | MMAP_PROT_WRITE, MMAP_FLAG_PRIVATE | MMAP_FLAG_ANONYMOUS | MMAP_FLAG_FIXED, -1, 0); ASSERT_TRUE(result != nullptr); ASSERT_TRUE(ToUintPtr(result) == cur_addr); @@ -63,4 +65,4 @@ TEST_F(MMapFixedTest, MMapAsanTest) munmap(result, MMAP_ALLOC_SIZE); } -} // namespace panda +} // namespace panda::os::mem diff --git a/libpandabase/tests/mmap_mem_pool_test.cpp b/libpandabase/tests/mmap_mem_pool_test.cpp index dbe3e6516b..d3f6437178 100644 --- a/libpandabase/tests/mmap_mem_pool_test.cpp +++ b/libpandabase/tests/mmap_mem_pool_test.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ #include "mem/mem.h" -#include #include "mem/mmap_mem_pool-inl.h" #include "gtest/gtest.h" diff --git a/libpandabase/tests/unique_fd_test.cpp b/libpandabase/tests/unique_fd_test.cpp index bf39749eea..79bbf1587d 100644 --- a/libpandabase/tests/unique_fd_test.cpp +++ b/libpandabase/tests/unique_fd_test.cpp @@ -13,13 +13,13 @@ * limitations under the License. */ -#include "os/unix/unique_fd.h" +#include "os/unique_fd.h" #include #include #include -namespace panda::os::unix { +namespace panda::os::unique_fd { enum testValue { DEFAULT_VALUE = -1, STDIN_VALUE, STDOUT_VALUE, STDERR_VALUE }; @@ -132,4 +132,4 @@ TEST(UniqueFd, Reset) EXPECT_EQ(fd_d.Get(), dupDF.stferrValue); } -} // namespace panda::os::unix +} // namespace panda::os::unique_fd diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn index 4f259c25a4..c5637a16b9 100644 --- a/runtime/BUILD.gn +++ b/runtime/BUILD.gn @@ -76,7 +76,6 @@ ohos_static_library("libarkruntime_static") { "class_linker_extension.cpp", "coretypes/array.cpp", "coretypes/string.cpp", - "dprofiler/dprofiler.cpp", "dyn_class_linker_extension.cpp", "entrypoints/entrypoints.cpp", "exceptions.cpp", @@ -118,7 +117,6 @@ ohos_static_library("libarkruntime_static") { "mem/heap_manager.cpp", "mem/heap_verifier.cpp", "mem/internal_allocator.cpp", - "mem/mem_hooks.cpp", "mem/mem_stats.cpp", "mem/mem_stats_additional_info.cpp", "mem/mem_stats_default.cpp", @@ -141,7 +139,6 @@ ohos_static_library("libarkruntime_static") { "panda_vm.cpp", "runtime.cpp", "runtime_helpers.cpp", - "signal_handler.cpp", "stack_walker.cpp", "string_table.cpp", "thread.cpp", @@ -157,6 +154,12 @@ ohos_static_library("libarkruntime_static") { "tooling/pt_thread.cpp", "vtable_builder.cpp", ] + if (!is_mingw) { + sources += [ + "dprofiler/dprofiler.cpp", + "signal_handler.cpp", + ] + } if (current_cpu == "arm") { sources += [ "arch/arm/interpreter_support.S", @@ -228,7 +231,6 @@ ohos_static_library("libarkruntime_static") { deps = [ ":arkruntime_header_deps", ":arkruntime_interpreter_impl", - "$ark_root/dprof:libdprof", "$ark_root/libpandabase:libarkbase", "$ark_root/libpandafile:libarkfile", "$ark_root/libpandafile:libarkfile_type_gen_h", @@ -237,6 +239,10 @@ ohos_static_library("libarkruntime_static") { sdk_libc_secshared_dep, ] + if (!is_mingw) { + deps += [ "$ark_root/dprof:libdprof" ] + } + if (is_standard_system) { cflags_cc = [ "-fvisibility=hidden" ] } diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index a5bb82fc21..23c744dd22 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -107,7 +107,6 @@ set(SOURCES mem/mem_stats.cpp mem/internal_allocator.cpp mem/panda_string.cpp - mem/mem_hooks.cpp mem/memory_manager.cpp mark_word.cpp method.cpp diff --git a/runtime/dprofiler/dprofiler.h b/runtime/dprofiler/dprofiler.h index 0a2f2dc0f8..bb1ea09928 100644 --- a/runtime/dprofiler/dprofiler.h +++ b/runtime/dprofiler/dprofiler.h @@ -38,7 +38,15 @@ class RuntimeListener; */ class DProfiler final { public: +#ifdef PANDA_TARGET_UNIX DProfiler(std::string_view app_name, Runtime *runtime); +#else + DProfiler([[maybe_unused]] std::string_view app_name, [[maybe_unused]] Runtime *runtime) + { + // Unsupported on windows platform + UNREACHABLE(); + } +#endif // PANDA_TARGET_UNIX ~DProfiler() = default; /** diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index 3d9a494e17..a4e1e25d72 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -24,7 +24,6 @@ #include "libpandabase/mem/arena_allocator.h" #include "libpandabase/os/mutex.h" -#include "libpandabase/os/library_loader.h" #include "libpandabase/utils/expected.h" #include "libpandabase/utils/dfx.h" #include "libpandafile/file_items.h" @@ -43,6 +42,7 @@ #include "runtime/string_table.h" #include "runtime/thread_manager.h" #include "verification/verification_options.h" +#include "libpandabase/os/library_loader.h" namespace panda { @@ -312,7 +312,7 @@ public: return signal_manager_; } - Trace *CreateTrace(LanguageContext ctx, PandaUniquePtr trace_file, size_t buffer_size); + Trace *CreateTrace(LanguageContext ctx, PandaUniquePtr trace_file, size_t buffer_size); void SetPtLangExt(tooling::PtLangExt *pt_lang_ext); diff --git a/runtime/interpreter/interpreter-inl.h b/runtime/interpreter/interpreter-inl.h index 4f232464a0..bc5d356133 100644 --- a/runtime/interpreter/interpreter-inl.h +++ b/runtime/interpreter/interpreter-inl.h @@ -58,7 +58,6 @@ #include "runtime/interpreter/vregister_iterator.h" #include "runtime/jit/profiling_data.h" #include "runtime/mem/vm_handle.h" -#include "runtime/object_accessor-impl.cpp" #include "runtime/handle_base-inl.h" // ALWAYS_INLINE is mandatory attribute for handlers. There are cases which will be failed without it. diff --git a/runtime/mem/gc/bitmap.h b/runtime/mem/gc/bitmap.h index 8adb635a75..6c249eadc7 100644 --- a/runtime/mem/gc/bitmap.h +++ b/runtime/mem/gc/bitmap.h @@ -16,10 +16,7 @@ #ifndef PANDA_RUNTIME_MEM_GC_BITMAP_H_ #define PANDA_RUNTIME_MEM_GC_BITMAP_H_ -// clash with mingw -#ifndef PANDA_TARGET_WINDOWS #include -#endif #include #include #include @@ -46,9 +43,7 @@ public: void ClearAllBits() { -#ifndef PANDA_TARGET_WINDOWS (void)memset_s(bitmap_.Data(), bitmap_.SizeBytes(), 0, bitmap_.SizeBytes()); -#endif } Span GetBitMap() @@ -242,13 +237,11 @@ protected: void SetWords([[maybe_unused]] size_t word_begin, [[maybe_unused]] size_t word_end) { ASSERT(word_begin <= word_end); -#ifndef PANDA_TARGET_WINDOWS if (UNLIKELY(word_begin == word_end)) { return; } (void)memset_s(&bitmap_[word_begin], (word_end - word_begin) * sizeof(BitmapWordType), ~static_cast(0), (word_end - word_begin) * sizeof(BitmapWordType)); -#endif } /** @@ -259,13 +252,11 @@ protected: void ClearWords([[maybe_unused]] size_t word_begin, [[maybe_unused]] size_t word_end) { ASSERT(word_begin <= word_end); -#ifndef PANDA_TARGET_WINDOWS if (UNLIKELY(word_begin == word_end)) { return; } (void)memset_s(&bitmap_[word_begin], (word_end - word_begin) * sizeof(BitmapWordType), static_cast(0), (word_end - word_begin) * sizeof(BitmapWordType)); -#endif } explicit Bitmap(BitmapWordType *bitmap, size_t bitsize) @@ -299,7 +290,7 @@ private: size_t GetBitIdxWithinWord(size_t bit_offset) const { CheckBitOffset(bit_offset); - constexpr auto BIT_INDEX_MASK = static_cast((1UL << LOG_BITSPERWORD) - 1); + constexpr auto BIT_INDEX_MASK = static_cast((1ULL << LOG_BITSPERWORD) - 1); return bit_offset & BIT_INDEX_MASK; } @@ -310,7 +301,7 @@ private: */ BitmapWordType GetBitMask(size_t bit_offset) const { - return 1UL << GetBitIdxWithinWord(bit_offset); + return 1ULL << GetBitIdxWithinWord(bit_offset); } /** diff --git a/runtime/mem/malloc-proxy-allocator-inl.h b/runtime/mem/malloc-proxy-allocator-inl.h index ca3e6d3455..22cc7a72b0 100644 --- a/runtime/mem/malloc-proxy-allocator-inl.h +++ b/runtime/mem/malloc-proxy-allocator-inl.h @@ -47,8 +47,8 @@ void *MallocProxyAllocator::Alloc(size_t size, Alignment align) lock_.Lock(); } size_t alignment_in_bytes = GetAlignmentInBytes(align); - size_t aligned_size = (size + alignment_in_bytes - 1) & ~(alignment_in_bytes - 1); - void *ret = aligned_alloc(alignment_in_bytes, aligned_size); + void *ret = os::mem::AlignedAlloc(alignment_in_bytes, size); + // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon) if constexpr (!DUMMY_ALLOC_CONFIG) { ASSERT(allocated_memory_.find(ret) == allocated_memory_.end()); @@ -72,7 +72,7 @@ void MallocProxyAllocator::Free(void *mem) if constexpr (!DUMMY_ALLOC_CONFIG) { lock_.Lock(); } - std::free(mem); // NOLINT(cppcoreguidelines-no-malloc) + os::mem::AlignedFree(mem); // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon) if constexpr (!DUMMY_ALLOC_CONFIG) { auto iterator = allocated_memory_.find(mem); diff --git a/runtime/mem/mem_hooks.cpp b/runtime/mem/mem_hooks.cpp deleted file mode 100644 index f171b90a9e..0000000000 --- a/runtime/mem/mem_hooks.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -#include - -#include "mem_hooks.h" - -namespace panda::mem { - -size_t PandaHooks::alloc_via_standard = 0; -void *(*volatile PandaHooks::old_malloc_hook)(size_t, const void *) = nullptr; -void *(*volatile PandaHooks::old_memalign_hook)(size_t, size_t, const void *) = nullptr; -void (*volatile PandaHooks::old_free_hook)(void *, const void *) = nullptr; - -/* static */ -void PandaHooks::SaveMemHooks() -{ -#ifndef __MUSL__ - old_malloc_hook = __malloc_hook; - old_memalign_hook = __memalign_hook; - old_free_hook = __free_hook; -#endif // __MUSL__ -} - -/* static */ -void PandaHooks::SetMemHooks() -{ -#ifndef __MUSL__ - __malloc_hook = MallocHook; - __memalign_hook = MemalignHook; - __free_hook = FreeHook; -#endif // __MUSL__ -} - -/* static */ -void *PandaHooks::MallocHook(size_t size, [[maybe_unused]] const void *caller) -{ - alloc_via_standard += size; - // tracking internal allocator is implemented by malloc, we would fail here with this option -#ifndef TRACK_INTERNAL_ALLOCATIONS - if (alloc_via_standard > MAX_ALLOC_VIA_STANDARD) { - std::cerr << "Too many usage of standard allocations" << std::endl; - abort(); - } -#endif // TRACK_INTERNAL_ALLOCATIONS - Disable(); - void *result = malloc(size); // NOLINT(cppcoreguidelines-no-malloc) - if (UNLIKELY(result == nullptr)) { - std::cerr << "Malloc error" << std::endl; - abort(); - } - SetMemHooks(); - return result; -} - -/* static */ -void *PandaHooks::MemalignHook(size_t alignment, size_t size, [[maybe_unused]] const void *caller) -{ - alloc_via_standard += size; - // tracking internal allocator is implemented by malloc, we would fail here with this option -#ifndef TRACK_INTERNAL_ALLOCATIONS - if (alloc_via_standard > MAX_ALLOC_VIA_STANDARD) { - std::cerr << "Too many usage of standard allocations" << std::endl; - abort(); - } -#endif // TRACK_INTERNAL_ALLOCATIONS - Disable(); - void *result = memalign(alignment, size); - if (UNLIKELY(result == nullptr)) { - std::cerr << "Align error" << std::endl; - abort(); - } - SetMemHooks(); - return result; -} - -/* static */ -void PandaHooks::FreeHook(void *ptr, [[maybe_unused]] const void *caller) -{ - Disable(); - free(ptr); // NOLINT(cppcoreguidelines-no-malloc) - ptr = nullptr; - SetMemHooks(); -} - -/* static */ -void PandaHooks::Enable() -{ - SaveMemHooks(); - SetMemHooks(); -} - -/* static */ -void PandaHooks::Disable() -{ -#ifndef __MUSL__ - __malloc_hook = old_malloc_hook; - __memalign_hook = old_memalign_hook; - __free_hook = old_free_hook; -#endif // __MUSL__ -} - -} // namespace panda::mem diff --git a/runtime/mem/mem_hooks.h b/runtime/mem/mem_hooks.h deleted file mode 100644 index ade78af9e6..0000000000 --- a/runtime/mem/mem_hooks.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PANDA_RUNTIME_MEM_MEM_HOOKS_H_ -#define PANDA_RUNTIME_MEM_MEM_HOOKS_H_ - -#include "libpandabase/mem/mem.h" - -namespace panda::mem { - -class PandaHooks { -public: - static void Enable(); - - static void Disable(); - - static size_t GetAllocViaStandard() noexcept - { - return alloc_via_standard; - } - -private: - static constexpr size_t MAX_ALLOC_VIA_STANDARD = 4_MB; - - static void SaveMemHooks(); - - static void SetMemHooks(); - - static void *(*volatile old_malloc_hook)(size_t, const void *); - static void *(*volatile old_memalign_hook)(size_t, size_t, const void *); - static void (*volatile old_free_hook)(void *, const void *); - - static void *MallocHook(size_t size, const void *caller); - static void *MemalignHook(size_t alignment, size_t size, const void *caller); - static void FreeHook(void *ptr, const void *caller); - - static size_t alloc_via_standard; -}; - -} // namespace panda::mem - -#endif // PANDA_RUNTIME_MEM_MEM_HOOKS_H_ diff --git a/runtime/runtime.cpp b/runtime/runtime.cpp index b7893d3319..ec6f4ebba6 100644 --- a/runtime/runtime.cpp +++ b/runtime/runtime.cpp @@ -26,7 +26,7 @@ #include "libpandabase/events/events.h" #include "libpandabase/mem/mem_config.h" #include "libpandabase/mem/pool_manager.h" -#include "libpandabase/os/library_loader.h" +#include "libpandabase/os/mem_hooks.h" #include "libpandabase/os/native_stack.h" #include "libpandabase/os/thread.h" #include "libpandabase/utils/arena_containers.h" @@ -53,7 +53,6 @@ #include "runtime/mem/gc/stw-gc/stw-gc.h" #include "runtime/mem/gc/crossing_map_singleton.h" #include "runtime/mem/heap_manager.h" -#include "runtime/mem/mem_hooks.h" #include "runtime/mem/memory_manager.h" #include "runtime/mem/internal_allocator-inl.h" #include "runtime/core/core_class_linker_extension.h" @@ -414,7 +413,7 @@ Runtime::Runtime(const RuntimeOptions &options, mem::InternalAllocatorPtr intern // libbfd (which is used to get debug info from elf files) does a lot of allocations. // Don't track allocations in this case. if (!options_.IsSafepointBacktrace()) { - mem::PandaHooks::Enable(); + panda::os::mem_hooks::PandaHooks::Enable(); } } @@ -432,7 +431,7 @@ Runtime::~Runtime() panda::verifier::debug::DebugContext::Destroy(); if (IsEnableMemoryHooks()) { - mem::PandaHooks::Disable(); + panda::os::mem_hooks::PandaHooks::Disable(); } trace::ScopedTrace scoped_trace("Delete state"); @@ -1175,10 +1174,11 @@ bool Runtime::SaveProfileInfo() const } Trace *Runtime::CreateTrace([[maybe_unused]] LanguageContext ctx, - [[maybe_unused]] PandaUniquePtr trace_file, + [[maybe_unused]] PandaUniquePtr trace_file, [[maybe_unused]] size_t buffer_size) { LOG(FATAL, RUNTIME) << "Method tracing isn't supported at the moment!"; return nullptr; } + } // namespace panda diff --git a/runtime/signal_handler.cpp b/runtime/signal_handler.cpp index d4fd92ef67..838f35a446 100644 --- a/runtime/signal_handler.cpp +++ b/runtime/signal_handler.cpp @@ -22,9 +22,6 @@ #include "include/panda_vm.h" #include "include/thread.h" #include "include/stack_walker.h" -#if defined(PANDA_TARGET_UNIX) -#include "libpandabase/os/unix/sighooklib/sighook.h" -#endif // PANDA_TARGET_UNIX namespace panda { diff --git a/runtime/signal_handler.h b/runtime/signal_handler.h index 9d6fa0d522..2022b58599 100644 --- a/runtime/signal_handler.h +++ b/runtime/signal_handler.h @@ -22,6 +22,7 @@ #include #include #include "runtime/include/mem/panda_containers.h" +#include "libpandabase/os/sighook.h" namespace panda { @@ -52,7 +53,11 @@ public: return allocator_; } +#ifdef PANDA_TARGET_UNIX void DeleteHandlersArray(); +#else + void DeleteHandlersArray() {} +#endif // PANDA_TARGET_UNIX explicit SignalManager(mem::InternalAllocatorPtr allocator) : allocator_(allocator) {} SignalManager(SignalManager &&) = delete; diff --git a/verification/debug/config_load.cpp b/verification/debug/config_load.cpp index 9ff3245033..d488058bc5 100644 --- a/verification/debug/config_load.cpp +++ b/verification/debug/config_load.cpp @@ -25,9 +25,7 @@ #include "verification/debug/breakpoint/breakpoint_private.h" #include "verification/debug/allowlist/allowlist_private.h" -#if !PANDA_TARGET_WINDOWS #include "securec.h" -#endif #include "utils/logger.h" #include "libpandabase/os/file.h" -- Gitee From 03af79f1715d622c0d6b85a0e3b20cc404e43416 Mon Sep 17 00:00:00 2001 From: huangyu Date: Tue, 19 Apr 2022 15:39:54 +0800 Subject: [PATCH 07/14] Fix open mode Signed-off-by: huangyu Change-Id: Ib8024d4df06abe7ea247658f681870fff7a29c19 --- libpandafile/file.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/libpandafile/file.cpp b/libpandafile/file.cpp index 8bb960c9f5..df261bc6bb 100644 --- a/libpandafile/file.cpp +++ b/libpandafile/file.cpp @@ -56,26 +56,26 @@ const char *ANONMAPNAME_PERFIX = "panda-"; os::file::Mode GetMode(panda_file::File::OpenMode open_mode) { - os::file::Mode mode; switch (open_mode) { - case File::READ_WRITE: { - mode = os::file::Mode::READWRITE; - break; - } case File::READ_ONLY: { - mode = os::file::Mode::READONLY; - break; + return os::file::Mode::READONLY; + } + case File::READ_WRITE: { +#ifdef PANDA_TARGET_WINDOWS + return os::file::Mode::READWRITE; +#else + return os::file::Mode::READONLY; +#endif } case File::WRITE_ONLY: { - mode = os::file::Mode::WRITEONLY; - break; + return os::file::Mode::WRITEONLY; } default: { - UNREACHABLE(); break; } } - return mode; + + UNREACHABLE(); } static uint32_t GetProt(panda_file::File::OpenMode mode) @@ -439,9 +439,8 @@ inline std::string VersionToString(const std::array std::unique_ptr File::Open(std::string_view filename, OpenMode open_mode) { trace::ScopedTrace scoped_trace("Open panda file " + std::string(filename)); - os::file::File file = os::file::Open(filename, os::file::Mode::READONLY); - /* os::file::Mode mode = GetMode(open_mode); */ - /* os::file::File file = os::file::Open(filename, mode); */ + os::file::Mode mode = GetMode(open_mode); + os::file::File file = os::file::Open(filename, mode); if (!file.IsValid()) { PLOG(ERROR, PANDAFILE) << "Failed to open panda file '" << filename << "'"; -- Gitee From 20e42a0806dbfe69230895e1be3d32e6469425d4 Mon Sep 17 00:00:00 2001 From: huangyu Date: Tue, 19 Apr 2022 23:15:44 +0800 Subject: [PATCH 08/14] Fix review comments Signed-off-by: huangyu Change-Id: I375ef5894f50eaec7b8978a1a09b6e6a1187a5a5 --- libpandabase/os/time.cpp | 30 ------------------------- libpandabase/os/time.h | 8 +++++++ libpandabase/os/unique_fd.h | 25 +++++++++------------ libpandabase/os/unix/mem.cpp | 3 ++- libpandabase/os/unix/thread.cpp | 2 ++ libpandabase/os/unix/time.h | 31 ++++++++++++++++++++++++++ libpandabase/os/unix/unique_fd.h | 29 ++++++++++++++++++++++++ libpandabase/os/windows/mem_hooks.cpp | 6 +---- libpandabase/os/windows/time.h | 32 +++++++++++++++++++++++++++ libpandabase/os/windows/unique_fd.h | 31 ++++++++++++++++++++++++++ 10 files changed, 146 insertions(+), 51 deletions(-) create mode 100644 libpandabase/os/unix/time.h create mode 100644 libpandabase/os/unix/unique_fd.h create mode 100644 libpandabase/os/windows/time.h create mode 100644 libpandabase/os/windows/unique_fd.h diff --git a/libpandabase/os/time.cpp b/libpandabase/os/time.cpp index 780743ecab..4b7019b11d 100644 --- a/libpandabase/os/time.cpp +++ b/libpandabase/os/time.cpp @@ -15,38 +15,8 @@ #include "os/time.h" -#include - -#ifdef PANDA_TARGET_WINDOWS -#include -#endif - namespace panda::os::time { -#ifdef PANDA_TARGET_UNIX -template -static uint64_t GetClockTime(clockid_t clock) -{ - struct timespec time = {0, 0}; - if (clock_gettime(clock, &time) != -1) { - auto duration = std::chrono::seconds {time.tv_sec} + std::chrono::nanoseconds {time.tv_nsec}; - return std::chrono::duration_cast(duration).count(); - } - return 0; -} -#else -template -static uint64_t GetClockTime(clockid_t clock) -{ - struct timeval time = {0, 0}; - if (gettimeofday(&time, nullptr) != -1) { - auto duration = std::chrono::seconds {time.tv_sec} + std::chrono::microseconds {time.tv_usec}; - return std::chrono::duration_cast(duration).count(); - } - return 0; -} -#endif // PANDA_TARGET_UNIX - /** * Return current time in nanoseconds */ diff --git a/libpandabase/os/time.h b/libpandabase/os/time.h index f9390ebcb4..028973f34f 100644 --- a/libpandabase/os/time.h +++ b/libpandabase/os/time.h @@ -16,6 +16,14 @@ #ifndef PANDA_LIBPANDABASE_OS_TIME_H_ #define PANDA_LIBPANDABASE_OS_TIME_H_ +#ifdef PANDA_TARGET_UNIX +#include "os/unix/time.h" +#elif PANDA_TARGET_WINDOWS +#include "os/windows/time.h" +#else +#error "Unsupported platform" +#endif // PANDA_TARGET_UNIX + #include namespace panda::os::time { diff --git a/libpandabase/os/unique_fd.h b/libpandabase/os/unique_fd.h index 38f16acaab..f43722cd1d 100644 --- a/libpandabase/os/unique_fd.h +++ b/libpandabase/os/unique_fd.h @@ -16,13 +16,18 @@ #ifndef PANDA_LIBPANDABASE_OS_UNIQUE_FD_H_ #define PANDA_LIBPANDABASE_OS_UNIQUE_FD_H_ -#include -#include "utils/logger.h" +#ifdef PANDA_TARGET_UNIX +#include "os/unix/unique_fd.h" +#elif PANDA_TARGET_WINDOWS +#include "os/windows/unique_fd.h" +#else +#error "Unsupported platform" +#endif // PANDA_TARGET_UNIX + #include "os/failure_retry.h" +#include "utils/logger.h" -#ifdef PANDA_TARGET_UNIX -#include -#endif +#include namespace panda::os::unique_fd { @@ -87,16 +92,6 @@ private: int fd_ = -1; }; -inline int DupCloexec([[maybe_unused]] int fd) -{ -#ifdef PANDA_TARGET_UNIX - return fcntl(fd, F_DUPFD_CLOEXEC, 0); -#else - // Unsupported on windows platform - UNREACHABLE(); -#endif -} - } // namespace panda::os::unique_fd #endif // PANDA_LIBPANDABASE_OS_UNIQUE_FD_H_ diff --git a/libpandabase/os/unix/mem.cpp b/libpandabase/os/unix/mem.cpp index 70757b0359..e9f8e7b445 100644 --- a/libpandabase/os/unix/mem.cpp +++ b/libpandabase/os/unix/mem.cpp @@ -117,7 +117,8 @@ void *AlignedAlloc(size_t alignment_in_bytes, size_t size) void AlignedFree(void *mem) { - std::free(mem); // NOLINT(cppcoreguidelines-no-malloc) + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + std::free(mem); } static uint32_t GetPageSizeFromOs() diff --git a/libpandabase/os/unix/thread.cpp b/libpandabase/os/unix/thread.cpp index 8c8d82c923..ff7e8bf116 100644 --- a/libpandabase/os/unix/thread.cpp +++ b/libpandabase/os/unix/thread.cpp @@ -16,8 +16,10 @@ #include "os/thread.h" #include +#ifdef PANDA_TARGET_UNIX #include #include +#endif #include namespace panda::os::thread { diff --git a/libpandabase/os/unix/time.h b/libpandabase/os/unix/time.h new file mode 100644 index 0000000000..04995ae16d --- /dev/null +++ b/libpandabase/os/unix/time.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace panda::os::time { + +template +static uint64_t GetClockTime(clockid_t clock) +{ + struct timespec time = {0, 0}; + if (clock_gettime(clock, &time) != -1) { + auto duration = std::chrono::seconds {time.tv_sec} + std::chrono::nanoseconds {time.tv_nsec}; + return std::chrono::duration_cast(duration).count(); + } + return 0; +} + +} // namespace panda::os::time diff --git a/libpandabase/os/unix/unique_fd.h b/libpandabase/os/unix/unique_fd.h new file mode 100644 index 0000000000..a89d41bd66 --- /dev/null +++ b/libpandabase/os/unix/unique_fd.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ +#define PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ + +#include + +namespace panda::os::unique_fd { + +inline int DupCloexec(int fd) +{ + return fcntl(fd, F_DUPFD_CLOEXEC, 0); +} + +} // namespace panda::os::unique_fd + +#endif // PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ diff --git a/libpandabase/os/windows/mem_hooks.cpp b/libpandabase/os/windows/mem_hooks.cpp index 48d2bd9c45..1a5bb54f77 100644 --- a/libpandabase/os/windows/mem_hooks.cpp +++ b/libpandabase/os/windows/mem_hooks.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -97,8 +97,6 @@ void PandaHooks::Enable() _CrtSetAllocHook(PandaAllocHook); _CrtMemCheckpoint(&begin); _CrtMemDumpAllObjectsSince(&begin); - - return; } /* static */ @@ -113,8 +111,6 @@ void PandaHooks::Disable() std::cerr << "Memory leak detected:" << std::endl; _CrtDumpMemoryLeaks(); } - - return; } } // namespace panda::os::windows::mem_hooks diff --git a/libpandabase/os/windows/time.h b/libpandabase/os/windows/time.h new file mode 100644 index 0000000000..296cd40861 --- /dev/null +++ b/libpandabase/os/windows/time.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +namespace panda::os::time { + +template +static uint64_t GetClockTime([[maybe_unused]] clockid_t clock) +{ + struct timeval time = {0, 0}; + if (gettimeofday(&time, nullptr) != -1) { + auto duration = std::chrono::seconds {time.tv_sec} + std::chrono::microseconds {time.tv_usec}; + return std::chrono::duration_cast(duration).count(); + } + return 0; +} + +} // namespace panda::os::time diff --git a/libpandabase/os/windows/unique_fd.h b/libpandabase/os/windows/unique_fd.h new file mode 100644 index 0000000000..d88bffda29 --- /dev/null +++ b/libpandabase/os/windows/unique_fd.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_LIBPANDABASE_OS_WINDOWS_UNIQUE_FD_H_ +#define PANDA_LIBPANDABASE_OS_WINDOWS_UNIQUE_FD_H_ + +#include "libpandabase/macros.h" + +namespace panda::os::unique_fd { + +inline int DupCloexec([[maybe_unused]] int fd) +{ + // Unsupported on windows platform + UNREACHABLE(); +} + +} // namespace panda::os::unique_fd + +#endif // PANDA_LIBPANDABASE_OS_WINDOWS_UNIQUE_FD_H_ -- Gitee From cb6852a4d05498e1e7232002370d4f38eebac5c4 Mon Sep 17 00:00:00 2001 From: huangyu Date: Wed, 20 Apr 2022 10:22:45 +0800 Subject: [PATCH 09/14] Fix new review comments Signed-off-by: huangyu Change-Id: I87714f81662e1f9cda92c906a9e55beb184f8af3 --- libpandabase/os/sighook.h | 2 -- libpandabase/os/windows/sighook.h | 23 ------------------- runtime/arch/asm_support.cpp | 4 +--- runtime/arch/asm_support.h | 7 ++++++ ...ompiled_code_to_interpreter_bridge_amd64.S | 4 +--- ...led_code_to_interpreter_bridge_dyn_amd64.S | 4 +--- .../compiled_code_to_runtime_bridge_amd64.S | 8 ++----- ...nterpreter_to_compiled_code_bridge_amd64.S | 8 ++----- ...preter_to_compiled_code_bridge_dyn_amd64.S | 8 ++----- runtime/include/runtime.h | 6 +++++ runtime/runtime.cpp | 4 ++++ runtime/signal_handler.h | 4 ---- 12 files changed, 26 insertions(+), 56 deletions(-) delete mode 100644 libpandabase/os/windows/sighook.h diff --git a/libpandabase/os/sighook.h b/libpandabase/os/sighook.h index 65ccc1e8ca..37fb736a6f 100644 --- a/libpandabase/os/sighook.h +++ b/libpandabase/os/sighook.h @@ -18,8 +18,6 @@ #ifdef PANDA_TARGET_UNIX #include "os/unix/sighook.h" -#elif PANDA_TARGET_WINDOWS -#include "os/windows/sighook.h" #else #error "Unsupported platform" #endif diff --git a/libpandabase/os/windows/sighook.h b/libpandabase/os/windows/sighook.h deleted file mode 100644 index b297935e85..0000000000 --- a/libpandabase/os/windows/sighook.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PANDA_LIBPANDABASE_OS_WINDOWS_SIGHOOK_H_ -#define PANDA_LIBPANDABASE_OS_WINDOWS_SIGHOOK_H_ - -#ifndef siginfo_t -#define siginfo_t void -#endif - -#endif // PANDA_LIBPANDABASE_OS_WINDOWS_SIGHOOK_H_ diff --git a/runtime/arch/asm_support.cpp b/runtime/arch/asm_support.cpp index 0922484a63..0cee17c74b 100644 --- a/runtime/arch/asm_support.cpp +++ b/runtime/arch/asm_support.cpp @@ -38,12 +38,10 @@ static_assert(FRAME_SLOT_OFFSET == 80U); static_assert(FRAME_TAG_OFFSET == 88U); #endif -#ifndef PANDA_TARGET_WINDOWS -extern "C" ManagedThread *GetCurrentThread() +extern "C" ManagedThread *GetCurrentManagedThread() { return ManagedThread::GetCurrent(); } -#endif extern "C" void AsmUnreachable() { diff --git a/runtime/arch/asm_support.h b/runtime/arch/asm_support.h index 17c1ac3d82..85c88b3ca1 100644 --- a/runtime/arch/asm_support.h +++ b/runtime/arch/asm_support.h @@ -37,6 +37,13 @@ // clang-format off +#ifndef PANDA_TARGET_WINDOWS +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TYPE_FUNCTION(name) .type name, %function +#else +#define TYPE_FUNCTION(name) +#endif + #ifndef NDEBUG // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) diff --git a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S index acae8d6d0b..295183b912 100644 --- a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S +++ b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S @@ -30,9 +30,7 @@ .extern IncrementHotnessCounter .global CompiledCodeToInterpreterBridge -#ifndef PANDA_TARGET_WINDOWS -.type CompiledCodeToInterpreterBridge, %function -#endif +TYPE_FUNCTION(CompiledCodeToInterpreterBridge,) CompiledCodeToInterpreterBridge: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S index 6f3c8fe01a..9056cb8a33 100644 --- a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S +++ b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_dyn_amd64.S @@ -29,9 +29,7 @@ // CompiledCodeToInterpreterBridgeDyn(Method* method, uint32_t num_args, int64_t func_obj, int64_t func_tag, int64_t arg_i, int64_t tag_i, ...) .global CompiledCodeToInterpreterBridgeDyn -#ifndef PANDA_TARGET_WINDOWS -.type CompiledCodeToInterpreterBridgeDyn, %function -#endif +TYPE_FUNCTION(CompiledCodeToInterpreterBridgeDyn) CompiledCodeToInterpreterBridgeDyn: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S b/runtime/bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S index ccb1189820..9b7166b7d4 100644 --- a/runtime/bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S +++ b/runtime/bridge/arch/amd64/compiled_code_to_runtime_bridge_amd64.S @@ -17,9 +17,7 @@ .macro ENTRYPOINT name, entry, paramsnum .global \name -#ifndef PANDA_TARGET_WINDOWS -.type \name, %function -#endif +TYPE_FUNCTION(\name) \name: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) @@ -67,9 +65,7 @@ #include "entrypoints_bridge_asm_macro.inl" .global AbstractMethodStub -#ifndef PANDA_TARGET_WINDOWS -.type AbstractMethodStub, %function -#endif +TYPE_FUNCTION(AbstractMethodStub) AbstractMethodStub: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_amd64.S b/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_amd64.S index 74ed70ce4f..5aaa7370fb 100644 --- a/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_amd64.S +++ b/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_amd64.S @@ -261,9 +261,7 @@ // void InterpreterToCompiledCodeBridge(const BytecodeInstruction* insn, const Frame *iframe, const Method *method, ManagedThread* thread) .global InterpreterToCompiledCodeBridge -#ifndef PANDA_TARGET_WINDOWS -.type InterpreterToCompiledCodeBridge, %function -#endif +TYPE_FUNCTION(InterpreterToCompiledCodeBridge) InterpreterToCompiledCodeBridge: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) @@ -452,9 +450,7 @@ InterpreterToCompiledCodeBridge: // DecodedTaggedValue InvokeCompiledCodeWithArguments(const int64_t* args, const Frame *iframe, const Method *method, ManagedThread* thread) .global InvokeCompiledCodeWithArgArray -#ifndef PANDA_TARGET_WINDOWS -.type InvokeCompiledCodeWithArgArray, %function -#endif +TYPE_FUNCTION(InvokeCompiledCodeWithArgArray) InvokeCompiledCodeWithArgArray: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S b/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S index 0c898a30b5..f4d2ff8991 100644 --- a/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S +++ b/runtime/bridge/arch/amd64/interpreter_to_compiled_code_bridge_dyn_amd64.S @@ -21,9 +21,7 @@ // const Method*, %rdx // ManagedThread* thread) %rcx .global InterpreterToCompiledCodeBridgeDyn -#ifndef PANDA_TARGET_WINDOWS -.type InterpreterToCompiledCodeBridgeDyn, %function -#endif +TYPE_FUNCTION(InterpreterToCompiledCodeBridgeDyn) InterpreterToCompiledCodeBridgeDyn: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) @@ -127,9 +125,7 @@ InterpreterToCompiledCodeBridgeDyn: // const Method*, %rcx // ManagedThread* thread) %r8 .global InvokeCompiledCodeWithArgArrayDyn -#ifndef PANDA_TARGET_WINDOWS -.type InvokeCompiledCodeWithArgArrayDyn, %function -#endif +TYPE_FUNCTION(InvokeCompiledCodeWithArgArrayDyn) InvokeCompiledCodeWithArgArrayDyn: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index a4e1e25d72..5d0f4f49a2 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -33,7 +33,9 @@ #include "runtime/include/runtime_options.h" #include "runtime/include/gc_task.h" #include "runtime/include/tooling/debug_interface.h" +#ifndef PANDA_TARGET_WINDOWS #include "runtime/signal_handler.h" +#endif #include "runtime/mem/allocator_adapter.h" #include "runtime/mem/gc/gc.h" #include "runtime/mem/gc/gc_trigger.h" @@ -307,10 +309,12 @@ public: return is_stacktrace_; } +#ifndef PANDA_TARGET_WINDOWS SignalManager *GetSignalManager() { return signal_manager_; } +#endif Trace *CreateTrace(LanguageContext ctx, PandaUniquePtr trace_file, size_t buffer_size); @@ -377,7 +381,9 @@ private: PandaVM *panda_vm_ = nullptr; +#ifndef PANDA_TARGET_WINDOWS SignalManager *signal_manager_ {nullptr}; +#endif // Language context static constexpr size_t LANG_EXTENSIONS_COUNT = static_cast(panda_file::SourceLang::LAST) + 1; diff --git a/runtime/runtime.cpp b/runtime/runtime.cpp index ec6f4ebba6..2510635c2b 100644 --- a/runtime/runtime.cpp +++ b/runtime/runtime.cpp @@ -406,8 +406,10 @@ Runtime::Runtime(const RuntimeOptions &options, mem::InternalAllocatorPtr intern // CODECHECK-NOLINTNEXTLINE(CPP_RULE_ID_SMARTPOINTER_INSTEADOF_ORIGINPOINTER) class_linker_ = new ClassLinker(internal_allocator_, std::move(extensions)); +#ifndef PANDA_TARGET_WINDOWS // CODECHECK-NOLINTNEXTLINE(CPP_RULE_ID_SMARTPOINTER_INSTEADOF_ORIGINPOINTER) signal_manager_ = new SignalManager(internal_allocator_); +#endif if (IsEnableMemoryHooks()) { // libbfd (which is used to get debug info from elf files) does a lot of allocations. @@ -435,8 +437,10 @@ Runtime::~Runtime() } trace::ScopedTrace scoped_trace("Delete state"); +#ifndef PANDA_TARGET_WINDOWS signal_manager_->DeleteHandlersArray(); delete signal_manager_; +#endif delete class_linker_; if (dprofiler_ != nullptr) { internal_allocator_->Delete(dprofiler_); diff --git a/runtime/signal_handler.h b/runtime/signal_handler.h index 2022b58599..8c850359b9 100644 --- a/runtime/signal_handler.h +++ b/runtime/signal_handler.h @@ -53,11 +53,7 @@ public: return allocator_; } -#ifdef PANDA_TARGET_UNIX void DeleteHandlersArray(); -#else - void DeleteHandlersArray() {} -#endif // PANDA_TARGET_UNIX explicit SignalManager(mem::InternalAllocatorPtr allocator) : allocator_(allocator) {} SignalManager(SignalManager &&) = delete; -- Gitee From 81041c2c4d701e5d09fc47ca5ba90b5bda40872c Mon Sep 17 00:00:00 2001 From: huangyu Date: Wed, 20 Apr 2022 10:28:28 +0800 Subject: [PATCH 10/14] Fix 0419 new review comments Signed-off-by: huangyu Change-Id: I4e58ab08f370d3ebd42528223464a37057ec5c5c --- libpandabase/os/failure_retry.h | 4 +++- libpandabase/os/thread.h | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libpandabase/os/failure_retry.h b/libpandabase/os/failure_retry.h index b4cb0593e6..5d804d8b82 100644 --- a/libpandabase/os/failure_retry.h +++ b/libpandabase/os/failure_retry.h @@ -31,9 +31,11 @@ // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define PANDA_FAILURE_RETRY(exp) (__extension__ TEMP_FAILURE_RETRY(exp)) -#else +#elif PANDA_TARGET_WINDOWS // Windows Os does not support TEMP_FAILURE_RETRY macro #define PANDA_FAILURE_RETRY(exp) (exp) +#else +#error "Unsupported platform" #endif // PANDA_TARGET_UNIX #endif // PANDA_LIBPANDABASE_OS_UNIX_FAILURE_RETRY_H_ diff --git a/libpandabase/os/thread.h b/libpandabase/os/thread.h index eb91e2ed2f..3038f7faa9 100644 --- a/libpandabase/os/thread.h +++ b/libpandabase/os/thread.h @@ -28,7 +28,6 @@ namespace panda::os::thread { using ThreadId = uint32_t; using native_handle_type = std::thread::native_handle_type; -using HANDLE = void *; ThreadId GetCurrentThreadId(); int SetPriority(int thread_id, int prio); -- Gitee From 909b6a90ecfcb1ecc902e11f3adbe39d5de2f510 Mon Sep 17 00:00:00 2001 From: huangyu Date: Wed, 20 Apr 2022 12:09:42 +0800 Subject: [PATCH 11/14] Fix difference Signed-off-by: huangyu Change-Id: I80838076f409ee9e3a785c40b637f2ebfe9c0814 --- libpandabase/BUILD.gn | 1 + libpandabase/CMakeLists.txt | 66 ++++++++-------- libpandabase/os/failure_retry.h | 1 + libpandabase/os/filesystem.h | 2 +- libpandabase/os/mem.h | 2 +- libpandabase/os/mem_hooks.h | 2 +- libpandabase/os/sighook.h | 2 +- libpandabase/os/unix/unique_fd.h | 1 + libpandabase/os/windows/mem.cpp | 4 +- libpandabase/os/windows/mem_hooks.cpp | 5 +- libpandabase/os/windows/mem_hooks.h | 3 +- libpandabase/os/windows/windows_mem.h | 4 + libpandabase/tests/dfx_test.cpp | 79 ++++++++++--------- libpandabase/tests/hash_test.cpp | 2 +- libpandabase/tests/mmap_fixed_test.cpp | 7 +- libpandafile/panda_cache.h | 28 +++---- ...ompiled_code_to_interpreter_bridge_amd64.S | 2 +- runtime/include/runtime.h | 2 - runtime/mem/malloc-proxy-allocator-inl.h | 1 - runtime/runtime.cpp | 8 -- verification/debug/config_load.cpp | 2 + 21 files changed, 111 insertions(+), 113 deletions(-) diff --git a/libpandabase/BUILD.gn b/libpandabase/BUILD.gn index 2182489c20..f6bc3b924f 100644 --- a/libpandabase/BUILD.gn +++ b/libpandabase/BUILD.gn @@ -74,6 +74,7 @@ if (is_mingw) { "$ark_root/libpandabase/mem/pool_manager.cpp", "$ark_root/libpandabase/mem/pool_map.cpp", "$ark_root/libpandabase/os/dfx_option.cpp", + "$ark_root/libpandabase/os/native_stack.cpp", "$ark_root/libpandabase/os/property.cpp", # product build diff --git a/libpandabase/CMakeLists.txt b/libpandabase/CMakeLists.txt index 26ac128b4e..c55b7e5e5b 100644 --- a/libpandabase/CMakeLists.txt +++ b/libpandabase/CMakeLists.txt @@ -194,41 +194,45 @@ target_include_directories(arkbase PUBLIC ${INCLUDE_DIRECTORIES} ) +set(ARKBASE_TESTS_SOURCES + tests/list_test.cpp + tests/bit_helpers_test.cpp + tests/bit_memory_region_test.cpp + tests/bit_table_test.cpp + tests/bit_utils_test.cpp + tests/bit_vector_test.cpp + tests/string_helpers_test.cpp + tests/type_converter_tests.cpp + tests/logger_test.cpp + tests/dfx_test.cpp + tests/leb128_test.cpp + tests/utf_test.cpp + tests/arena_test.cpp + tests/arena_allocator_test.cpp + tests/expected_test.cpp + tests/code_allocator_test.cpp + tests/small_vector_test.cpp + tests/span_test.cpp + tests/pandargs_test.cpp + tests/pool_map_test.cpp + tests/hash_test.cpp + tests/math_helpers_test.cpp + tests/serializer_test.cpp + tests/base_mem_stats_test.cpp + tests/unique_fd_test.cpp + tests/mem_range_test.cpp + tests/mmap_fixed_test.cpp + tests/mmap_mem_pool_test.cpp + tests/native_bytes_from_mallinfo_test.cpp + tests/json_parser_test.cpp + tests/alloc_tracker_test.cpp +) + panda_add_gtest( NO_CORES NAME arkbase_tests SOURCES - tests/list_test.cpp - tests/bit_helpers_test.cpp - tests/bit_memory_region_test.cpp - tests/bit_table_test.cpp - tests/bit_utils_test.cpp - tests/bit_vector_test.cpp - tests/string_helpers_test.cpp - tests/type_converter_tests.cpp - tests/logger_test.cpp - tests/dfx_test.cpp - tests/leb128_test.cpp - tests/utf_test.cpp - tests/arena_test.cpp - tests/arena_allocator_test.cpp - tests/expected_test.cpp - tests/code_allocator_test.cpp - tests/small_vector_test.cpp - tests/span_test.cpp - tests/pandargs_test.cpp - tests/pool_map_test.cpp - tests/hash_test.cpp - tests/math_helpers_test.cpp - tests/serializer_test.cpp - tests/base_mem_stats_test.cpp - tests/unique_fd_test.cpp - tests/mem_range_test.cpp - tests/mmap_fixed_test.cpp - tests/mmap_mem_pool_test.cpp - tests/native_bytes_from_mallinfo_test.cpp - tests/json_parser_test.cpp - tests/alloc_tracker_test.cpp + ${ARKBASE_TESTS_SOURCES) LIBRARIES arkbase SANITIZERS diff --git a/libpandabase/os/failure_retry.h b/libpandabase/os/failure_retry.h index 5d804d8b82..2d914c1cfd 100644 --- a/libpandabase/os/failure_retry.h +++ b/libpandabase/os/failure_retry.h @@ -19,6 +19,7 @@ #ifdef PANDA_TARGET_UNIX // Mac Os' libc doesn't have this macro #ifndef TEMP_FAILURE_RETRY +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define TEMP_FAILURE_RETRY(exp) \ (__extension__({ \ decltype(exp) _result; \ diff --git a/libpandabase/os/filesystem.h b/libpandabase/os/filesystem.h index 36ca777b2e..2693a8aeb1 100644 --- a/libpandabase/os/filesystem.h +++ b/libpandabase/os/filesystem.h @@ -27,7 +27,7 @@ constexpr size_t NAME_MAX = 255; #include #else #include -#endif // PANDA_TARGET_WINDOWS +#endif namespace panda::os { diff --git a/libpandabase/os/mem.h b/libpandabase/os/mem.h index 403f7afe59..fa9bd61f08 100644 --- a/libpandabase/os/mem.h +++ b/libpandabase/os/mem.h @@ -365,7 +365,7 @@ inline void ReleasePages([[maybe_unused]] uintptr_t pages_start, [[maybe_unused] #ifdef PANDA_TARGET_UNIX madvise(ToVoidPtr(pages_start), pages_end - pages_start, MADV_DONTNEED); #else - // On windows systems we can't do anything + // On windows systems we can do nothing #endif } diff --git a/libpandabase/os/mem_hooks.h b/libpandabase/os/mem_hooks.h index 036f868324..f8d08d0ff2 100644 --- a/libpandabase/os/mem_hooks.h +++ b/libpandabase/os/mem_hooks.h @@ -22,6 +22,6 @@ #include "os/windows/mem_hooks.h" #else #error "Unsupported platform" -#endif +#endif // PANDA_TARGET_UNIX #endif // PANDA_LIBPANDABASE_OS_MEM_HOOKS_H_ diff --git a/libpandabase/os/sighook.h b/libpandabase/os/sighook.h index 37fb736a6f..a0b9bce455 100644 --- a/libpandabase/os/sighook.h +++ b/libpandabase/os/sighook.h @@ -20,6 +20,6 @@ #include "os/unix/sighook.h" #else #error "Unsupported platform" -#endif +#endif // PANDA_TARGET_UNIX #endif // PANDA_LIBPANDABASE_OS_SIGHOOK_H_ diff --git a/libpandabase/os/unix/unique_fd.h b/libpandabase/os/unix/unique_fd.h index a89d41bd66..977054b9a8 100644 --- a/libpandabase/os/unix/unique_fd.h +++ b/libpandabase/os/unix/unique_fd.h @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ #define PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ diff --git a/libpandabase/os/windows/mem.cpp b/libpandabase/os/windows/mem.cpp index fde47555ed..e2195d5842 100644 --- a/libpandabase/os/windows/mem.cpp +++ b/libpandabase/os/windows/mem.cpp @@ -60,8 +60,8 @@ static DWORD mem_protection_flags_for_file(const int prot, const uint32_t map_fl } /* Notice that only single FILE_MAP_COPY flag can ensure a copy-on-write mapping which - * MMAP_FLAG_PRIVATE needs. It can't be bitwise OR'ed with FLAG_MAP_ALL_ACCESS, FILE_MAP_READ - * or FLAG_MAP_WRITE. Or else it will be converted to PAGE_READONLY or PAGE_READWRITE, and make + * MMAP_FLAG_PRIVATE needs. It can't be bitwise OR'ed with FILE_MAP_ALL_ACCESS, FILE_MAP_READ + * or FILE_MAP_WRITE. Or else it will be converted to PAGE_READONLY or PAGE_READWRITE, and make * the changes synced back to the original file. */ if ((map_flags & MMAP_FLAG_PRIVATE) != 0) { diff --git a/libpandabase/os/windows/mem_hooks.cpp b/libpandabase/os/windows/mem_hooks.cpp index 1a5bb54f77..42fdff7ccf 100644 --- a/libpandabase/os/windows/mem_hooks.cpp +++ b/libpandabase/os/windows/mem_hooks.cpp @@ -51,9 +51,8 @@ static const char *GetBlockTypeName(int bt) } } -int PandaAllocHook(int alloctype, void *data, std::size_t size, - int blocktype, long request, - const unsigned char *filename, int linenumber) +int PandaAllocHook(int alloctype, [[maybe_unused]] void *data, std::size_t size, int blocktype, + [[maybe_unused]] long request, const unsigned char *filename, int linenumber) { if (!enable) { return true; diff --git a/libpandabase/os/windows/mem_hooks.h b/libpandabase/os/windows/mem_hooks.h index a497462390..4bcf50fb10 100644 --- a/libpandabase/os/windows/mem_hooks.h +++ b/libpandabase/os/windows/mem_hooks.h @@ -34,8 +34,7 @@ private: * Installed it using "_CrtSetAllocHook", then it will be called every time memory is * allocated, reallocated, or freed. */ - static int PandaAllocHook(int alloctype, void *data, std::size_t size, - int blocktype, long request, + static int PandaAllocHook(int alloctype, void *data, std::size_t size, int blocktype, long request, const unsigned char *filename, int linenumber); static _CrtMemState begin, end, out; diff --git a/libpandabase/os/windows/windows_mem.h b/libpandabase/os/windows/windows_mem.h index e781ed4272..9127555d3f 100644 --- a/libpandabase/os/windows/windows_mem.h +++ b/libpandabase/os/windows/windows_mem.h @@ -28,6 +28,10 @@ static constexpr uint32_t MMAP_FLAG_PRIVATE = 2; static constexpr uint32_t MMAP_FLAG_FIXED = 0x10; static constexpr uint32_t MMAP_FLAG_ANONYMOUS = 0x20; +void *mmap([[maybe_unused]] void *addr, size_t len, int prot, uint32_t flags, int fildes, off_t off); + +int munmap(void *addr, [[maybe_unused]] size_t len); + } // namespace panda::os::mem #endif // PANDA_LIBPANDABASE_OS_WINDOWS_WINDOWS_MEM_H_ diff --git a/libpandabase/tests/dfx_test.cpp b/libpandabase/tests/dfx_test.cpp index 688c5e55ed..78397552d0 100644 --- a/libpandabase/tests/dfx_test.cpp +++ b/libpandabase/tests/dfx_test.cpp @@ -22,6 +22,43 @@ namespace panda::test { +void MapDfxOption(std::map &option_map, DfxOptionHandler::DfxOption option) +{ + switch (option) { +#ifdef PANDA_TARGET_UNIX + case DfxOptionHandler::COMPILER_NULLCHECK: + option_map[DfxOptionHandler::COMPILER_NULLCHECK] = 1; + break; + case DfxOptionHandler::SIGNAL_CATCHER: + option_map[DfxOptionHandler::SIGNAL_CATCHER] = 1; + break; + case DfxOptionHandler::SIGNAL_HANDLER: + option_map[DfxOptionHandler::SIGNAL_HANDLER] = 1; + break; + case DfxOptionHandler::ARK_SIGQUIT: + option_map[DfxOptionHandler::ARK_SIGQUIT] = 1; + break; + case DfxOptionHandler::ARK_SIGUSR1: + option_map[DfxOptionHandler::ARK_SIGUSR1] = 1; + break; + case DfxOptionHandler::ARK_SIGUSR2: + option_map[DfxOptionHandler::ARK_SIGUSR2] = 1; + break; + case DfxOptionHandler::MOBILE_LOG: + option_map[DfxOptionHandler::MOBILE_LOG] = 1; + break; +#endif + case DfxOptionHandler::REFERENCE_DUMP: + option_map[DfxOptionHandler::REFERENCE_DUMP] = 1; + break; + case DfxOptionHandler::DFXLOG: + option_map[DfxOptionHandler::DFXLOG] = 0; + break; + default: + break; + } +} + TEST(DfxController, Initialization) { if (DfxController::IsInitialized()) { @@ -37,42 +74,8 @@ TEST(DfxController, Initialization) std::map option_map; for (auto option = DfxOptionHandler::DfxOption(0); option < DfxOptionHandler::END_FLAG; - option = DfxOptionHandler::DfxOption(option + 1)) { - switch (option) { -#ifdef PANDA_TARGET_UNIX - case DfxOptionHandler::COMPILER_NULLCHECK: - option_map[DfxOptionHandler::COMPILER_NULLCHECK] = 1; - break; -#endif - case DfxOptionHandler::REFERENCE_DUMP: - option_map[DfxOptionHandler::REFERENCE_DUMP] = 1; - break; -#ifdef PANDA_TARGET_UNIX - case DfxOptionHandler::SIGNAL_CATCHER: - option_map[DfxOptionHandler::SIGNAL_CATCHER] = 1; - break; - case DfxOptionHandler::SIGNAL_HANDLER: - option_map[DfxOptionHandler::SIGNAL_HANDLER] = 1; - break; - case DfxOptionHandler::ARK_SIGQUIT: - option_map[DfxOptionHandler::ARK_SIGQUIT] = 1; - break; - case DfxOptionHandler::ARK_SIGUSR1: - option_map[DfxOptionHandler::ARK_SIGUSR1] = 1; - break; - case DfxOptionHandler::ARK_SIGUSR2: - option_map[DfxOptionHandler::ARK_SIGUSR2] = 1; - break; - case DfxOptionHandler::MOBILE_LOG: - option_map[DfxOptionHandler::MOBILE_LOG] = 1; - break; -#endif - case DfxOptionHandler::DFXLOG: - option_map[DfxOptionHandler::DFXLOG] = 0; - break; - default: - break; - } + option = DfxOptionHandler::DfxOption(option + 1)) { + MapDfxOption(option_map, option); } DfxController::Initialize(option_map); @@ -132,9 +135,7 @@ TEST(DfxController, TestPrintDfxOptionValues) tid, tid, tid, tid, tid, tid, tid, tid, tid, tid); #else std::string res = helpers::string::Format( - //TODO(huangyu): check for gtest - "[TID %06x] E/dfx: DFX option: reference-dump, option values: 1\n" - "[TID %06x] E/dfx: DFX option: dfx-log, option values: 0\n", tid, tid, tid); + "[TID %06x] E/dfx: DFX option: dfx-log, option values: 0\n", tid, tid); #endif EXPECT_EQ(err, res); diff --git a/libpandabase/tests/hash_test.cpp b/libpandabase/tests/hash_test.cpp index b768bbe73d..61a51d843c 100644 --- a/libpandabase/tests/hash_test.cpp +++ b/libpandabase/tests/hash_test.cpp @@ -119,7 +119,7 @@ void HashTest::EndOfPageStringHashTest() const constexpr size_t ALLOC_SIZE = PAGE_SIZE * 2; void *mem = panda::os::mem::MapRWAnonymousRaw(ALLOC_SIZE); ASAN_UNPOISON_MEMORY_REGION(mem, ALLOC_SIZE); - MakeMemWithProtFlag(reinterpret_cast(reinterpret_cast(mem) + PAGE_SIZE), PAGE_SIZE, PROT_NONE); + panda::os::mem::MakeMemWithProtFlag(reinterpret_cast(reinterpret_cast(mem) + PAGE_SIZE), PAGE_SIZE, PROT_NONE); char *string = reinterpret_cast((reinterpret_cast(mem) + PAGE_SIZE) - sizeof(char) * string_size); string[0] = 'O'; diff --git a/libpandabase/tests/mmap_fixed_test.cpp b/libpandabase/tests/mmap_fixed_test.cpp index 26ee7d141c..5afe49de02 100644 --- a/libpandabase/tests/mmap_fixed_test.cpp +++ b/libpandabase/tests/mmap_fixed_test.cpp @@ -15,9 +15,6 @@ #include "os/mem.h" #include "mem/mem.h" #include "utils/asan_interface.h" -#ifdef PANDA_TARGET_WINDOWS -#include "os/windows/mem.cpp" -#endif #include "gtest/gtest.h" @@ -47,8 +44,8 @@ TEST_F(MMapFixedTest, MMapAsanTest) uintptr_t end_addr = panda::os::mem::MMAP_FIXED_MAGIC_ADDR_FOR_ASAN; end_addr = AlignUp(end_addr, sizeof(uint64_t)); void *result = // NOLINTNEXTLINE(hicpp-signed-bitwise) - mmap(ToVoidPtr(cur_addr), MMAP_ALLOC_SIZE, MMAP_PROT_READ | MMAP_PROT_WRITE, MMAP_FLAG_PRIVATE | MMAP_FLAG_ANONYMOUS | MMAP_FLAG_FIXED, -1, - 0); + mmap(ToVoidPtr(cur_addr), MMAP_ALLOC_SIZE, MMAP_PROT_READ | MMAP_PROT_WRITE, + MMAP_FLAG_PRIVATE | MMAP_FLAG_ANONYMOUS | MMAP_FLAG_FIXED, -1, 0); ASSERT_TRUE(result != nullptr); ASSERT_TRUE(ToUintPtr(result) == cur_addr); while (cur_addr < end_addr) { diff --git a/libpandafile/panda_cache.h b/libpandafile/panda_cache.h index b27d25d6b7..edb0146b08 100644 --- a/libpandafile/panda_cache.h +++ b/libpandafile/panda_cache.h @@ -80,7 +80,7 @@ public: inline Method *GetMethodFromCache([[maybe_unused]] File::EntityId id) const { // the os platform macro should be removed when "atomic" symbol is provided in mingw -#ifdef PANDA_TARGET_UNIX +#ifndef PANDA_TARGET_WINDOWS uint32_t index = GetMethodIndex(id); auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(method_cache_[index]))); @@ -89,14 +89,14 @@ public: if (pair.id_ == id) { return pair.ptr_; } -#endif // PANDA_TARGET_UNIX +#endif return nullptr; } inline void SetMethodCache([[maybe_unused]] File::EntityId id, [[maybe_unused]] Method *method) { // the os platform macro should be removed when "atomic" symbol is provided in mingw -#ifdef PANDA_TARGET_UNIX +#ifndef PANDA_TARGET_WINDOWS MethodCachePair pair; pair.id_ = id; pair.ptr_ = method; @@ -105,13 +105,13 @@ public: reinterpret_cast *>(reinterpret_cast(&(method_cache_[index]))); TSAN_ANNOTATE_HAPPENS_BEFORE(pair_ptr); pair_ptr->store(pair, std::memory_order_release); -#endif // PANDA_TARGET_UNIX +#endif } inline Field *GetFieldFromCache([[maybe_unused]] File::EntityId id) const { // the os platform macro should be removed when "atomic" symbol is provided in mingw -#ifdef PANDA_TARGET_UNIX +#ifndef PANDA_TARGET_WINDOWS uint32_t index = GetFieldIndex(id); auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(field_cache_[index]))); @@ -120,14 +120,14 @@ public: if (pair.id_ == id) { return pair.ptr_; } -#endif // PANDA_TARGET_UNIX +#endif return nullptr; } inline void SetFieldCache([[maybe_unused]] File::EntityId id, [[maybe_unused]] Field *field) { // the os platform macro should be removed when "atomic" symbol is provided in mingw -#ifdef PANDA_TARGET_UNIX +#ifndef PANDA_TARGET_WINDOWS uint32_t index = GetFieldIndex(id); auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(field_cache_[index]))); @@ -136,13 +136,13 @@ public: pair.ptr_ = field; TSAN_ANNOTATE_HAPPENS_BEFORE(pair_ptr); pair_ptr->store(pair, std::memory_order_release); -#endif // PANDA_TARGET_UNIX +#endif } inline Class *GetClassFromCache([[maybe_unused]] File::EntityId id) const { // the os platform macro should be removed when "atomic" symbol is provided in mingw -#ifdef PANDA_TARGET_UNIX +#ifndef PANDA_TARGET_WINDOWS uint32_t index = GetClassIndex(id); auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(class_cache_[index]))); @@ -151,14 +151,14 @@ public: if (pair.id_ == id) { return pair.ptr_; } -#endif // PANDA_TARGET_UNIX +#endif return nullptr; } inline void SetClassCache([[maybe_unused]] File::EntityId id, [[maybe_unused]] Class *clazz) { // the os platform macro should be removed when "atomic" symbol is provided in mingw -#ifdef PANDA_TARGET_UNIX +#ifndef PANDA_TARGET_WINDOWS ClassCachePair pair; pair.id_ = id; pair.ptr_ = clazz; @@ -167,14 +167,14 @@ public: reinterpret_cast *>(reinterpret_cast(&(class_cache_[index]))); TSAN_ANNOTATE_HAPPENS_BEFORE(pair_ptr); pair_ptr->store(pair, std::memory_order_release); -#endif // PANDA_TARGET_UNIX +#endif } template bool EnumerateCachedClasses([[maybe_unused]] const Callback &cb) { // the os platform macro should be removed when "atomic" symbol is provided in mingw -#ifdef PANDA_TARGET_UNIX +#ifndef PANDA_TARGET_WINDOWS for (uint32_t i = 0; i < CLASS_CACHE_SIZE; i++) { auto *pair_ptr = reinterpret_cast *>(reinterpret_cast(&(class_cache_[i]))); @@ -186,7 +186,7 @@ public: } } } -#endif // PANDA_TARGET_UNIX +#endif return true; } diff --git a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S index 295183b912..f6638f6c20 100644 --- a/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S +++ b/runtime/bridge/arch/amd64/compiled_code_to_interpreter_bridge_amd64.S @@ -30,7 +30,7 @@ .extern IncrementHotnessCounter .global CompiledCodeToInterpreterBridge -TYPE_FUNCTION(CompiledCodeToInterpreterBridge,) +TYPE_FUNCTION(CompiledCodeToInterpreterBridge) CompiledCodeToInterpreterBridge: CFI_STARTPROC CFI_DEF_CFA(rsp, 8) diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index 5d0f4f49a2..e915b585a9 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -316,8 +316,6 @@ public: } #endif - Trace *CreateTrace(LanguageContext ctx, PandaUniquePtr trace_file, size_t buffer_size); - void SetPtLangExt(tooling::PtLangExt *pt_lang_ext); static mem::GCType GetGCType(const RuntimeOptions &options); diff --git a/runtime/mem/malloc-proxy-allocator-inl.h b/runtime/mem/malloc-proxy-allocator-inl.h index 22cc7a72b0..f045576e9c 100644 --- a/runtime/mem/malloc-proxy-allocator-inl.h +++ b/runtime/mem/malloc-proxy-allocator-inl.h @@ -48,7 +48,6 @@ void *MallocProxyAllocator::Alloc(size_t size, Alignment align) } size_t alignment_in_bytes = GetAlignmentInBytes(align); void *ret = os::mem::AlignedAlloc(alignment_in_bytes, size); - // NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon) if constexpr (!DUMMY_ALLOC_CONFIG) { ASSERT(allocated_memory_.find(ret) == allocated_memory_.end()); diff --git a/runtime/runtime.cpp b/runtime/runtime.cpp index 2510635c2b..624311dd8c 100644 --- a/runtime/runtime.cpp +++ b/runtime/runtime.cpp @@ -1177,12 +1177,4 @@ bool Runtime::SaveProfileInfo() const return save_profiling_info_; } -Trace *Runtime::CreateTrace([[maybe_unused]] LanguageContext ctx, - [[maybe_unused]] PandaUniquePtr trace_file, - [[maybe_unused]] size_t buffer_size) -{ - LOG(FATAL, RUNTIME) << "Method tracing isn't supported at the moment!"; - return nullptr; -} - } // namespace panda diff --git a/verification/debug/config_load.cpp b/verification/debug/config_load.cpp index d488058bc5..9ff3245033 100644 --- a/verification/debug/config_load.cpp +++ b/verification/debug/config_load.cpp @@ -25,7 +25,9 @@ #include "verification/debug/breakpoint/breakpoint_private.h" #include "verification/debug/allowlist/allowlist_private.h" +#if !PANDA_TARGET_WINDOWS #include "securec.h" +#endif #include "utils/logger.h" #include "libpandabase/os/file.h" -- Gitee From 35bffadf9ed4c93371109b6ccc8195461ed5abf8 Mon Sep 17 00:00:00 2001 From: huangyu Date: Wed, 20 Apr 2022 17:04:24 +0800 Subject: [PATCH 12/14] Fix codestyle Signed-off-by: huangyu Change-Id: I9a1185d58d4b578847c26fe36bfab5b9110fe0b1 --- libpandabase/CMakeLists.txt | 2 +- libpandabase/os/mutex.cpp | 2 -- libpandabase/os/windows/mem_hooks.h | 2 +- libpandabase/tests/dfx_test.cpp | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libpandabase/CMakeLists.txt b/libpandabase/CMakeLists.txt index c55b7e5e5b..30e47bf94a 100644 --- a/libpandabase/CMakeLists.txt +++ b/libpandabase/CMakeLists.txt @@ -232,7 +232,7 @@ panda_add_gtest( NO_CORES NAME arkbase_tests SOURCES - ${ARKBASE_TESTS_SOURCES) + ${ARKBASE_TESTS_SOURCES} LIBRARIES arkbase SANITIZERS diff --git a/libpandabase/os/mutex.cpp b/libpandabase/os/mutex.cpp index 929230bee2..b98ecad2b8 100644 --- a/libpandabase/os/mutex.cpp +++ b/libpandabase/os/mutex.cpp @@ -43,10 +43,8 @@ Mutex::Mutex(bool is_init) : mutex_() Mutex::~Mutex() { -#ifdef PANDA_TARGET_UNIX int rc = pthread_mutex_destroy(&mutex_); FatalIfError("pthread_mutex_destroy", rc); -#endif } void Mutex::Init(pthread_mutexattr_t *attrs) diff --git a/libpandabase/os/windows/mem_hooks.h b/libpandabase/os/windows/mem_hooks.h index 4bcf50fb10..c65155564b 100644 --- a/libpandabase/os/windows/mem_hooks.h +++ b/libpandabase/os/windows/mem_hooks.h @@ -16,8 +16,8 @@ #ifndef PANDA_LIBPANDABASE_OS_WINDOWS_MEM_HOOKS_H_ #define PANDA_LIBPANDABASE_OS_WINDOWS_MEM_HOOKS_H_ -#include #include +#include namespace panda::os::windows::mem_hooks { diff --git a/libpandabase/tests/dfx_test.cpp b/libpandabase/tests/dfx_test.cpp index 78397552d0..c0dd9f1312 100644 --- a/libpandabase/tests/dfx_test.cpp +++ b/libpandabase/tests/dfx_test.cpp @@ -47,7 +47,7 @@ void MapDfxOption(std::map &option_map, Df case DfxOptionHandler::MOBILE_LOG: option_map[DfxOptionHandler::MOBILE_LOG] = 1; break; -#endif +#endif // PANDA_TARGET_UNIX case DfxOptionHandler::REFERENCE_DUMP: option_map[DfxOptionHandler::REFERENCE_DUMP] = 1; break; -- Gitee From 2965f7f719efc105e475daae2216387449d966c6 Mon Sep 17 00:00:00 2001 From: huangyu Date: Thu, 21 Apr 2022 16:21:15 +0800 Subject: [PATCH 13/14] Fix codestyle Signed-off-by: huangyu --- libpandabase/os/library_loader.h | 3 --- libpandabase/os/mutex.cpp | 4 ---- libpandabase/os/time.cpp | 2 -- libpandabase/os/time.h | 2 -- libpandabase/os/unique_fd.h | 2 -- libpandabase/os/unix/mem_hooks.cpp | 2 -- libpandabase/os/unix/mem_hooks.h | 2 -- libpandabase/os/unix/sighook.cpp | 8 +++----- libpandabase/os/unix/sighook.h | 2 -- libpandabase/os/unix/thread.cpp | 2 -- libpandabase/os/unix/time.h | 7 +++++-- libpandabase/os/unix/unique_fd.h | 2 -- libpandabase/os/windows/library_loader.cpp | 4 ---- libpandabase/os/windows/library_loader.h | 2 -- libpandabase/os/windows/mem_hooks.cpp | 6 ++---- libpandabase/os/windows/mem_hooks.h | 2 -- libpandabase/os/windows/time.h | 7 +++++-- libpandabase/os/windows/unique_fd.h | 2 -- libpandabase/tests/hash_test.cpp | 3 ++- 19 files changed, 17 insertions(+), 47 deletions(-) diff --git a/libpandabase/os/library_loader.h b/libpandabase/os/library_loader.h index 9e60ddf26e..e77ced28de 100644 --- a/libpandabase/os/library_loader.h +++ b/libpandabase/os/library_loader.h @@ -30,11 +30,8 @@ #include namespace panda::os::library_loader { - Expected Load(std::string_view filename); - Expected ResolveSymbol(const LibraryHandle &handle, std::string_view name); - } // namespace panda::os::library_loader #endif // PANDA_LIBPANDABASE_OS_LIBRARY_LOADER_H_ diff --git a/libpandabase/os/mutex.cpp b/libpandabase/os/mutex.cpp index b98ecad2b8..f8cad440c7 100644 --- a/libpandabase/os/mutex.cpp +++ b/libpandabase/os/mutex.cpp @@ -14,15 +14,12 @@ */ #include "mutex.h" - #include "utils/logger.h" #include - #include namespace panda::os::unix::memory { - const int64_t MILLISECONDS_PER_SEC = 1000; const int64_t NANOSECONDS_PER_MILLISEC = 1000000; const int64_t NANOSECONDS_PER_SEC = 1000000000; @@ -199,5 +196,4 @@ bool ConditionVariable::TimedWait(Mutex *mutex, uint64_t ms, uint64_t ns, bool i FatalIfError("pthread_cond_timedwait", rc); return false; } - } // namespace panda::os::unix::memory diff --git a/libpandabase/os/time.cpp b/libpandabase/os/time.cpp index 4b7019b11d..ac9d8f47f0 100644 --- a/libpandabase/os/time.cpp +++ b/libpandabase/os/time.cpp @@ -16,7 +16,6 @@ #include "os/time.h" namespace panda::os::time { - /** * Return current time in nanoseconds */ @@ -40,5 +39,4 @@ uint64_t GetClockTimeInThreadCpuTime() { return GetClockTime(CLOCK_THREAD_CPUTIME_ID); } - } // namespace panda::os::time diff --git a/libpandabase/os/time.h b/libpandabase/os/time.h index 028973f34f..d898fead7d 100644 --- a/libpandabase/os/time.h +++ b/libpandabase/os/time.h @@ -27,11 +27,9 @@ #include namespace panda::os::time { - uint64_t GetClockTimeInMicro(); uint64_t GetClockTimeInMilli(); uint64_t GetClockTimeInThreadCpuTime(); - } // namespace panda::os::time #endif // PANDA_LIBPANDABASE_OS_TIME_H_ diff --git a/libpandabase/os/unique_fd.h b/libpandabase/os/unique_fd.h index f43722cd1d..b3fe7d477b 100644 --- a/libpandabase/os/unique_fd.h +++ b/libpandabase/os/unique_fd.h @@ -30,7 +30,6 @@ #include namespace panda::os::unique_fd { - class UniqueFd { public: explicit UniqueFd(int fd = -1) noexcept @@ -91,7 +90,6 @@ private: int fd_ = -1; }; - } // namespace panda::os::unique_fd #endif // PANDA_LIBPANDABASE_OS_UNIQUE_FD_H_ diff --git a/libpandabase/os/unix/mem_hooks.cpp b/libpandabase/os/unix/mem_hooks.cpp index 4eba650257..aabbe7110b 100644 --- a/libpandabase/os/unix/mem_hooks.cpp +++ b/libpandabase/os/unix/mem_hooks.cpp @@ -20,7 +20,6 @@ #include "mem_hooks.h" namespace panda::os::unix::mem_hooks { - size_t PandaHooks::alloc_via_standard = 0; void *(*volatile PandaHooks::old_malloc_hook)(size_t, const void *) = nullptr; void *(*volatile PandaHooks::old_memalign_hook)(size_t, size_t, const void *) = nullptr; @@ -113,5 +112,4 @@ void PandaHooks::Disable() __free_hook = old_free_hook; #endif // __MUSL__ } - } // namespace panda::os::unix::mem_hooks diff --git a/libpandabase/os/unix/mem_hooks.h b/libpandabase/os/unix/mem_hooks.h index d1c9260c25..8a21884f55 100644 --- a/libpandabase/os/unix/mem_hooks.h +++ b/libpandabase/os/unix/mem_hooks.h @@ -19,7 +19,6 @@ #include "libpandabase/mem/mem.h" namespace panda::os::unix::mem_hooks { - class PandaHooks { public: static void Enable(); @@ -48,7 +47,6 @@ private: static size_t alloc_via_standard; }; - } // namespace panda::os::unix::mem_hooks namespace panda::os::mem_hooks { diff --git a/libpandabase/os/unix/sighook.cpp b/libpandabase/os/unix/sighook.cpp index dcfe2ce09a..c93a1b0c1c 100644 --- a/libpandabase/os/unix/sighook.cpp +++ b/libpandabase/os/unix/sighook.cpp @@ -13,9 +13,6 @@ * limitations under the License. */ -#include "os/sighook.h" - -#include "utils/logger.h" #include #include // NOLINTNEXTLINE(modernize-deprecated-headers) #include // NOLINTNEXTLINE(modernize-deprecated-headers) @@ -24,6 +21,9 @@ #include // NOLINTNEXTLINE(modernize-deprecated-headers) #include +#include "os/sighook.h" +#include "utils/logger.h" + #include #include #include @@ -35,7 +35,6 @@ #include namespace panda { - static decltype(&sigaction) real_sigaction; static decltype(&sigprocmask) real_sigprocmask; static bool g_is_init_really {false}; @@ -495,5 +494,4 @@ void ClearSignalHooksHandlersArray() signal_hooks[i].ClearHookActionHandlers(); } } - } // namespace panda diff --git a/libpandabase/os/unix/sighook.h b/libpandabase/os/unix/sighook.h index e56ae7da83..63baff2d42 100644 --- a/libpandabase/os/unix/sighook.h +++ b/libpandabase/os/unix/sighook.h @@ -20,7 +20,6 @@ #include // NOLINTNEXTLINE(modernize-deprecated-headers) namespace panda { - #if PANDA_TARGET_MACOS && !defined _NSIG #define _NSIG NSIG #endif @@ -49,7 +48,6 @@ struct SigchainAction { extern "C" void AddSpecialSignalHandlerFn(int signal, SigchainAction *sa); extern "C" void RemoveSpecialSignalHandlerFn(int signal, bool (*fn)(int, siginfo_t *, void *)); extern "C" void EnsureFrontOfChain(int signal); - } // namespace panda #endif // PANDA_LIBPANDABASE_OS_UNIX_SIGHOOK_H_ diff --git a/libpandabase/os/unix/thread.cpp b/libpandabase/os/unix/thread.cpp index ff7e8bf116..28d5f1929f 100644 --- a/libpandabase/os/unix/thread.cpp +++ b/libpandabase/os/unix/thread.cpp @@ -23,7 +23,6 @@ #include namespace panda::os::thread { - ThreadId GetCurrentThreadId() { #if defined(HAVE_GETTID) @@ -88,5 +87,4 @@ void ThreadJoin(native_handle_type pthread_id, void **retval) { pthread_join(pthread_id, retval); } - } // namespace panda::os::thread diff --git a/libpandabase/os/unix/time.h b/libpandabase/os/unix/time.h index 04995ae16d..e568fec065 100644 --- a/libpandabase/os/unix/time.h +++ b/libpandabase/os/unix/time.h @@ -13,10 +13,12 @@ * limitations under the License. */ +#ifndef PANDA_LIBPANDABASE_OS_UNIX_TIME_H_ +#define PANDA_LIBPANDABASE_OS_UNIX_TIME_H_ + #include namespace panda::os::time { - template static uint64_t GetClockTime(clockid_t clock) { @@ -27,5 +29,6 @@ static uint64_t GetClockTime(clockid_t clock) } return 0; } - } // namespace panda::os::time + +#endif // PANDA_LIBPANDABASE_OS_UNIX_TIME_H_ diff --git a/libpandabase/os/unix/unique_fd.h b/libpandabase/os/unix/unique_fd.h index 977054b9a8..e8a390b9a9 100644 --- a/libpandabase/os/unix/unique_fd.h +++ b/libpandabase/os/unix/unique_fd.h @@ -19,12 +19,10 @@ #include namespace panda::os::unique_fd { - inline int DupCloexec(int fd) { return fcntl(fd, F_DUPFD_CLOEXEC, 0); } - } // namespace panda::os::unique_fd #endif // PANDA_LIBPANDABASE_OS_UNIX_UNIQUE_FD_H_ diff --git a/libpandabase/os/windows/library_loader.cpp b/libpandabase/os/windows/library_loader.cpp index a9dded0063..24449ecd35 100644 --- a/libpandabase/os/windows/library_loader.cpp +++ b/libpandabase/os/windows/library_loader.cpp @@ -18,7 +18,6 @@ #include namespace panda::os::library_loader { - Expected Load(std::string_view filename) { HMODULE module = LoadLibrary(filename.data()); @@ -40,16 +39,13 @@ Expected ResolveSymbol(const LibraryHandle &handle, std::string_v return Unexpected(Error(std::string("Failed to resolve symbol ") + name.data() + std::string(", error code ") + std::to_string(GetLastError()))); } - } // namespace panda::os::library_loader namespace panda::os::windows::library_loader { - LibraryHandle::~LibraryHandle() { if (handle_ != nullptr) { FreeLibrary(reinterpret_cast(handle_)); } } - } // namespace panda::os::windows::library_loader diff --git a/libpandabase/os/windows/library_loader.h b/libpandabase/os/windows/library_loader.h index 9a82abc9e4..8d8efabb4e 100644 --- a/libpandabase/os/windows/library_loader.h +++ b/libpandabase/os/windows/library_loader.h @@ -19,7 +19,6 @@ #include "macros.h" namespace panda::os::windows::library_loader { - class LibraryHandle { public: explicit LibraryHandle(void *handle) : handle_(handle) {} @@ -54,7 +53,6 @@ private: NO_COPY_SEMANTIC(LibraryHandle); }; - } // namespace panda::os::windows::library_loader namespace panda::os::library_loader { diff --git a/libpandabase/os/windows/mem_hooks.cpp b/libpandabase/os/windows/mem_hooks.cpp index 42fdff7ccf..eb0b62876c 100644 --- a/libpandabase/os/windows/mem_hooks.cpp +++ b/libpandabase/os/windows/mem_hooks.cpp @@ -13,13 +13,12 @@ * limitations under the License. */ -#include "mem_hooks.h" +#include "os/mem_hooks.h" #include #include namespace panda::os::windows::mem_hooks { - volatile bool enable = false; static bool first = true; @@ -51,7 +50,7 @@ static const char *GetBlockTypeName(int bt) } } -int PandaAllocHook(int alloctype, [[maybe_unused]] void *data, std::size_t size, int blocktype, +int PandaHooks::PandaAllocHook(int alloctype, [[maybe_unused]] void *data, std::size_t size, int blocktype, [[maybe_unused]] long request, const unsigned char *filename, int linenumber) { if (!enable) { @@ -111,5 +110,4 @@ void PandaHooks::Disable() _CrtDumpMemoryLeaks(); } } - } // namespace panda::os::windows::mem_hooks diff --git a/libpandabase/os/windows/mem_hooks.h b/libpandabase/os/windows/mem_hooks.h index c65155564b..e703873813 100644 --- a/libpandabase/os/windows/mem_hooks.h +++ b/libpandabase/os/windows/mem_hooks.h @@ -20,7 +20,6 @@ #include namespace panda::os::windows::mem_hooks { - class PandaHooks { public: static void Enable(); @@ -39,7 +38,6 @@ private: static _CrtMemState begin, end, out; }; - } // namespace panda::os::windows::mem_hooks namespace panda::os::mem_hooks { diff --git a/libpandabase/os/windows/time.h b/libpandabase/os/windows/time.h index 296cd40861..35b8eb6a18 100644 --- a/libpandabase/os/windows/time.h +++ b/libpandabase/os/windows/time.h @@ -13,11 +13,13 @@ * limitations under the License. */ +#ifndef PANDA_LIBPANDABASE_OS_WINDOWS_TIME_H_ +#define PANDA_LIBPANDABASE_OS_WINDOWS_TIME_H_ + #include #include namespace panda::os::time { - template static uint64_t GetClockTime([[maybe_unused]] clockid_t clock) { @@ -28,5 +30,6 @@ static uint64_t GetClockTime([[maybe_unused]] clockid_t clock) } return 0; } - } // namespace panda::os::time + +#endif // PANDA_LIBPANDABASE_OS_WINDOWS_TIME_H_ diff --git a/libpandabase/os/windows/unique_fd.h b/libpandabase/os/windows/unique_fd.h index d88bffda29..b26c0c823f 100644 --- a/libpandabase/os/windows/unique_fd.h +++ b/libpandabase/os/windows/unique_fd.h @@ -19,13 +19,11 @@ #include "libpandabase/macros.h" namespace panda::os::unique_fd { - inline int DupCloexec([[maybe_unused]] int fd) { // Unsupported on windows platform UNREACHABLE(); } - } // namespace panda::os::unique_fd #endif // PANDA_LIBPANDABASE_OS_WINDOWS_UNIQUE_FD_H_ diff --git a/libpandabase/tests/hash_test.cpp b/libpandabase/tests/hash_test.cpp index 61a51d843c..e67c1bfba6 100644 --- a/libpandabase/tests/hash_test.cpp +++ b/libpandabase/tests/hash_test.cpp @@ -119,7 +119,8 @@ void HashTest::EndOfPageStringHashTest() const constexpr size_t ALLOC_SIZE = PAGE_SIZE * 2; void *mem = panda::os::mem::MapRWAnonymousRaw(ALLOC_SIZE); ASAN_UNPOISON_MEMORY_REGION(mem, ALLOC_SIZE); - panda::os::mem::MakeMemWithProtFlag(reinterpret_cast(reinterpret_cast(mem) + PAGE_SIZE), PAGE_SIZE, PROT_NONE); + panda::os::mem::MakeMemWithProtFlag( + reinterpret_cast(reinterpret_cast(mem) + PAGE_SIZE), PAGE_SIZE, PROT_NONE); char *string = reinterpret_cast((reinterpret_cast(mem) + PAGE_SIZE) - sizeof(char) * string_size); string[0] = 'O'; -- Gitee From 279b5b397182c1a7f9ccc922d915b20017a71c8f Mon Sep 17 00:00:00 2001 From: huangyu Date: Fri, 22 Apr 2022 15:36:19 +0800 Subject: [PATCH 14/14] Fix codecheck Signed-off-by: huangyu Change-Id: I3218e03650ce7a8724e473a21592b68f0bf91124 --- libpandabase/os/unix/sighook.cpp | 2 +- libpandabase/os/windows/mem_hooks.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libpandabase/os/unix/sighook.cpp b/libpandabase/os/unix/sighook.cpp index c93a1b0c1c..d19ea82990 100644 --- a/libpandabase/os/unix/sighook.cpp +++ b/libpandabase/os/unix/sighook.cpp @@ -21,8 +21,8 @@ #include // NOLINTNEXTLINE(modernize-deprecated-headers) #include -#include "os/sighook.h" #include "utils/logger.h" +#include "os/sighook.h" #include #include diff --git a/libpandabase/os/windows/mem_hooks.cpp b/libpandabase/os/windows/mem_hooks.cpp index eb0b62876c..741f7a8959 100644 --- a/libpandabase/os/windows/mem_hooks.cpp +++ b/libpandabase/os/windows/mem_hooks.cpp @@ -51,7 +51,7 @@ static const char *GetBlockTypeName(int bt) } int PandaHooks::PandaAllocHook(int alloctype, [[maybe_unused]] void *data, std::size_t size, int blocktype, - [[maybe_unused]] long request, const unsigned char *filename, int linenumber) + [[maybe_unused]] long request, const unsigned char *filename, int linenumber) { if (!enable) { return true; -- Gitee