mprotect ma wadę: Twoja pamięć musi być wyrównana do strony. Miałem problematyczną pamięć na stosie i nie mogłem użyć mprotect().
Zgodnie z tym, co powiedział Adam, chodzi o manipulowanie rejestrami debugowania. W systemie Windows użyłem tego: http://www.morearty.com/code/breakpoint/ i działało świetnie. Przesyłałem go również do Mach-O (Mac OS X) i działało też świetnie. Było to również łatwe, ponieważ Mach-O ma thread_set_state(), co jest równoważne SetThreadContext().
Problem z Linuksem polega na tym, że nie ma takich odpowiedników. Znalazłem ptrace, ale pomyślałem, to nie może być to, musi być coś prostszego. Ale nie ma. Jeszcze. Myślę, że pracują nad interfejsem API hw_breakpoint dla obu przestrzeni jądra i użytkownika.(zobacz http://lwn.net/Articles/317153/)
Ale kiedy znalazłem to: http://blogs.oracle.com/nike/entry/memory_debugger_for_linux Spróbowałem i nie było tak źle. Metoda ptrace działa przez jakiś "proces zewnętrzny" działając jako "debugger", dołączając do twojego programu, wprowadzając nowe wartości do rejestrów debugowania i kończąc z twoim programem kontynuującym z nowym zestawem punktów przerwania hw. Chodzi o to, że możesz samemu stworzyć ten "proces zewnętrzny", używając fork(), (nie miałem żadnego sukcesu z pthreadem) i wykonując te proste kroki w kodzie.
Kod addwatchpoint musi być dostosowany do pracy z 64-bitowym systemem Linux, ale to tylko zmienia USER_DR7 itd. W offset2 (użytkownik struct, u_debugreg [7]). Inną sprawą jest to, że po PTRACE_ATTACH, musisz poczekać, aż debuger faktycznie się zatrzyma. Ale zamiast ponawiania POKEUSER'a w zajętej pętli, poprawną rzeczą byłoby użycie waitpid() na twoim pidzie.
Jedynym haczykiem przy użyciu metody ptrace jest to, że program może mieć tylko jeden "debugger" podłączony w tym samym czasie. Tak więc dołączenie ptrace nie powiedzie się, jeśli twój program jest już uruchomiony pod kontrolą gdb. Ale tak jak w przykładowym kodzie, możesz zarejestrować obsługę sygnału dla SIGTRAP, uruchomić bez gdb, a kiedy złapiesz sygnał, wprowadź pętlę zajętą, czekającą na dołączenie gdb. Stamtąd możesz zobaczyć, kto próbował napisać twoją pamięć.
Dostęp do rejestrów debugowania można uzyskać tylko na poziomie uprawnień 0, tj. W jądrze. Zobacz http://pdos.csail.mit.edu/6.828/2008/readings/i386/s12_02.htm –