Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-696] EXC_BAD_ACCESS on returning a throwing Dictionary #43311

Closed
AliSoftware opened this issue Feb 9, 2016 · 5 comments
Closed

[SR-696] EXC_BAD_ACCESS on returning a throwing Dictionary #43311

AliSoftware opened this issue Feb 9, 2016 · 5 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software run-time crash Bug → crash: Swift code crashed during execution SILGen Area → compiler: The SIL generation stage

Comments

@AliSoftware
Copy link
Contributor

Previous ID SR-696
Radar None
Original Reporter @AliSoftware
Type Bug
Status Resolved
Resolution Cannot Reproduce

Attachment: Download

Environment

Xcode 7.2.0 & 7.2.1

$ swift --version
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, RunTimeCrash, SILGen
Assignee None
Priority

md5: 7b824fc2a06caeee5b99f3f8ad73bb66

Issue Description:

Summary

When creating a Dictionary literal containing values build from a throwing expression, the code often crashes with EXC_BAD_ACCESS (it seems while trying to release the dictionary being constructed)

How to reproduce

enum Crash: ErrorType { case Boom }
func kaboom(str: String) throws -> String {
  throw Crash.Boom
}

// Crash with EXC_BAD_ACCESS, not every time but quite often
func test4() throws -> [String:String] {
  return [
    "foo": try kaboom("test4")
  ]
}

Stacktrace

When crashing, the stacktrace looks like this (extract from REPL; had similar stacktrace in my full project in Xcode):

12> try test4()
Execution interrupted. Enter Swift code to recover and continue.
Enter LLDB commands to investigate (type :help for assistance.)
 13> :bt
* thread #​1: tid = 0x987f8, 0x00000001002518bf libswiftCore.dylib`swift_unknownRelease + 31, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x7908b7f1c120)
  * frame #​0: 0x00000001002518bf libswiftCore.dylib`swift_unknownRelease + 31
    frame #&#8203;1: 0x000000010054c43e $__lldb_expr2`__lldb_expr_1.test4 ($error=ErrorType @ 0x00007fff5fbffd40) throws -> Swift.Dictionary<Swift.String, Swift.String> + 430 at repl.swift:9
    frame #&#8203;2: 0x000000010054cae6 $__lldb_expr4`main + 134 at repl.swift:12
    frame #&#8203;3: 0x0000000100000df0 repl_swift`_mh_execute_header + 3568
    frame #&#8203;4: 0x00007fff8d0ad5ad libdyld.dylib`start + 1
    frame #&#8203;5: 0x00007fff8d0ad5ad libdyld.dylib`start + 1

Observed with any compiler optimization level

I tried pasting that code in a main.swift and compiling it with both swiftc main.swift, swift -O main.swift and swift -Onone main.swift. No matter what, the crash happens with all three optimization levels when running the ./main compiled code.

Complete example with multiple tested variants

Here are other various tests I tried and their result (see also attached file)

It seems whatever I try, as soon as I build a Dictionary literal with a throwing expression as value it might crash. Doesn't seem to happen when building an Array literal, only with Dictionary (or I've been very lucky after 20x tries with arrays).

enum Crash: ErrorType { case Key(String) }
func kaboom(str: String) throws -> String {
  throw Crash.Key(str)
}

// Crash with EXC_BAD_ACCESS, not every time but quite often
func test1() throws -> [String:[String]] {
  return [
    "foo": try [kaboom("test1a"), kaboom("test1b")]
  ]
}

// Crash with EXC_BAD_ACCESS, not every time but very often
func test2() throws -> [String:Any] {
  return [
    "foo": try ["test2a","test2b"].map { try kaboom($0) }
  ]
}

// Crash with EXC_BAD_ACCESS sometimes, but way less often
func test3() throws -> [String:Any] {
  let t: [String:Any] = [
    "foo": try ["test3a","test3b"].map { try kaboom($0) }
  ]
  return t
}

// Crash with EXC_BAD_ACCESS, not every time but quite often
func test4() throws -> [String:String] {
  return [
    "foo": try kaboom("test4")
  ]
}


// Crash with EXC_BAD_ACCESS, not every time but quite often
func test5() -> [String:Any] {
  do {
    return [
      "foo": try [kaboom("test5a"), kaboom("test5b")]
    ]
  } catch {
    print(error)
    return [:]
  }
}


// Seems ok
func test6() throws -> [Any] {
  return [try kaboom("test6a"), try kaboom("test6b")]
}



// Obviously only test one case at a time to isolate the issue

do {
  // randomly EXC_BAD_ACCESS
  try test1()
} catch { print(error) }

do {
  // randomly EXC_BAD_ACCESS
  try test2()
} catch { print(error) }

do {
  // randomly EXC_BAD_ACCESS
  try test3()
} catch { print(error) }

do {
  // randomly EXC_BAD_ACCESS
  try test4()
} catch { print(error) }

// randomly EXC_BAD_ACCESS
test5()

do {
  // Seems ok, didn't manage to make it crash
  try test6()
} catch { print(error) }

Attached sample code

The above code has been embedded in the attached file main.swift with #if blocs for testing convenience. Simply use swiftc main.swift -DTEST1 then run ./main multiple times to reproduce the segfault using the test1() case; same for test2(), etc.

@swift-ci
Copy link
Collaborator

swift-ci commented May 4, 2016

Comment by Sergey Galezdinov (JIRA)

Caught that with an array.

indirect enum Test {
  case .One(String)
  case .Two(String, Test)
}

enum Crash: ErrorType { case Key(String) }
func kaboom(str: String) throws -> Test {
  throw Crash.Key(str)
}

struct Example {
  var items: [Test] = []()

  public mutating func addItem() throws {
        items.append(.Two(.StringValue("whatever"), try kaboom("addItem")))
    }
}

@swift-ci
Copy link
Collaborator

swift-ci commented May 7, 2018

Comment by Ivan Gulakov (JIRA)

Seems like that issue does not exist anymore. I've run attached file (swift 4.1) and all tests passed.

@AliSoftware
Copy link
Contributor Author

@ivan Gulakov did you try to run the test multiple times — and properly activate one of the 6 tests with -DTEST1 etc? (I'm not at a computer to test by myself rn)

As this crash only happened sometimes at that time, maybe it just happens less often now with Swift 4.1 compiler but is still present? Just want to be sure before really considering this fixed 😉

@swift-ci
Copy link
Collaborator

swift-ci commented May 7, 2018

Comment by Ivan Gulakov (JIRA)

@AliSoftware Yes I did. I've run every test 50 times. Seems like it's really fixed in 4.1.

@AliSoftware
Copy link
Contributor Author

Cool![]( Really good news then) Thanks for the tests 🙂

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added the crash Bug: A crash, i.e., an abnormal termination of software label Dec 12, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software run-time crash Bug → crash: Swift code crashed during execution SILGen Area → compiler: The SIL generation stage
Projects
None yet
Development

No branches or pull requests

3 participants