mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Revert "Add asan switch indicators"
This is a good idea but only for non-nested coroutines. We nest. This reverts commit a9121d4cd1b8ef495645127f89fdbfc2191efd9c.
This commit is contained in:
parent
637902f43f
commit
c47641f454
@ -57,36 +57,6 @@
|
|||||||
#include <sys/mman.h> // mmap, mprotect, munmap
|
#include <sys/mman.h> // mmap, mprotect, munmap
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
#include <sanitizer/asan_interface.h>
|
|
||||||
// ASan fiber switching APIs (available since Clang 3.9/GCC 7)
|
|
||||||
extern "C" {
|
|
||||||
void __sanitizer_start_switch_fiber(void** fake_stack_save,
|
|
||||||
const void* bottom, size_t size);
|
|
||||||
void __sanitizer_finish_switch_fiber(void* fake_stack_save,
|
|
||||||
const void** bottom_old,
|
|
||||||
size_t* size_old);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thread-local tracking of ASAN fiber switch state
|
|
||||||
static bool& GetAsanFiberSwitchState()
|
|
||||||
{
|
|
||||||
thread_local bool asan_fiber_switch_active = false;
|
|
||||||
return asan_fiber_switch_active;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add runtime ASAN detection
|
|
||||||
static bool IsASanEnabled()
|
|
||||||
{
|
|
||||||
static std::optional<bool> asan_enabled;
|
|
||||||
if (!asan_enabled.has_value())
|
|
||||||
{
|
|
||||||
asan_enabled = (__has_feature(address_sanitizer) );
|
|
||||||
}
|
|
||||||
return asan_enabled.value();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement a coroutine.
|
* Implement a coroutine.
|
||||||
*
|
*
|
||||||
@ -140,24 +110,12 @@ private:
|
|||||||
void* tsan_fiber; // The TSAN fiber for this context
|
void* tsan_fiber; // The TSAN fiber for this context
|
||||||
bool own_tsan_fiber; // Do we own this TSAN fiber? (we only delete fibers we own)
|
bool own_tsan_fiber; // Do we own this TSAN fiber? (we only delete fibers we own)
|
||||||
#endif
|
#endif
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
void* asan_fake_stack; // ASan fake stack for this context
|
|
||||||
const void* asan_stack_bottom; // Stack bottom for ASan
|
|
||||||
size_t asan_stack_size; // Stack size for ASan
|
|
||||||
bool asan_stack_registered; // Track if we registered this stack
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CONTEXT_T() :
|
CONTEXT_T() :
|
||||||
ctx( nullptr )
|
ctx( nullptr )
|
||||||
#ifdef KICAD_SANITIZE_THREADS
|
#ifdef KICAD_SANITIZE_THREADS
|
||||||
,tsan_fiber( nullptr )
|
,tsan_fiber( nullptr )
|
||||||
,own_tsan_fiber( true )
|
,own_tsan_fiber( true )
|
||||||
#endif
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
,asan_fake_stack( nullptr )
|
|
||||||
,asan_stack_bottom( nullptr )
|
|
||||||
,asan_stack_size( 0 )
|
|
||||||
,asan_stack_registered( false )
|
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -167,15 +125,6 @@ private:
|
|||||||
// Only destroy the fiber when we own it
|
// Only destroy the fiber when we own it
|
||||||
if( own_tsan_fiber )
|
if( own_tsan_fiber )
|
||||||
__tsan_destroy_fiber( tsan_fiber );
|
__tsan_destroy_fiber( tsan_fiber );
|
||||||
#endif
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
// Clean up ASAN registration if we registered it
|
|
||||||
if( asan_stack_registered && IsASanEnabled() )
|
|
||||||
{
|
|
||||||
// Note: ASAN doesn't provide explicit stack deregistration,
|
|
||||||
// but we should reset our tracking
|
|
||||||
asan_stack_registered = false;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -257,6 +206,9 @@ public:
|
|||||||
m_retVal( 0 )
|
m_retVal( 0 )
|
||||||
#ifdef KICAD_USE_VALGRIND
|
#ifdef KICAD_USE_VALGRIND
|
||||||
,m_valgrind_stack( 0 )
|
,m_valgrind_stack( 0 )
|
||||||
|
#endif
|
||||||
|
#ifdef KICAD_SANITIZE_ADDRESS
|
||||||
|
,asan_stack( nullptr )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
m_stacksize = ADVANCED_CFG::GetCfg().m_CoroutineStackSize;
|
m_stacksize = ADVANCED_CFG::GetCfg().m_CoroutineStackSize;
|
||||||
@ -324,6 +276,12 @@ public:
|
|||||||
CALL_CONTEXT ctx;
|
CALL_CONTEXT ctx;
|
||||||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &ctx };
|
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &ctx };
|
||||||
|
|
||||||
|
#ifdef KICAD_SANITIZE_THREADS
|
||||||
|
// Get the TSAN fiber for the current stack here
|
||||||
|
m_caller.tsan_fiber = __tsan_get_current_fiber();
|
||||||
|
m_caller.own_tsan_fiber = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
wxLogTrace( kicadTraceCoroutineStack, "COROUTINE::Call (from root)" );
|
wxLogTrace( kicadTraceCoroutineStack, "COROUTINE::Call (from root)" );
|
||||||
|
|
||||||
ctx.Continue( doCall( &args, aArg ) );
|
ctx.Continue( doCall( &args, aArg ) );
|
||||||
@ -364,6 +322,12 @@ public:
|
|||||||
CALL_CONTEXT ctx;
|
CALL_CONTEXT ctx;
|
||||||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &ctx };
|
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROOT, this, &ctx };
|
||||||
|
|
||||||
|
#ifdef KICAD_SANITIZE_THREADS
|
||||||
|
// Get the TSAN fiber for the current stack here
|
||||||
|
m_caller.tsan_fiber = __tsan_get_current_fiber();
|
||||||
|
m_caller.own_tsan_fiber = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
wxLogTrace( kicadTraceCoroutineStack, wxT( "COROUTINE::Resume (from root)" ) );
|
wxLogTrace( kicadTraceCoroutineStack, wxT( "COROUTINE::Resume (from root)" ) );
|
||||||
|
|
||||||
ctx.Continue( doResume( &args ) );
|
ctx.Continue( doResume( &args ) );
|
||||||
@ -413,22 +377,6 @@ private:
|
|||||||
assert( m_func );
|
assert( m_func );
|
||||||
assert( !( m_callee.ctx ) );
|
assert( !( m_callee.ctx ) );
|
||||||
|
|
||||||
#ifdef KICAD_SANITIZE_THREADS
|
|
||||||
// Get the TSAN fiber for the current stack here
|
|
||||||
m_caller.tsan_fiber = __tsan_get_current_fiber();
|
|
||||||
m_caller.own_tsan_fiber = false;
|
|
||||||
#endif
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
if( IsASanEnabled() )
|
|
||||||
{
|
|
||||||
// Initialize caller's ASan context (main stack)
|
|
||||||
m_caller.asan_fake_stack = nullptr;
|
|
||||||
m_caller.asan_stack_bottom = nullptr; // Main stack, managed by ASan
|
|
||||||
m_caller.asan_stack_size = 0;
|
|
||||||
m_caller.asan_stack_registered = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_args = &aArgs;
|
m_args = &aArgs;
|
||||||
|
|
||||||
std::size_t stackSize = m_stacksize;
|
std::size_t stackSize = m_stacksize;
|
||||||
@ -460,22 +408,6 @@ private:
|
|||||||
#ifdef KICAD_USE_VALGRIND
|
#ifdef KICAD_USE_VALGRIND
|
||||||
m_valgrind_stack = VALGRIND_STACK_REGISTER( sp, m_stack.get() );
|
m_valgrind_stack = VALGRIND_STACK_REGISTER( sp, m_stack.get() );
|
||||||
#endif
|
#endif
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
if( IsASanEnabled() )
|
|
||||||
{
|
|
||||||
// Register the allocated stack with ASan
|
|
||||||
m_callee.asan_stack_bottom = m_stack.get();
|
|
||||||
m_callee.asan_stack_size = stackSize;
|
|
||||||
m_callee.asan_fake_stack = nullptr;
|
|
||||||
m_callee.asan_stack_registered = true;
|
|
||||||
|
|
||||||
// Poison the guard page for better debugging
|
|
||||||
if( m_stack.get() )
|
|
||||||
{
|
|
||||||
__asan_poison_memory_region( m_stack.get(), SystemPageSize() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef KICAD_SANITIZE_THREADS
|
#ifdef KICAD_SANITIZE_THREADS
|
||||||
@ -562,21 +494,6 @@ private:
|
|||||||
|
|
||||||
INVOCATION_ARGS* doResume( INVOCATION_ARGS* args )
|
INVOCATION_ARGS* doResume( INVOCATION_ARGS* args )
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef KICAD_SANITIZE_THREADS
|
|
||||||
// Get the TSAN fiber for the current stack here
|
|
||||||
m_caller.tsan_fiber = __tsan_get_current_fiber();
|
|
||||||
m_caller.own_tsan_fiber = false;
|
|
||||||
#endif
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
if( IsASanEnabled() )
|
|
||||||
{
|
|
||||||
// Initialize caller's ASan context for resume
|
|
||||||
m_caller.asan_fake_stack = nullptr;
|
|
||||||
m_caller.asan_stack_bottom = nullptr;
|
|
||||||
m_caller.asan_stack_size = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return jumpIn( args );
|
return jumpIn( args );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,38 +519,17 @@ private:
|
|||||||
|
|
||||||
INVOCATION_ARGS* jumpIn( INVOCATION_ARGS* args )
|
INVOCATION_ARGS* jumpIn( INVOCATION_ARGS* args )
|
||||||
{
|
{
|
||||||
|
|
||||||
wxLogTrace( kicadTraceCoroutineStack, wxT( "COROUTINE::jumpIn" ) );
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
// Only use ASAN fiber switching for root-level calls to avoid nesting
|
|
||||||
if( IsASanEnabled() && !GetAsanFiberSwitchState()
|
|
||||||
&& ( m_callee.asan_stack_registered || m_callee.asan_stack_bottom ) )
|
|
||||||
{
|
|
||||||
GetAsanFiberSwitchState() = true;
|
|
||||||
__sanitizer_start_switch_fiber( &m_caller.asan_fake_stack,
|
|
||||||
m_callee.asan_stack_bottom,
|
|
||||||
m_callee.asan_stack_size );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef KICAD_SANITIZE_THREADS
|
#ifdef KICAD_SANITIZE_THREADS
|
||||||
// Tell TSAN we are changing fibers to the callee
|
// Tell TSAN we are changing fibers to the callee
|
||||||
__tsan_switch_to_fiber( m_callee.tsan_fiber, 0 );
|
__tsan_switch_to_fiber( m_callee.tsan_fiber, 0 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
wxLogTrace( kicadTraceCoroutineStack, wxT( "COROUTINE::jumpIn" ) );
|
||||||
|
|
||||||
args = reinterpret_cast<INVOCATION_ARGS*>(
|
args = reinterpret_cast<INVOCATION_ARGS*>(
|
||||||
libcontext::jump_fcontext( &( m_caller.ctx ), m_callee.ctx,
|
libcontext::jump_fcontext( &( m_caller.ctx ), m_callee.ctx,
|
||||||
reinterpret_cast<intptr_t>( args ) )
|
reinterpret_cast<intptr_t>( args ) )
|
||||||
);
|
);
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
// Complete fiber switch only if we started it
|
|
||||||
if( IsASanEnabled() && GetAsanFiberSwitchState() )
|
|
||||||
{
|
|
||||||
__sanitizer_finish_switch_fiber( m_caller.asan_fake_stack,
|
|
||||||
&m_caller.asan_stack_bottom,
|
|
||||||
&m_caller.asan_stack_size );
|
|
||||||
GetAsanFiberSwitchState() = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
@ -643,16 +539,6 @@ private:
|
|||||||
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROUTINE, nullptr, nullptr };
|
INVOCATION_ARGS args{ INVOCATION_ARGS::FROM_ROUTINE, nullptr, nullptr };
|
||||||
INVOCATION_ARGS* ret;
|
INVOCATION_ARGS* ret;
|
||||||
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
// Only use ASAN fiber switching for root-level calls to avoid nesting
|
|
||||||
if( IsASanEnabled() && !GetAsanFiberSwitchState() )
|
|
||||||
{
|
|
||||||
GetAsanFiberSwitchState() = true;
|
|
||||||
__sanitizer_start_switch_fiber( &m_callee.asan_fake_stack,
|
|
||||||
m_caller.asan_stack_bottom,
|
|
||||||
m_caller.asan_stack_size );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef KICAD_SANITIZE_THREADS
|
#ifdef KICAD_SANITIZE_THREADS
|
||||||
// Tell TSAN we are changing fibers back to the caller
|
// Tell TSAN we are changing fibers back to the caller
|
||||||
__tsan_switch_to_fiber( m_caller.tsan_fiber, 0 );
|
__tsan_switch_to_fiber( m_caller.tsan_fiber, 0 );
|
||||||
@ -665,16 +551,6 @@ private:
|
|||||||
reinterpret_cast<intptr_t>( &args ) )
|
reinterpret_cast<intptr_t>( &args ) )
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
// Complete fiber switch only if we started it
|
|
||||||
if( IsASanEnabled() && GetAsanFiberSwitchState() )
|
|
||||||
{
|
|
||||||
__sanitizer_finish_switch_fiber( m_callee.asan_fake_stack,
|
|
||||||
&m_callee.asan_stack_bottom,
|
|
||||||
&m_callee.asan_stack_size );
|
|
||||||
GetAsanFiberSwitchState() = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
m_callContext = ret->context;
|
m_callContext = ret->context;
|
||||||
|
|
||||||
if( ret->type == INVOCATION_ARGS::FROM_ROOT )
|
if( ret->type == INVOCATION_ARGS::FROM_ROOT )
|
||||||
@ -683,24 +559,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KICAD_SANITIZE_ADDRESS
|
|
||||||
// Additional helper for debugging ASAN integration
|
|
||||||
void LogASanStatus() const
|
|
||||||
{
|
|
||||||
if( !IsASanEnabled() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxLogTrace( kicadTraceCoroutineStack,
|
|
||||||
wxT("ASAN Coroutine Status: fiber_switch_active=%s, "
|
|
||||||
"caller_bottom=%p, caller_size=%zu, "
|
|
||||||
"callee_bottom=%p, callee_size=%zu, callee_registered=%s"),
|
|
||||||
GetAsanFiberSwitchState() ? "yes" : "no",
|
|
||||||
m_caller.asan_stack_bottom, m_caller.asan_stack_size,
|
|
||||||
m_callee.asan_stack_bottom, m_callee.asan_stack_size,
|
|
||||||
m_callee.asan_stack_registered ? "yes" : "no" );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LIBCONTEXT_HAS_OWN_STACK
|
#ifndef LIBCONTEXT_HAS_OWN_STACK
|
||||||
/// Coroutine stack.
|
/// Coroutine stack.
|
||||||
std::unique_ptr<char[], struct STACK_DELETER> m_stack;
|
std::unique_ptr<char[], struct STACK_DELETER> m_stack;
|
||||||
@ -729,6 +587,10 @@ private:
|
|||||||
#ifdef KICAD_USE_VALGRIND
|
#ifdef KICAD_USE_VALGRIND
|
||||||
uint32_t m_valgrind_stack;
|
uint32_t m_valgrind_stack;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KICAD_SANITIZE_ADDRESS
|
||||||
|
void* asan_stack;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
x
Reference in New Issue
Block a user