detect: Job list
linD026 opened this issue · comments
Detect Function Example
/*
* KCSAN uses the same instrumentation that is emitted by supported compilers
* for ThreadSanitizer (TSAN).
*
* When enabled, the compiler emits instrumentation calls (the functions
* prefixed with "__tsan" below) for all loads and stores that it generated;
* inline asm is not instrumented.
*
* Note that, not all supported compiler versions distinguish aligned/unaligned
* accesses, but e.g. recent versions of Clang do. We simply alias the unaligned
* version to the generic version, which can handle both.
*/
#define DEFINE_TSAN_READ_WRITE(size) \
void __tsan_read##size(void *ptr); \
void __tsan_read##size(void *ptr) \
{ \
check_access(ptr, size, 0, _RET_IP_); \
} \
EXPORT_SYMBOL(__tsan_read##size); \
void __tsan_unaligned_read##size(void *ptr) \
__alias(__tsan_read##size); \
EXPORT_SYMBOL(__tsan_unaligned_read##size); \
void __tsan_write##size(void *ptr); \
void __tsan_write##size(void *ptr) \
{ \
check_access(ptr, size, KCSAN_ACCESS_WRITE, _RET_IP_); \
} \
EXPORT_SYMBOL(__tsan_write##size); \
void __tsan_unaligned_write##size(void *ptr) \
__alias(__tsan_write##size); \
EXPORT_SYMBOL(__tsan_unaligned_write##size); \
void __tsan_read_write##size(void *ptr); \
void __tsan_read_write##size(void *ptr) \
{ \
check_access(ptr, size, \
KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE, \
_RET_IP_); \
} \
EXPORT_SYMBOL(__tsan_read_write##size); \
void __tsan_unaligned_read_write##size(void *ptr) \
__alias(__tsan_read_write##size); \
EXPORT_SYMBOL(__tsan_unaligned_read_write##size)
DEFINE_TSAN_READ_WRITE(1);
DEFINE_TSAN_READ_WRITE(2);
DEFINE_TSAN_READ_WRITE(4);
DEFINE_TSAN_READ_WRITE(8);
DEFINE_TSAN_READ_WRITE(16);
Watchpoint
enum watchpoint_state {
is_none,
is_write,
is_read,
};
atomic_int watchpoint;
void detect::check_access(void *ptr, size_t size, int read_write_state)
{
watchpoint = find_watchpoint(ptr);
if (watchpoint == is_none) // atomic operation
watchpoint = read_write_state; //atomic operation
else {
// someone already created the watchpoint
// report the data race to unify subsystem
unify::report(ptr, size, read_write_state);
return;
}
// wait some time
while (1) {
if (detect someone access this address) {
// data race
// XXX: only one task will report the data race to system
// report the task info to unify subsystem
unify::report(...);
}
}
// no one is access it, no data race
watchpoint = is_none; // atomic operation
return;
}
@ziyuan1135
I add the basic thread sanitizer interface, which is the __tsan_{read, write}()
function, please check it.
The commit is 807ffbf.
It will call the check_access()
function and pass the operation type, like UCSAN_ACCESEE_WRITE
to specific the write operation.
- 所以【#define UCSAN_ACCESS_WRITE 0x1】,會傳1給我囉
- check_access的parameters多一個【unsigned long ip】,我會用到嗎
- 所以【#define UCSAN_ACCESS_WRITE 0x1】,會傳1給我囉
Yes.
But, you can use the bitwise AND to the macro name ( like UCSAN_ACCESS_WRITE & type ) to get the type.
- check_access的parameters多一個【unsigned long ip】,我會用到嗎
Yes.
It will get the return function address.
See the __builtin_return_address in
https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html
I create the PR for the find_watchpoint()
.
This patch set the basic idea of how the watchpoint store the information of the object that we want to detect the data race.
And how the watchpoint will be maintained.
See here:
I create the PR for the basic concept of how the detect and unify subsystems interact.