Bài 36.426 phút đọc
Bản debug và bản phát hành
Sau bài này bạn sẽ làm được
- Viết dòng lệnh cho bản debug đầy đủ sanitizer
- Viết dòng lệnh cho bản phát hành gia cố
- Giải thích vì sao không trộn hai hồ sơ
- Dùng strip và biết nó bỏ đi gì
Một dự án nghiêm túc có ít nhất hai cách dựng: một bản chậm bắt mọi lỗi để phát triển, và một bản nhanh gia cố bảo mật để phát hành. Bài này viết cả hai dòng lệnh và giải thích vì sao chúng phải tách bạch.
#Hai hồ sơ build
| Debug | Release | |
|---|---|---|
| Mức tối ưu | -O0 hoặc -Og | -O2 |
| Thông tin gỡ lỗi | -g3 đầy đủ | -g rồi tách ra |
| Sanitizer | Có, ASan và UBSan | Không |
| Kiểm tra assert | Bật | Thường tắt bằng -DNDEBUG |
| Gia cố bảo mật | Không cần | Đầy đủ |
| LTO | Không | Có, nếu đo được lợi ích |
| Tốc độ dịch | Nhanh | Chậm hơn |
| Tốc độ chạy | Chậm 2 tới 30 lần | Nhanh nhất |
#Bản debug
Bản debug, chậm nhưng bắt mọi lỗi
gcc -std=c17 \
-Wall -Wextra -Wpedantic -Wshadow -Wconversion \
-g3 -O0 \
-fsanitize=address,undefined -fno-omit-frame-pointer \
-DDEBUG \
src/*.c -o build/app_debug#Bản phát hành
Bản phát hành, nhanh và gia cố
gcc -std=c17 \
-Wall -Wextra -Werror \
-O2 -DNDEBUG -flto \
-D_FORTIFY_SOURCE=2 -fstack-protector-strong \
-fPIE -pie \
-Wl,-z,relro,-z,now -Wl,-z,noexecstack \
src/*.c -o build/app
strip build/app| Cờ | Làm gì | Bài |
|---|---|---|
| -O2 | Tối ưu đầy đủ | 36.2 |
| -DNDEBUG | Tắt assert | 56.5 |
| -flto | Tối ưu xuyên tệp | 36.2 |
| -D_FORTIFY_SOURCE=2 | Thay hàm chuỗi bằng bản kiểm tra kích thước | 59.1 |
| -fstack-protector-strong | Canh gác ngăn xếp chống tràn | 59.1 |
| -fPIE -pie | Bật ASLR cho mã thực thi | 59.1 |
| -Wl,-z,relro,-z,now | Bảng GOT chỉ đọc sau khi nạp | 59.1 |
| -Wl,-z,noexecstack | Ngăn xếp không chạy được (NX) | 59.1 |
#Vì sao không trộn
Trộn hai hồ sơ
# "Bat het cho chac"
gcc -O2 -g3 -fsanitize=address -DNDEBUG \
-fstack-protector-strong app.c -o app
# Bon van de:
# 1. -O2 voi sanitizer: kho go loi, va -O2 co the che mot so
# loi ma sanitizer se bat o -O1.
# 2. -DNDEBUG tat assert, nhung ban DANG go loi, luc can assert
# nhat.
# 3. Ban chay cham vi sanitizer NHUNG cung dinh do hieu nang?
# So do vo nghia.
# 4. Mot binary vua go loi vua phat hanh khong phuc vu tot
# muc dich nao.
Tách bạch
# Hai muc tieu rieng trong Makefile
debug: CFLAGS += -O0 -g3 -fsanitize=address,undefined -DDEBUG
release: CFLAGS += -O2 -DNDEBUG -flto -D_FORTIFY_SOURCE=2 \
-fstack-protector-strong
# make debug -> ban de go loi
# make release -> ban de phat hanh
# Moi ban lam DUNG mot viec, va lam tot.
#strip
terminal
# Binary phat hanh voi -O2 -g, truoc khi strip
gcc -std=c11 -O2 -g std.c -o std_full.exe && stat -c%s std_full.exe
55840
strip std_full.exe && stat -c%s std_full.exe
15360
Tự làm thử
- Viết dòng lệnh bản debug và bản release cho một dự án của bạn.
- Đặt
_FORTIFY_SOURCE=2mà quên-O2và xác nhận nó không có tác dụng. - Trên Linux, dịch bản debug với sanitizer và chạy nó trên mã có lỗi bộ nhớ.
- Viết một
assertcó tác dụng phụ và chứng minh nó biến mất với-DNDEBUG. stripmột binary và so kích thước trước sau.- Trên Linux, chạy
checksectrên bản release và xác nhận đủ bốn cơ chế bảo vệ.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
- Hai hồ sơ: debug chậm bắt mọi lỗi, release nhanh gia cố bảo mật.
- Bản debug:
-O0 -g3, sanitizer,-DDEBUG, giữ assert. - Bản release:
-O2 -DNDEBUG, LTO, FORTIFY, canh gác, ASLR, RELRO, NX. - Không trộn hai hồ sơ;
_FORTIFY_SOURCEcần-O1trở lên, và assert biến mất với-DNDEBUG. stripgiảm kích thước binary nhưng bỏ ký hiệu; tách thông tin gỡ lỗi ra tệp riêng trước khi strip.