Skip to content

Thread pthread_t lifetime issues can cause memory corruption #5240

@weissi

Description

@weissi

If you run the below program (which is pretty silly), you'll see crashes very likely due to the fact that Foundation.Thread is holding onto pthread_t values whose lifetime has ended

import Foundation

func makeThread() -> Thread {
    let t = Thread {
        print("hi from thread")
        sleep(2)
    }
    t.start()
    return t
}

var threads: [Thread] = []
var i = 0
var arrays: [[UInt8]] = []
while true {
    arrays.append(
        Array(repeating: UInt8(0x41), count: 8388607)
    )
    let t = makeThread()
    threads.append(t)
    Thread.sleep(forTimeInterval: 0.1)
    print("hello from \(threads)")
    print(threads.map { t in
        t.name
    })
    Thread.current.name = "hey \(i)"
    threads.forEach { t in
        i += 1
        t.name = "foo \(i)"
    }
    print(Array(repeating: 4, count: 1000000).map { x in
        x * 2
    }.count)
    let memGood = arrays.allSatisfy { array in
        print(array.withUnsafeBufferPointer { $0 })
        return array.allSatisfy { $0 == 0x41 }
    }
    precondition(memGood)
    if arrays.count > 30 {
        arrays.shuffle()
        arrays.removeLast(15)
    }
}

e.g.

root@395116d91deb:/tmp/repro# swiftc test.swift && ./test
hi from thread
hello from [<Thread: 0x0000aaab16023170>]
[Optional("test")]
1000000
UnsafeBufferPointer(start: 0x0000ffff7dc00030, count: 8388607)
[...]
1000000
UnsafeBufferPointer(start: 0x0000ffff7dc00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff7c800030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff76c00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff75800030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff74400030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6ec00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6e200030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6d800030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6ce00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6c400030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff63600030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff62c00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff62200030, count: 8388607)
hi from thread
hello from [<Thread: 0x0000aaab16023170>, <Thread: 0x0000aaab160250a0>, <Thread: 0x0000aaab160253b0>, <Thread: 0x0000aaab160255c0>, <Thread: 0x0000aaab16025860>, <Thread: 0x0000aaab16025ce0>, <Thread: 0x0000aaab16025d70>, <Thread: 0x0000aaab16025f80>, <Thread: 0x0000aaab160262d0>, <Thread: 0x0000aaab160264f0>, <Thread: 0x0000aaab16026720>, <Thread: 0x0000aaab16026c10>, <Thread: 0x0000aaab16026e80>, <Thread: 0x0000aaab16027110>]
[Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78"), Optional("hey 78")]
1000000
UnsafeBufferPointer(start: 0x0000ffff7dc00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff7c800030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff76c00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff75800030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff74400030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6ec00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6e200030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6d800030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6ce00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff6c400030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff63600030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff62c00030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff62200030, count: 8388607)
UnsafeBufferPointer(start: 0x0000ffff61800030, count: 8388607)
hi from thread
hello from [<Thread: 0x0000aaab16023170>, <Thread: 0x0000aaab160250a0>, <Thread: 0x0000aaab160253b0>, <Thread: 0x0000aaab160255c0>, <Thread: 0x0000aaab16025860>, <Thread: 0x0000aaab16025ce0>, <Thread: 0x0000aaab16025d70>, <Thread: 0x0000aaab16025f80>, <Thread: 0x0000aaab160262d0>, <Thread: 0x0000aaab160264f0>, <Thread: 0x0000aaab16026720>, <Thread: 0x0000aaab16026c10>, <Thread: 0x0000aaab16026e80>, <Thread: 0x0000aaab16027110>, <Thread: 0x0000aaab16023360>]
[Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91"), Optional("hey 91")]

💣 Program crashed: Bad pointer dereference at 0x0000ffff7da0f170

Thread 0 "hey 105" crashed:

0 0x0000ffff810dcbfc <unknown> in libc.so.6
1 0x0000ffff81d5deec Thread.name.setter + 99 in libFoundation.so
2 0x0000aaaae01f2e54 <unknown> in test (deleted)
3 0x0000ffff826eeb88 Sequence.forEach(_:) + 431 in libswiftCore.so
4 0x0000aaaae01f3c54 <unknown> in test (deleted)
5 0x0000ffff810784c4 <unknown> in libc.so.6
6 0x0000ffff81078598 <unknown> in libc.so.6

Backtrace took 0.01s

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions