Debug your program with data break-points. Your callback will be executed whenever a variable is written to. Example usage:
#include <stdio.h>
#include <stdlib.h>
#include "qdbp.h"
void callback(void *arg) {
char *ptr = arg;
if (ptr[123] == 'e') {
printf("Error: ptr[123] has an invalid value!\n");
// Check stack backtrace to see who is to blame.
}
}
int main() {
char *ptr = malloc(256);
qdbp_trap(ptr[123], callback, ptr);
ptr[123] = 'e';
// As if "callback(ptr);" was here.
return(0);
}#include "qdbp.h"
int qdbp_set_trap(void const *addr, int len, qdbp_cb_t cb, void *arg);
int qdbp_del_trap(int id);The qdbp_set_trap function sets a trap that covers len bytes
of memory starting at addr.
Whenever any memory location within the range is written to,
the callback cb will be called with argument arg.
Returns the identifier of the trap.
There is a convenience macro
qdbp_trap(object, callback, argument) which is equivalent to
qdbp_set_trap(&(object), sizeof(object), callback, argument).
The qdbp_del_trap function deletes the trap identified by id,
which must have been returned by a previous call to qdbp_set_trap.
The program using qdbp needs to be run under qdbp_enable:
qdbp_enable PROGRAM [ARGUMENT]...otherwise the callback will not be executed.
This limitation comes from the use of ptrace.
The memory range covered by a trap needs to be valid for mprotect.
That means that it should come from a call to mmap().
This is most probably the case for memory allocated by any of the
malloc-family of functions.
Before memory covered by a trap is freed or re-allocated,
it should be released with qdbp_del_trap.
After re-allocating, traps can be assigned again.
The underlying mechanism makes use of the signals
SIGSEGV, SIGTRAP and SIGUSR1, so, they must not be used
by the application.
The number of simultaneous active traps may be limited by implementation.
It has only been tested with the x86 architecture.
The qdbp_set_trap function returns the trap identifier or
a negative value in case of error.
The qdbp_del_trap function returns 0 on success or
a negative value in case of error.
The qdbp_set_trap returns:
-EINVALin case of an invalid argument:addrisNULLor less than the page size.lenis less than 1 or greater than the page size.cbisNULL.
-EBUSYin case the memory range specified overlaps with another trap.
The qdbp_set_trap returns:
-EINVALin case of an invalid argument:iddoes not represent an active trap.
This software is licensed under the 0BSD license (BSD Zero Clause License).