Skip to content

Commit

Permalink
Improve compilation times on Windows (#172)
Browse files Browse the repository at this point in the history
Thank you for the very useful library!

Few improvements:
- Better header hygiene
- Isolate `windows.h` to `.cpp` whenever possible
- Use `WIN32_LEAN_AND_MEAN`
- Remove unused headers

Tested on Windows with 
```
cmake .. -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=1 
  -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS="-ftime-trace -Wall -Wextra -Wpedantic 
  -Wno-ignored-attributes" -DCMAKE_COLOR_DIAGNOSTICS=1 -DCPPTRACE_BUILD_TESTING=1 
  -DCPPTRACE_BUILD_BENCHMARKING=0
```

There's a lot more that can be improved if you are interested.

---------

Co-authored-by: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com>
  • Loading branch information
vittorioromeo and jeremy-rifkin authored Oct 2, 2024
1 parent 4ed90c1 commit 0ddbbf4
Show file tree
Hide file tree
Showing 44 changed files with 220 additions and 156 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

- [Changelog](#changelog)
- [v0.7.1](#v071)
- [v0.7.0](#v070)
- [v0.6.3](#v063)
- [v0.6.2](#v062)
Expand All @@ -20,6 +21,24 @@
- [v0.1.1](#v011)
- [v0.1](#v01)

# v0.7.1

Added
- Better support for finding libunwind on macos https://github.com/jeremy-rifkin/cpptrace/pull/162
- Support for libbacktrace under mingw https://github.com/jeremy-rifkin/cpptrace/pull/166

Fixed
- Computation of object address for safe object frames https://github.com/jeremy-rifkin/cpptrace/issues/169
- Nested microfmt in cpptrace's namespace due to an ODR problem with libassert https://github.com/jeremy-rifkin/libassert/issues/103
- Compilation on iOS https://github.com/jeremy-rifkin/cpptrace/pull/167
- Compilation on old MSVC https://github.com/jeremy-rifkin/cpptrace/pull/165
- Dbghelp use on 32 bit https://github.com/jeremy-rifkin/cpptrace/issues/170
- Warning in brand new cmake due to `FetchContent_Populate` being deprecated https://github.com/jeremy-rifkin/cpptrace/issues/171

Other changes
- Bumped the buffer size for execinfo and CaptureStackBackTrace to 400 frames
- Switched to execinfo.h for unwinding on clang/apple clang on macos due to `_Unwind` not working with `-fno-exceptions` https://github.com/jeremy-rifkin/cpptrace/issues/161

# v0.7.0

Added
Expand Down
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ set(package_name "cpptrace")

project(
cpptrace
VERSION 0.7.0
VERSION 0.7.1
DESCRIPTION "Simple, portable, and self-contained stacktrace library for C++11 and newer "
HOMEPAGE_URL "https://github.com/jeremy-rifkin/cpptrace"
LANGUAGES C CXX
Expand Down Expand Up @@ -246,6 +246,9 @@ target_sources(
src/unwind/unwind_with_nothing.cpp
src/unwind/unwind_with_unwind.cpp
src/unwind/unwind_with_winapi.cpp
src/utils/microfmt.cpp
src/utils/utils.cpp
src/platform/dbghelp_syminit_manager.cpp
)

target_include_directories(
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ include(FetchContent)
FetchContent_Declare(
cpptrace
GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git
GIT_TAG v0.7.0 # <HASH or TAG>
GIT_TAG v0.7.1 # <HASH or TAG>
)
FetchContent_MakeAvailable(cpptrace)
target_link_libraries(your_target cpptrace::cpptrace)
Expand Down Expand Up @@ -793,7 +793,7 @@ include(FetchContent)
FetchContent_Declare(
cpptrace
GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git
GIT_TAG v0.7.0 # <HASH or TAG>
GIT_TAG v0.7.1 # <HASH or TAG>
)
FetchContent_MakeAvailable(cpptrace)
target_link_libraries(your_target cpptrace::cpptrace)
Expand All @@ -809,7 +809,7 @@ information.

```sh
git clone https://github.com/jeremy-rifkin/cpptrace.git
git checkout v0.7.0
git checkout v0.7.1
mkdir cpptrace/build
cd cpptrace/build
cmake .. -DCMAKE_BUILD_TYPE=Release
Expand Down Expand Up @@ -852,7 +852,7 @@ you when installing new libraries.
```ps1
git clone https://github.com/jeremy-rifkin/cpptrace.git
git checkout v0.7.0
git checkout v0.7.1
mkdir cpptrace/build
cd cpptrace/build
cmake .. -DCMAKE_BUILD_TYPE=Release
Expand All @@ -870,7 +870,7 @@ To install just for the local user (or any custom prefix):

```sh
git clone https://github.com/jeremy-rifkin/cpptrace.git
git checkout v0.7.0
git checkout v0.7.1
mkdir cpptrace/build
cd cpptrace/build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/wherever
Expand Down Expand Up @@ -953,7 +953,7 @@ make install
cd ~/scratch/cpptrace-test
git clone https://github.com/jeremy-rifkin/cpptrace.git
cd cpptrace
git checkout v0.7.0
git checkout v0.7.1
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=On -DCPPTRACE_USE_EXTERNAL_LIBDWARF=On -DCMAKE_PREFIX_PATH=~/scratch/cpptrace-test/resources -DCMAKE_INSTALL_PREFIX=~/scratch/cpptrace-test/resources
Expand All @@ -973,7 +973,7 @@ cpptrace and its dependencies.
Cpptrace is available through conan at https://conan.io/center/recipes/cpptrace.
```
[requires]
cpptrace/0.7.0
cpptrace/0.7.1
[generators]
CMakeDeps
CMakeToolchain
Expand Down
1 change: 1 addition & 0 deletions cmake/has_stackwalk.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <dbghelp.h>

Expand Down
4 changes: 1 addition & 3 deletions src/binary/module_base.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#include "binary/module_base.hpp"

#include "utils/common.hpp"
#include "platform/platform.hpp"
#include "utils/utils.hpp"

#include <string>
#include <vector>
#include <mutex>
#include <unordered_map>

Expand All @@ -17,7 +16,6 @@
#include "binary/elf.hpp"
#endif
#elif IS_WINDOWS
#include <windows.h>
#include "binary/pe.hpp"
#endif

Expand Down
1 change: 0 additions & 1 deletion src/binary/module_base.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef IMAGE_MODULE_BASE_HPP
#define IMAGE_MODULE_BASE_HPP

#include "utils/common.hpp"
#include "utils/utils.hpp"

#include <cstdint>
Expand Down
3 changes: 2 additions & 1 deletion src/binary/object.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "binary/object.hpp"

#include "utils/common.hpp"
#include "platform/platform.hpp"
#include "utils/utils.hpp"
#include "binary/module_base.hpp"

Expand All @@ -16,6 +16,7 @@
#include <link.h> // needed for dladdr1's link_map info
#endif
#elif IS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

Expand Down
12 changes: 7 additions & 5 deletions src/binary/object.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#ifndef OBJECT_HPP
#define OBJECT_HPP

#include "utils/common.hpp"
#include "utils/utils.hpp"
#include "binary/module_base.hpp"

#include <string>
#include <vector>
#include <cstdint>

namespace cpptrace {

struct object_frame;
struct safe_object_frame;

using frame_ptr = std::uintptr_t;

namespace detail {
object_frame get_frame_object_info(frame_ptr address);

Expand Down
4 changes: 2 additions & 2 deletions src/binary/pe.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#include "binary/pe.hpp"

#include "utils/common.hpp"
#include "platform/platform.hpp"
#include "utils/error.hpp"
#include "utils/utils.hpp"

#if IS_WINDOWS
#include <array>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <string>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

namespace cpptrace {
Expand Down
2 changes: 1 addition & 1 deletion src/binary/pe.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef PE_HPP
#define PE_HPP

#include "utils/common.hpp"
#include "platform/platform.hpp"
#include "utils/utils.hpp"

#if IS_WINDOWS
Expand Down
2 changes: 2 additions & 0 deletions src/cpptrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <new>
#include <sstream>
#include <stdexcept>
Expand All @@ -16,6 +17,7 @@
#include "demangle/demangle.hpp"
#include "platform/exception_type.hpp"
#include "utils/common.hpp"
#include "utils/microfmt.hpp"
#include "utils/utils.hpp"
#include "binary/object.hpp"
#include "binary/safe_dl.hpp"
Expand Down
1 change: 1 addition & 0 deletions src/demangle/demangle_with_winapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <string>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <dbghelp.h>

Expand Down
6 changes: 2 additions & 4 deletions src/from_current.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
#include <typeinfo>

#include "platform/platform.hpp"
#include "utils/common.hpp"
#include "utils/microfmt.hpp"
#include "utils/utils.hpp"

#ifndef _MSC_VER
#include <array>
#include <string.h>
#if IS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <sys/mman.h>
Expand All @@ -25,7 +23,7 @@
#endif
#else
#include <fstream>
#include <iomanip>
#include <ios>
#endif
#endif
#endif
Expand Down
45 changes: 45 additions & 0 deletions src/platform/dbghelp_syminit_manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "platform/platform.hpp"

#if IS_WINDOWS

#include "platform/dbghelp_syminit_manager.hpp"

#include "utils/error.hpp"
#include "utils/microfmt.hpp"

#include <unordered_set>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <dbghelp.h>

namespace cpptrace {
namespace detail {

dbghelp_syminit_manager::~dbghelp_syminit_manager() {
for(auto handle : set) {
if(!SymCleanup(handle)) {
ASSERT(false, microfmt::format("Cpptrace SymCleanup failed with code {}\n", GetLastError()).c_str());
}
}
}

void dbghelp_syminit_manager::init(HANDLE proc) {
if(set.count(proc) == 0) {
if(!SymInitialize(proc, NULL, TRUE)) {
throw internal_error("SymInitialize failed {}", GetLastError());
}
set.insert(proc);
}
}

// Thread-safety: Must only be called from symbols_with_dbghelp while the dbghelp_lock lock is held
dbghelp_syminit_manager& get_syminit_manager() {
static dbghelp_syminit_manager syminit_manager;
return syminit_manager;
}

}
}

#endif
33 changes: 6 additions & 27 deletions src/platform/dbghelp_syminit_manager.hpp
Original file line number Diff line number Diff line change
@@ -1,42 +1,21 @@
#ifndef DBGHELP_SYMINIT_MANAGER_HPP
#define DBGHELP_SYMINIT_MANAGER_HPP

#include "utils/common.hpp"
#include "utils/utils.hpp"

#include <unordered_set>

#include <windows.h>
#include <dbghelp.h>

namespace cpptrace {
namespace detail {
struct dbghelp_syminit_manager {
std::unordered_set<HANDLE> set;

~dbghelp_syminit_manager() {
for(auto handle : set) {
if(!SymCleanup(handle)) {
ASSERT(false, microfmt::format("Cpptrace SymCleanup failed with code {}\n", GetLastError()).c_str());
}
}
}
// The set below contains Windows `HANDLE` objects, `void*` is used to avoid
// including the (expensive) Windows header here
std::unordered_set<void*> set;

void init(HANDLE proc) {
if(set.count(proc) == 0) {
if(!SymInitialize(proc, NULL, TRUE)) {
throw internal_error("SymInitialize failed {}", GetLastError());
}
set.insert(proc);
}
}
~dbghelp_syminit_manager();
void init(void* proc);
};

// Thread-safety: Must only be called from symbols_with_dbghelp while the dbghelp_lock lock is held
inline dbghelp_syminit_manager& get_syminit_manager() {
static dbghelp_syminit_manager syminit_manager;
return syminit_manager;
}
dbghelp_syminit_manager& get_syminit_manager();
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/platform/path.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#ifndef PATH_HPP
#define PATH_HPP

#include "utils/common.hpp"
#include "platform/platform.hpp"

#include <string>
#include <cctype>

#if IS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

Expand Down
1 change: 1 addition & 0 deletions src/platform/program_name.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "platform/platform.hpp"

#if IS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define CPPTRACE_MAX_PATH MAX_PATH
Expand Down
1 change: 1 addition & 0 deletions src/snippets/snippet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <iostream>

#include "utils/common.hpp"
#include "utils/microfmt.hpp"
#include "utils/utils.hpp"

namespace cpptrace {
Expand Down
Loading

0 comments on commit 0ddbbf4

Please sign in to comment.