Bỏ qua điều hướng, tới nội dung chính
Học C
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

DebugRelease
Mức tối ưu-O0 hoặc -Og-O2
Thông tin gỡ lỗi-g3 đầy đủ-g rồi tách ra
SanitizerCó, ASan và UBSanKhông
Kiểm tra assertBậtThường tắt bằng -DNDEBUG
Gia cố bảo mậtKhông cầnĐầy đủ
LTOKhôngCó, nếu đo được lợi ích
Tốc độ dịchNhanhChậm hơn
Tốc độ chạyChậm 2 tới 30 lầnNhanh 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
-O2Tối ưu đầy đủ36.2
-DNDEBUGTắt assert56.5
-fltoTối ưu xuyên tệp36.2
-D_FORTIFY_SOURCE=2Thay hàm chuỗi bằng bản kiểm tra kích thước59.1
-fstack-protector-strongCanh gác ngăn xếp chống tràn59.1
-fPIE -pieBật ASLR cho mã thực thi59.1
-Wl,-z,relro,-z,nowBảng GOT chỉ đọc sau khi nạp59.1
-Wl,-z,noexecstackNgă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ử

  1. Viết dòng lệnh bản debug và bản release cho một dự án của bạn.
  2. Đặt _FORTIFY_SOURCE=2 mà quên -O2 và xác nhận nó không có tác dụng.
  3. Trên Linux, dịch bản debug với sanitizer và chạy nó trên mã có lỗi bộ nhớ.
  4. Viết một assert có tác dụng phụ và chứng minh nó biến mất với -DNDEBUG.
  5. strip một binary và so kích thước trước sau.
  6. Trên Linux, chạy checksec trê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_SOURCE cần -O1 trở lên, và assert biến mất với -DNDEBUG.
  • strip giả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.