mprotect không có bất lợi: bộ nhớ của bạn phải được căn chỉnh theo ranh giới trang. Tôi đã có bộ nhớ có vấn đề của tôi trên ngăn xếp và không thể sử dụng mprotect().
Như Adam đã nói, điều bạn muốn là thao tác các thanh ghi gỡ lỗi. Trên cửa sổ, tôi đã sử dụng: http://www.morearty.com/code/breakpoint/ và nó hoạt động rất tốt. Tôi cũng chuyển nó sang Mach-O (Mac OS X), và nó cũng hoạt động rất tốt. Nó cũng dễ dàng, bởi vì Mach-O có thread_set_state(), tương đương với SetThreadContext().
Vấn đề với linux là nó không có tương đương như vậy. Tôi tìm thấy ptrace, nhưng tôi nghĩ, điều này không thể được, phải có một cái gì đó đơn giản hơn. Nhưng không có. Chưa. Tôi nghĩ rằng họ đang làm việc trên một API hw_breakpoint cho cả hạt nhân và không gian người dùng.(xem http://lwn.net/Articles/317153/)
Nhưng khi tôi tìm thấy điều này: http://blogs.oracle.com/nike/entry/memory_debugger_for_linux Tôi đã thử nó và nó không phải là xấu. Phương thức ptrace hoạt động bởi một số "quy trình bên ngoài" hoạt động như một "trình gỡ lỗi", gắn vào chương trình của bạn, tiêm các giá trị mới cho thanh ghi gỡ lỗi và kết thúc với chương trình của bạn tiếp tục với một bộ break break hw mới. Vấn đề là, bạn có thể tự tạo "quá trình bên ngoài" này bằng cách sử dụng fork(), (tôi đã không thành công với một pthread) và thực hiện các bước đơn giản này trong mã của bạn.
Mã addwatchpoint phải được điều chỉnh để làm việc với Linux 64 bit, nhưng đó chỉ là thay đổi USER_DR7 v.v. thành offsetof (struct user, u_debugreg [7]). Một điều nữa là sau một PTRACE_ATTACH, bạn phải đợi cho debuggee thực sự dừng lại. Nhưng thay vì thử lại POKEUSER trong một vòng lặp bận rộn, điều chính xác để làm sẽ là một waitpid() trên pid của bạn.
Phương pháp duy nhất với phương pháp ptrace là chương trình của bạn chỉ có thể có một "trình gỡ lỗi" được đính kèm tại một thời điểm. Vì vậy, một đính kèm ptrace sẽ thất bại nếu chương trình của bạn đã chạy dưới sự kiểm soát gdb. Nhưng giống như mã ví dụ, bạn có thể đăng ký trình xử lý tín hiệu cho SIGTRAP, chạy không có gdb và khi bạn bắt tín hiệu, hãy nhập một vòng lặp bận chờ gdb đính kèm. Từ đó bạn có thể thấy ai đã cố gắng để viết bộ nhớ của bạn.
Nguồn
2010-09-07 08:24:50
Trình đăng ký gỡ lỗi chỉ có thể được truy cập ở mức đặc quyền 0, tức là trong hạt nhân. Xem http://pdos.csail.mit.edu/6.828/2008/readings/i386/s12_02.htm –