Bộ nhớ chưa khởi tạo trong C và C++ là nguyên nhân phổ biến gây ra các vấn đề về độ tin cậy, lỗi về độ an toàn của bộ nhớ và rò rỉ thông tin. Để tránh những vấn đề này, Android sẽ khởi chạy nhiều bộ nhớ nhất có thể.
Bộ nhớ không gian người dùng được khởi tạo bằng 0
Kể từ Android 12, bộ nhớ ngăn xếp được khởi tạo bằng 0 trong tất cả mã gốc của nền tảng (bao gồm cả JNI) và bộ nhớ khối xếp được khởi tạo bằng 0 trong tất cả các quy trình gốc của nền tảng (chẳng hạn như netd
) nhưng không phải trong zygote
hoặc trong ứng dụng.
Bạn nên sử dụng cờ trình biên dịch -ftrivial-auto-var-init=zero
để khởi tạo các biến cục bộ trong ngăn xếp của ứng dụng bên thứ nhất và bên thứ ba được tạo bằng NDK. Trình biên dịch sẽ tối ưu hoá mọi giá trị bằng 0 không cần thiết.
Ví dụ: khi một biến cục bộ được khởi tạo rõ ràng (chẳng hạn như biến int x = 123;
x
chỉ được khởi tạo một lần).
Nếu chương trình có vùng đệm ngăn xếp lớn trong một điểm nóng hiệu suất, nhà phát triển có thể tắt tính năng khởi chạy bằng cách sử dụng thuộc tính trình biên dịch:
__attribute__((__uninitialized__)) char buf[BUFSIZ];
Ứng dụng cũng có thể chọn khởi chạy bằng cách sử dụng thuộc tính tệp kê khai android:nativeHeapZeroInitialized
.
Ngoài ra, bạn có thể kiểm soát quá trình khởi tạo vùng nhớ khối xếp bằng 0 trong thời gian chạy bằng:
int mallopt(M_BIONIC_ZERO_INIT, level)
Trong đó level là 0 hoặc 1.
Bộ nhớ nhân được khởi tạo bằng 0
Ngăn xếp và vùng nhớ khối xếp của hạt nhân được khởi tạo bằng 0 cho các hạt nhân GKI. Đây là đề xuất mạnh mẽ của CDD.
Để khởi tạo ngăn xếp, GKI sử dụng cấu hình CONFIG_INIT_STACK_ALL_ZERO
, từ đó tạo nhân bằng cờ trình biên dịch -ftrivial-auto-var-init=zero
.
Để khởi tạo vùng nhớ khối xếp, GKI sử dụng CONFIG_INIT_ON_ALLOC_DEFAULT_ON
, giúp tất cả các vùng nhớ khối xếp trang, SLAB và SLUB được khởi tạo bằng 0 khi được tạo. Tuỳ chọn này tương tự như việc truyền init_on_alloc=1
làm tuỳ chọn thời gian khởi động hạt nhân.
Báo cáo lỗi
Các công cụ của chúng tôi tạo ra báo cáo lỗi chi tiết chứa thông tin bổ sung để hỗ trợ gỡ lỗi. Dấu vết ngăn xếp phân bổ và giải phóng bổ sung giúp hiểu rõ hơn về vòng đời của một lượt phân bổ nhất định và giúp phát hiện nhanh hơn các lỗi gây ra sự cố về an toàn bộ nhớ.

Trong quá trình phát triển, nhà cung cấp nên theo dõi sự hiện diện của lỗi bằng cách kiểm tra /data/tombstones
và logcat
để tìm sự cố gốc. Để biết thêm thông tin về cách gỡ lỗi mã gốc Android, hãy xem thông tin tại đây.