Golang: Booting
Chúng ta bắt đầu với ví dụ “Hello World”:
Thực thi lệnh sau trong thư mục gốc của dự án:
-gcflags "-N -l"
được sử dụng để tắt tối ưu hóa và việc nội tuyến hóa hàm của trình biên dịch, để tránh mất vị trí mã tương ứng khi thiết lập điểm dừng sau này.
Kết quả là chúng ta có được tệp thực thi hello. Thực thi:
Chúng ta đã nhập vào chế độ gỡ lỗi gdb, thực thi info files
, chúng ta sẽ nhận được thông tin về tiêu đề tệp thực thi, liệt kê các phân đoạn:
Đồng thời, chúng ta cũng nhận được địa chỉ nhập khẩu: 0x450e20.
Đây là địa chỉ nhập khẩu của chương trình Go, tôi đang chạy trên hệ điều hành Linux, vì vậy tệp nhập khẩu là src/runtime/rt0_linux_amd64.s
, thư mục runtime chứa các tệp nhập khẩu với các tên khác nhau, hỗ trợ các hệ điều hành và kiến trúc khác nhau. Mã nguồn như sau:
Chủ yếu là lấy argc, argv từ bộ nhớ vào thanh ghi. Ở đây, LEAQ được sử dụng để tính địa chỉ bộ nhớ, sau đó đưa chính địa chỉ bộ nhớ vào thanh ghi, tức là đưa địa chỉ argv vào thanh ghi SI. Cuối cùng, nhảy đến:
Tiếp tục với nhảy đến runtime·rt0_go(SB)
, vị trí: /usr/local/go/src/runtime/asm_amd64.s
, mã nguồn:
Một bài viết trong tài liệu tham khảo [“Khám phá quá trình khởi động chương trình Go”] nghiên cứu sâu hơn về chủ đề này, tóm tắt như sau:
- Kiểm tra CPU của nền tảng chạy, thiết lập các cờ liên quan.
- Khởi tạo TLS.
- Các hàm runtime.args, runtime.osinit, runtime.schedinit thực hiện các biến và lập lịch cần thiết cho chương trình.
- Tạo một goroutine mới để gắn kết với hàm main do người dùng viết.
- Khởi động M, bắt đầu lập lịch goroutine.
Cuối cùng, hãy xem một hình ảnh tổng quan về quá trình khởi động Go:
Một số hoạt động quan trọng trong hàm main bao gồm: bắt đầu một goroutine chạy hàm sysmon, thực hiện garbage collection và preemption scheduling định kỳ; khởi động gc; thực hiện tất cả các hàm init, và nhiều hơn nữa.
Phần về việc thoát khỏi chương trình:
Khi hàm main kết thúc, nó sẽ gọi exit(0) để thoát khỏi tiến trình. Nếu sau exit(0), tiến trình không thoát, mã cuối cùng của hàm main sẽ liên tục truy cập vào địa chỉ không hợp lệ:
Thông thường, khi truy cập vào địa chỉ không hợp lệ, hệ thống sẽ kết thúc quá trình, đảm bảo tiến trình thoát.
Phần về quá trình thoát chương trình này được trích từ cuộc trò chuyện nhóm [“Đọc mã nguồn Go của runtime”], đó là một nhóm nghiên cứu mã nguồn cao cấp khác, trang GitHub của họ có trong tài liệu tham khảo.
Tất nhiên, phần khởi động chương trình Go cũng liên quan đến việc fork một quá trình mới, tải tệp thực thi, chuyển quyền điều khiển và nhiều vấn đề khác. Tôi khuyến nghị đọc hai cuốn sách trước đó, tôi nghĩ rằng tôi không thể viết tốt hơn, nên không trình bày chi tiết ở đây.