Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

detect: Job list #4

Closed
linD026 opened this issue Apr 15, 2022 · 6 comments
Closed

detect: Job list #4

linD026 opened this issue Apr 15, 2022 · 6 comments
Assignees
Labels
job The discussion of the main job resides here

Comments

@linD026
Copy link
Owner

linD026 commented Apr 15, 2022

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;
}
@linD026
Copy link
Owner Author

linD026 commented May 20, 2022

@ziyuan1135

@linD026
Copy link
Owner Author

linD026 commented Jun 6, 2022

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

@ziyuan1135
Copy link
Collaborator

@linD026

  1. 所以【#define UCSAN_ACCESS_WRITE 0x1】,會傳1給我囉
  2. check_access的parameters多一個【unsigned long ip】,我會用到嗎

@linD026
Copy link
Owner Author

linD026 commented Jun 6, 2022

  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

@linD026
Copy link
Owner Author

linD026 commented Jun 6, 2022

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:

@linD026 linD026 added the job The discussion of the main job resides here label Jun 8, 2022
@linD026
Copy link
Owner Author

linD026 commented Jun 13, 2022

I create the PR for the basic concept of how the detect and unify subsystems interact.

@linD026 linD026 closed this as completed Jun 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
job The discussion of the main job resides here
Projects
None yet
Development

No branches or pull requests

2 participants