Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,30 @@ jobs:
ninja
./unittest

unittest-cygwin:
runs-on: windows-2022
needs: unittest-linux
steps:
- uses: actions/checkout@v4
- name: Install Cygwin
uses: cygwin/cygwin-install-action@v4
with:
packages: cmake gcc-g++ ninja git
- name: build and test
shell: C:\cygwin\bin\bash.exe --login -o igncr {0}
run: |
cd "$GITHUB_WORKSPACE"
mkdir build
cd build
cmake .. \
-GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DCPPTRACE_WERROR_BUILD=On \
-DCPPTRACE_STD_FORMAT=Off \
-DCPPTRACE_BUILD_TESTING=On
ninja
./unittest.exe

unittest-windows-32-bit:
runs-on: windows-2022
needs: unittest-windows
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ if(CPPTRACE_GET_SYMBOLS_WITH_DBGHELP)
target_link_libraries(${target_name} PRIVATE dbghelp)
endif()

if(CYGWIN)
target_link_libraries(${target_name} PRIVATE kernel32)
endif()

if(CPPTRACE_GET_SYMBOLS_WITH_NOTHING)
target_compile_definitions(${target_name} PRIVATE CPPTRACE_GET_SYMBOLS_WITH_NOTHING)
endif()
Expand Down
4 changes: 2 additions & 2 deletions src/binary/module_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#else
#include "binary/elf.hpp"
#endif
#elif IS_WINDOWS
#elif IS_WINDOWS || IS_CYGWIN
#include "binary/pe.hpp"
#endif

Expand Down Expand Up @@ -72,7 +72,7 @@ namespace detail {
return it->second;
}
}
#else // Windows
#else // Windows / Cygwin
Result<std::uintptr_t, internal_error> get_module_image_base(const std::string& object_path) {
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
Expand Down
4 changes: 2 additions & 2 deletions src/binary/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
#if IS_LINUX || IS_APPLE
#include <unistd.h>
#include <dlfcn.h>
#if IS_LINUX
#if IS_LINUX && (defined(CPPTRACE_HAS_DL_FIND_OBJECT) || defined(CPPTRACE_HAS_DLADDR1))
#include <link.h> // needed for dladdr1's link_map info
#endif
#elif IS_WINDOWS
#elif IS_WINDOWS || IS_CYGWIN
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
Expand Down
17 changes: 12 additions & 5 deletions src/binary/pe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "utils/error.hpp"
#include "utils/utils.hpp"

#if IS_WINDOWS
#if IS_WINDOWS || IS_CYGWIN
#include <array>
#include <cstdio>
#include <cstring>
Expand Down Expand Up @@ -32,11 +32,18 @@ namespace detail {
// https://0xrick.github.io/win-internals/pe3/
// Endianness should always be little for dos and pe headers
std::FILE* file_ptr;
errno_t ret = fopen_s(&file_ptr, object_path.c_str(), "rb");
#ifdef __CYGWIN__
file_ptr = std::fopen(object_path.c_str(), "rb");
if(!file_ptr) {
return internal_error("Unable to read object file {}", object_path);
}
#else
errno_t ret = fopen_s(&file_ptr, object_path.c_str(), "rb");
if(ret != 0 || file_ptr == nullptr) {
return internal_error("Unable to read object file {}", object_path);
}
#endif
auto file = raii_wrap(std::move(file_ptr), file_deleter);
if(ret != 0 || file == nullptr) {
return internal_error("Unable to read object file {}", object_path);
}
auto magic = load_bytes<std::array<char, 2>>(file, 0);
if(!magic) {
return std::move(magic).unwrap_error();
Expand Down
2 changes: 1 addition & 1 deletion src/binary/pe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "platform/platform.hpp"
#include "utils/utils.hpp"

#if IS_WINDOWS
#if IS_WINDOWS || IS_CYGWIN
#include <cstdint>
#include <string>

Expand Down
2 changes: 1 addition & 1 deletion src/from_current.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ namespace detail {
if(type_info_addr - page_addr + sizeof(void*) > static_cast<unsigned>(page_size)) {
throw internal_error("pointer crosses page boundaries");
}
#if IS_WINDOWS
#if IS_WINDOWS || IS_CYGWIN
auto old_protections = mprotect_page_and_return_old_protections(
reinterpret_cast<void*>(page_addr),
page_size,
Expand Down
7 changes: 5 additions & 2 deletions src/platform/memory_mapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#ifndef _MSC_VER

#if IS_WINDOWS
#if IS_WINDOWS || IS_CYGWIN
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
Expand All @@ -31,7 +31,10 @@

CPPTRACE_BEGIN_NAMESPACE
namespace detail {
#if IS_WINDOWS
#if IS_WINDOWS || IS_CYGWIN
// Cygwin uses GCC/Itanium ABI but Cygwin's mprotect seems to require 64KB-aligned addresses (allocation
// granularity returned by sysconf(_SC_PAGESIZE)) while we need actual page granularity for typeinfo surgery.
// Using the windows API here works best.
int get_page_size() {
SYSTEM_INFO info;
GetSystemInfo(&info);
Expand Down
6 changes: 3 additions & 3 deletions src/platform/memory_mapping.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#ifndef _MSC_VER

#if IS_WINDOWS
#if IS_WINDOWS || IS_CYGWIN
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
Expand All @@ -13,15 +13,15 @@

CPPTRACE_BEGIN_NAMESPACE
namespace detail {
#if IS_WINDOWS
#if IS_WINDOWS || IS_CYGWIN
constexpr auto memory_readonly = PAGE_READONLY;
constexpr auto memory_readwrite = PAGE_READWRITE;
#else
constexpr auto memory_readonly = PROT_READ;
constexpr auto memory_readwrite = PROT_READ | PROT_WRITE;
#endif
int get_page_size();
#if !IS_WINDOWS
#if !IS_WINDOWS && !IS_CYGWIN
int get_page_protections(void* page);
#endif
int mprotect_page_and_return_old_protections(void* page, int page_size, int protections);
Expand Down
4 changes: 4 additions & 0 deletions src/platform/platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
#define IS_WINDOWS 0
#define IS_LINUX 0
#define IS_APPLE 0
#define IS_CYGWIN 0

#if defined(_WIN32)
#undef IS_WINDOWS
#define IS_WINDOWS 1
#elif defined(__CYGWIN__)
#undef IS_CYGWIN
#define IS_CYGWIN 1
#elif defined(__linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#undef IS_LINUX
#define IS_LINUX 1
Expand Down
2 changes: 1 addition & 1 deletion src/platform/program_name.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ namespace detail {
}
CPPTRACE_END_NAMESPACE

#elif IS_LINUX
#elif IS_LINUX || IS_CYGWIN

#include <sys/types.h>
#include <unistd.h>
Expand Down
4 changes: 2 additions & 2 deletions src/symbols/symbols_with_addr2line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <utility>
#include <vector>

#if IS_LINUX || IS_APPLE
#if IS_LINUX || IS_APPLE || IS_CYGWIN
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
Expand All @@ -27,7 +27,7 @@
CPPTRACE_BEGIN_NAMESPACE
namespace detail {
namespace addr2line {
#if IS_LINUX || IS_APPLE
#if IS_LINUX || IS_APPLE || IS_CYGWIN
bool has_addr2line() {
static std::mutex mutex;
static bool has_addr2line = false;
Expand Down
Loading