Skip to content

Commit ed4871d

Browse files
authored
Merge pull request #4 from DoctorLai/asan
Address Sanitizer
2 parents c2ef799 + f01e95c commit ed4871d

File tree

5 files changed

+131
-28
lines changed

5 files changed

+131
-28
lines changed

.github/workflows/ci.yml

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,37 @@
1-
name: C++ Build
1+
name: C++ CI
22

33
on:
44
push:
5+
branches: [main]
56
pull_request:
7+
branches: [main]
68

79
jobs:
8-
build:
10+
build-and-run:
911
runs-on: ubuntu-latest
10-
11-
strategy:
12-
matrix:
13-
compiler: [g++]
14-
12+
env:
13+
ASAN_OPTIONS: detect_leaks=1 # automatically detect memory leaks
1514
steps:
16-
- name: Checkout repo
15+
# 1. Checkout repo
16+
- name: Checkout code
1717
uses: actions/checkout@v4
1818

19+
# 2. Install build tools
1920
- name: Install build tools
2021
run: |
2122
sudo apt-get update
22-
sudo apt-get install -y build-essential
23-
24-
- name: Build all examples
25-
run: |
26-
make
23+
sudo apt-get install -y build-essential g++ clang
2724
28-
- name: Run examples
25+
# 3. Build and run all examples dynamically
26+
- name: Build and Run
2927
run: |
30-
for dir in */ ; do
31-
if [ -f "$dir/Makefile" ]; then
32-
echo "Running $dir"
33-
(cd "$dir" && make run || true)
34-
fi
28+
for san in address thread undefined; do
29+
echo "=== Building all examples with sanitizer $san ==="
30+
make SANITIZE=$san
31+
echo "=== Running all examples with sanitizer $san ==="
32+
make run
3533
done
3634
37-
- name: Clean
35+
- name: Clean up build artifacts
3836
run: |
3937
make clean

.gitignore

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,17 @@
1-
.o
1+
# Object files
2+
*.o
3+
4+
# Executable
5+
thread_safe_queue
6+
unique_ptr_basics
7+
*.out
8+
9+
# Backup files
10+
*~
11+
*.swp
12+
13+
# CMake / IDE files
14+
CMakeFiles/
15+
CMakeCache.txt
16+
*.idea/
17+
*.vscode/

Makefile

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,37 @@
1+
# ======================================
2+
# Top-level Makefile for cpp-coding-exercise
3+
# ======================================
4+
5+
# Auto-detect all subdirectories that contain a Makefile
16
SUBDIRS := $(dir $(wildcard */Makefile))
27

3-
.PHONY: all clean $(SUBDIRS)
8+
# Default sanitizer (can be overridden)
9+
SANITIZE ?= address
10+
11+
.PHONY: all clean run $(SUBDIRS)
412

13+
# --------------------------
14+
# Build all examples
15+
# --------------------------
516
all: $(SUBDIRS)
617

718
$(SUBDIRS):
8-
$(MAKE) -C $@
19+
@echo "=== Building $@ with SANITIZE=$(SANITIZE) ==="
20+
$(MAKE) -C $@ SANITIZE=$(SANITIZE)
21+
22+
# --------------------------
23+
# Run all examples (optional)
24+
# --------------------------
25+
run:
26+
@for dir in $(SUBDIRS); do \
27+
echo "=== Running $$dir ==="; \
28+
(cd $$dir && $(MAKE) SANITIZE=$(SANITIZE) run) || exit 1; \
29+
done
930

31+
# --------------------------
32+
# Clean all examples
33+
# --------------------------
1034
clean:
11-
for dir in $(SUBDIRS); do \
35+
@for dir in $(SUBDIRS); do \
1236
$(MAKE) -C $$dir clean; \
1337
done

README.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Runnable examples expose a `run` target:
7474
make run
7575
```
7676

77-
This keeps CI safe (build-only by default) while allowing local execution.
77+
`make run` on top level will run all built targets.
7878

7979
---
8080

@@ -97,11 +97,11 @@ make clean
9797

9898
## Shared build configuration
9999

100-
Common compiler settings live in `common.mk`:
100+
Common compiler settings live in [common.mk](./common.mk):
101101

102102
```make
103103
CXX := g++
104-
CXXFLAGS := -std=c++20 -O2 -Wall -Wextra
104+
CXXFLAGS := -std=c++20 -Wall -Wextra
105105
```
106106

107107
Individual examples may extend this, e.g.:
@@ -112,6 +112,25 @@ CXXFLAGS += -pthread
112112

113113
---
114114

115+
## Address Sanitizer Check
116+
The Address Sanitizer is enabled by default to ensure there is no memory leaks or other memory problems.
117+
118+
```make
119+
# Builds with AddressSanitizer automatically
120+
make
121+
122+
# ThreadSanitizer
123+
make SANITIZE=thread
124+
125+
# UndefinedBehaviorSanitizer
126+
make SANITIZE=undefined
127+
128+
# No sanitizers
129+
make SANITIZE=
130+
```
131+
132+
---
133+
115134
## Continuous Integration
116135

117136
GitHub Actions automatically builds all examples on:

common.mk

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,48 @@
1+
# ======================================
2+
# common.mk - shared compiler flags
3+
# ======================================
4+
15
CXX := g++
2-
CXXFLAGS := -std=c++20 -O2 -Wall -Wextra
6+
OPTFLAGS ?= -O1 -g # Safe for ASAN/TSAN (default)
7+
8+
# --------------------------
9+
# Sanitizer selection
10+
# --------------------------
11+
# Default: AddressSanitizer
12+
SANITIZE ?= address
13+
14+
ifeq ($(SANITIZE),address)
15+
SAN_FLAGS := -fsanitize=address
16+
else ifeq ($(SANITIZE),thread)
17+
SAN_FLAGS := -fsanitize=thread
18+
else ifeq ($(SANITIZE),undefined)
19+
SAN_FLAGS := -fsanitize=undefined
20+
else ifeq ($(SANITIZE),)
21+
SAN_FLAGS :=
22+
else
23+
$(error Unknown SANITIZE=$(SANITIZE))
24+
endif
25+
26+
# --------------------------
27+
# Compiler / Linker flags
28+
# --------------------------
29+
CXXFLAGS := -std=c++20 -Wall -Wextra $(OPTFLAGS) $(SAN_FLAGS)
30+
LDFLAGS := $(SAN_FLAGS)
31+
32+
# --------------------------
33+
# Usage notes
34+
# --------------------------
35+
# Local build (default): ASAN enabled
36+
# $ make
37+
#
38+
# Override for ThreadSanitizer:
39+
# $ make SANITIZE=thread
40+
#
41+
# Override for UBSAN:
42+
# $ make SANITIZE=undefined
43+
#
44+
# Disable sanitizers (rare):
45+
# $ make SANITIZE=
46+
#
47+
# LDFLAGS are automatically applied in example Makefiles:
48+
# $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)

0 commit comments

Comments
 (0)