linD026 / ucsan

The User Concurrency Sanitizer (UCSAN)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

detect: Job list

linD026 opened this issue · comments

Detect Function Example

Data-race detection in the Linux kernel

/*
 * 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.

@linD026

  1. 所以【#define UCSAN_ACCESS_WRITE 0x1】,會傳1給我囉
  2. check_access的parameters多一個【unsigned long ip】,我會用到嗎
  1. 所以【#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.

  1. 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.