Skip to content

[SR-14012] Passing generic inout to other function causes "ThreadSanitizer: SEGV on unknown address 0x000000000000" #56405

Open
@nevil

Description

@nevil
Previous ID SR-14012
Radar rdar://problem/72865081
Original Reporter @nevil
Type Bug
Environment

Compiler version:
Xcode 12.3
Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
Target: x86_64-apple-darwin19.6.0

Additional Detail from JIRA
Votes 0
Component/s
Labels Bug
Assignee @devincoughlin
Priority Medium

md5: fb60172b97766b7b4700302dd672750b

Issue Description:

The below sample code causes a ThreadSanitizer error inside callReturnNext().
Compiler invocation: swiftc -Onone -sanitize=thread main.swift

#if WORKING
// Working
struct MYRNG: RandomNumberGenerator {
    private var n: UInt64 = 0
    mutating func next() -> UInt64 { return 0 }
}

#else

// TSAN error
struct MYRNG: RandomNumberGenerator {
    mutating func next() -> UInt64 { return 1 }
}
#endif

func returnNext<R: RandomNumberGenerator>(using generator: inout R) -> UInt64 {
    return generator.next()
}

func callReturnNext<R: RandomNumberGenerator>(_ array: [Int], using generator: inout R) -> UInt64 {
    return returnNext(using: &generator)
}


var g = MYRNG()

_  = callReturnNext([0], using: &g)

Result:

ThreadSanitizer:DEADLYSIGNAL
==45104==ERROR: ThreadSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000103389eb7 bp 0x7ffeec8e16a0 sp 0x7ffeec8e1660 T1384854)
==45104==The signal is caused by a READ memory access.
==45104==Hint: address points to the zero page.
    #&#8203;0 __tsan::MemoryAccess(__tsan::ThreadState*, unsigned long, unsigned long, int, bool, bool) <null>:3 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x5beb7)
    #&#8203;1 __tsan::ExternalAccess(void*, void*, void*, void (*)(__tsan::ThreadState*, unsigned long, unsigned long, int)) <null>:3 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2a5ba)
    #&#8203;2 callReturnNext<A>(_:using:) Crash3.swift:22 (Crash3:x86_64+0x100002a35)
    #&#8203;3 main Crash3.swift:28 (Crash3:x86_64+0x10000281e)
    #&#8203;4 start <null>:2 (libdyld.dylib:x86_64+0x1acc8)

==45104==Register values:
rax = 0x0000800000003db0  rbx = 0x0000000000000000  rcx = 0x0000000000003db0  rdx = 0x0000000000000000
rdi = 0x0000800000000000  rsi = 0x0001000000000000  rbp = 0x00007ffeec8e16a0  rsp = 0x00007ffeec8e1660
 r8 = 0x0000000000000001   r9 = 0x0000000000000000  r10 = 0x0000000107ba2420  r11 = 0x0000000103360ce0
r12 = 0x00000c0000003db0  r13 = 0x0000000103320a36  r14 = 0x0000000000000000  r15 = 0x00000001041e9400
ThreadSanitizer can not provide additional info.
SUMMARY: ThreadSanitizer: SEGV (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x5beb7) in __tsan::MemoryAccess(__tsan::ThreadState*, unsigned long, unsigned long, int, bool, bool)+0x97
==45104==ABORTING
Abort trap: 6

Adding and initializing a property on the private struct makes the problem go away.
This can be tried by compiling with:
swiftc -Onone -sanitize=thread -DWORKING main.swift

Metadata

Metadata

Assignees

Labels

TSanFor issues in the Thread Sanitizer itselfbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.genericsFeature: generic declarations and typesinoutFeature → types: `inout` typesswift 5.3unexpected errorBug: Unexpected error

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions