swiftlang / swiftlang/swift-corelibs-libdispatch

[SR-5988] Memory leak in libdispatch on Linux

Open
#676 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug libdispatch
Dominant language
C
Stars
2.6k
Forks
496
Avg merge
2d 6h
Merged PRs (30d)
3

Description

Previous ID SR-5988
Radar rdar://problem/34650486
Original Reporter oc243 (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 0
Component/s libdispatch
Labels Bug
Assignee None
Priority Medium

md5: 80b03af9cefdb8950af898e9b1733df6

Issue Description:

Running the code below on Linux leaks memory, but it works fine on Darwin. I don't think that the code should be leaking memory (due to the wait). Swapping the `x=x+1` for the `print()` also leaks.

import Dispatch

func foo(q: DispatchQueue, g: DispatchGroup) {
  for _ in 0..<200 {
    q.async(group: g) {
      print()
    }
  }
  g.wait()
}

let g = DispatchGroup()
let q1 = DispatchQueue(label: "com.queue", attributes: .concurrent)

while true {
  foo(q: q1, g:g)
}
swift --version
Swift version 4.0 (swift-4.0-RELEASE)
Target: x86_64-unknown-linux-gnu

My investigations suggest that the following calloc of 64 bytes is never freed:

0 libc-2.23.so 0x00007fe837b88fba __calloc + 682 at malloc.c:3199
1 libdispatch.so 0x00007fe83a195854 _dispatch_continuation_alloc_from_heap + 36
2 libdispatch.so 0x00007fe83a1a2e5f dispatch_group_async + 207
3 libdispatch.so 0x00007fe83a1b7b9a Dispatch.DispatchQueue.async(group: Swift.Optional<Dispatch.DispatchGroup>, qos: Dispatch.DispatchQoS, flags: Dispatch.DispatchWorkItemFlags, execute: @convention(block) () -> ()) -> () + 31

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided Swift 4 reproducer on Linux and examining the allocation path through dispatch_group_async and _dispatch_continuation_alloc_from_heap in libdispatch. Compare the behavior with Darwin and confirm that repeated calls to foo no longer cause memory growth or leave the reported 64-byte allocation unreleased.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, swift
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.