diff --git a/docs/cn/sanitizers.md b/docs/cn/sanitizers.md index 3013526927..bdd32010b3 100644 --- a/docs/cn/sanitizers.md +++ b/docs/cn/sanitizers.md @@ -17,6 +17,24 @@ BUTIL_ASAN_POISON_MEMORY_REGION(addr, size); BUTIL_ASAN_UNPOISON_MEMORY_REGION(addr, size); ``` +如果某些对象池在设计上允许操作对象池中的对象,例如ExecutionQueue、Butex,则需要特化ObjectPoolWithASanPoison,表示不对这些对象池的对象内存进行poison/unpoison,例如: + +```c++ +namespace butil { +// TaskNode::cancel() may access the TaskNode object returned to the ObjectPool, +// so ObjectPool can not poison the memory region of TaskNode. +template <> +struct ObjectPoolWithASanPoison : false_type {}; +} // namespace butil + +namespace butil { +// Butex object returned to the ObjectPool may be accessed, +// so ObjectPool can not poison the memory region of Butex. +template <> +struct ObjectPoolWithASanPoison : false_type {}; +} // namespace butil +``` + 其他问题:如果ASan报告中new/delete的调用栈不完整,可以通过设置`fast_unwind_on_malloc=0`回溯出完整的调用栈了。需要注意的是`fast_unwind_on_malloc=0`很耗性能。 ## ThreadSanitizer(TSan) diff --git a/src/bthread/butex.cpp b/src/bthread/butex.cpp index c54198c6cf..aca1281670 100644 --- a/src/bthread/butex.cpp +++ b/src/bthread/butex.cpp @@ -122,6 +122,17 @@ struct BAIDU_CACHELINE_ALIGNMENT Butex { BAIDU_CASSERT(offsetof(Butex, value) == 0, offsetof_value_must_0); BAIDU_CASSERT(sizeof(Butex) == BAIDU_CACHELINE_SIZE, butex_fits_in_one_cacheline); +} // namespace bthread + +namespace butil { +// Butex object returned to the ObjectPool may be accessed, +// so ObjectPool can not poison the memory region of Butex. +template <> +struct ObjectPoolWithASanPoison : false_type {}; +} // namespace butil + +namespace bthread { + static void wakeup_pthread(ButexPthreadWaiter* pw) { // release fence makes wait_pthread see changes before wakeup. pw->sig.store(PTHREAD_SIGNALLED, butil::memory_order_release); diff --git a/src/bthread/execution_queue_inl.h b/src/bthread/execution_queue_inl.h index cf7d2ee5be..ddf7bc6ba2 100644 --- a/src/bthread/execution_queue_inl.h +++ b/src/bthread/execution_queue_inl.h @@ -587,7 +587,7 @@ inline int ExecutionQueueBase::dereference() { } // namespace bthread namespace butil { -// `TaskNode::cancel' may access the TaskNode object returned to the ObjectPool, +// TaskNode::cancel() may access the TaskNode object returned to the ObjectPool, // so ObjectPool can not poison the memory region of TaskNode. template <> struct ObjectPoolWithASanPoison : false_type {};