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

Intermittent preconditionFailure when building documentation for multiple modules in one docc convert call. #351

Closed
2 tasks done
heckj opened this issue Jul 30, 2022 · 9 comments
Assignees
Labels
bug Something isn't working

Comments

@heckj
Copy link
Member

heckj commented Jul 30, 2022

Description

I've been using the experimental --analyze feature for several months, and periodically it has been failing without any additional details - just a trap:

3430 Trace/BPT trap: 5       $(xcrun --find docc) convert Sources/SwiftVizScale/Documentation.docc --analyze --fallback-display-name SwiftVizScale --fallback-bundle-identifier com.github.swiftviz.SwiftVizScale --fallback-bundle-version 0.1.9 --additional-symbol-graph-dir .build/symbol-graphs --experimental-documentation-coverage --level brief

Checklist

  • If possible, I've reproduced the issue using the main branch of this package.
  • This issue hasn't been addressed in an existing GitHub issue.

Expected Behavior

report brief synopsis of the state of coverage for the documentation catalog in the project.

Actual behavior

3430 Trace/BPT trap: 5       $(xcrun --find docc) convert Sources/SwiftVizScale/Documentation.docc --analyze --fallback-display-name SwiftVizScale --fallback-bundle-identifier com.github.swiftviz.SwiftVizScale --fallback-bundle-version 0.1.9 --additional-symbol-graph-dir .build/symbol-graphs --experimental-documentation-coverage --level brief

Steps To Reproduce

  1. clone repo (public): git clone https://github.com/swiftviz/scale.git
  2. cd scale
  3. git checkout cc39b0a8becc14c471ebf857e825de4af997433c
  4. ./docreport.bash

Swift-DocC Version Information

d56e5a9

Swift Compiler Version Information

swift-driver version: 1.62.1 Apple Swift version 5.7 (swiftlang-5.7.0.123.7 clang-1400.0.29.50)
Target: arm64-apple-macosx12.0
@heckj heckj added the bug Something isn't working label Jul 30, 2022
@heckj
Copy link
Member Author

heckj commented Jul 30, 2022

I've compiled a local copy of docc from the main branch and run this under LLDB from the command line to get more details:

DOCC_HTML_DIR=/Applications/Xcode-beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/docc/render
# version is hardened, so I can't attach with the debugger to see what's happened
# DOCC=/Applications/Xcode-beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/docc

# built from source: d56e5a991991528c8396c0c6175ec8ee97e2bd6e (main branch)
DOCC=/Users/heckj/src/swift-project/swift-docc/.build/debug/docc

lldb $DOCC -- convert Sources/SwiftVizScale/Documentation.docc \
    --analyze \
    --fallback-display-name SwiftVizScale \
    --fallback-bundle-identifier com.github.swiftviz.SwiftVizScale \
    --fallback-bundle-version 0.1.9 \
    --additional-symbol-graph-dir .build/symbol-graphs \
    --experimental-documentation-coverage \
    --level brief

The error reported under LLDB was more informative:

SwiftDocC/DocumentationContext.swift:2236: Fatal error: Reference does not have an associated documentation node.
2022-07-30 10:30:21.533841-0700 docc[94104:3221654] SwiftDocC/DocumentationContext.swift:2236: Fatal error: Reference does not have an associated documentation node.
Process 94104 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = Fatal error: Reference does not have an associated documentation node.
    frame #0: 0x00000001b424132c libswiftCore.dylib`_swift_runtime_on_report
libswiftCore.dylib`:
->  0x1b424132c <+0>: ret

libswiftCore.dylib`:
    0x1b4241330 <+0>: b      0x1b424132c               ; _swift_runtime_on_report

libswiftCore.dylib`:
    0x1b4241334 <+0>: adrp   x8, 299488
    0x1b4241338 <+4>: ldrb   w0, [x8, #0x23c]
Target 0: (docc) stopped.

(referencing DocumentationContext.swift, line 2236)

I set a breakpoint to inspect the fragment:

breakpoint set --file DocumentationContext.swift --line 2233
run
fr v reference

And it's showing a fragment, with an available language, from a dependency of this library:

(SwiftDocC.ResolvedTopicReference) reference = {
  _storage = 0x0000600002cdb300 {
    bundleIdentifier = "com.github.swiftviz.SwiftVizScale"
    path = "/documentation/Numerics/AlgebraicField//(_:_:)-9bcy2"
    fragment = nil
    sourceLanguages = 1 value {
      [0] = {
        name = "Swift"
        id = "swift"
        idAliases = 0 values {}
        linkDisambiguationID = "swift"
      }
    }
    identifierPathAndFragment = "com.github.swiftviz.SwiftVizScale/documentation/Numerics/AlgebraicField//(_:_:)-9bcy2"
    url = "doc://com.github.swiftviz.SwiftVizScale/documentation/Numerics/AlgebraicField//(_:_:)-9bcy2"
    pathComponents = 5 values {
      [0] = "/"
      [1] = "documentation"
      [2] = "Numerics"
      [3] = "AlgebraicField"
      [4] = "(_:_:)-9bcy2"
    }
    absoluteString = "doc://com.github.swiftviz.SwiftVizScale/documentation/Numerics/AlgebraicField//(_:_:)-9bcy2"
  }
}

I looked briefly at what the error throwing method call (func entity(with reference: ResolvedTopicReference) throws -> DocumentationNode) does, and it looks like it's trying to look up a relevant DocumentationNode from a cache - only there's not going to be anything cached there for me (local build) since I don't have any external resolvers, and as far as I know - the dependency documentation isn't being built either.

I'm not sure of the context in the code of how we got here, or the overall flow of what's happening in these sources - but hoped this additional information would make it easier to highlight what could or should be resolved so that this experimental feature could be more stable.

@Kyle-Ye Kyle-Ye self-assigned this Jul 31, 2022
@Kyle-Ye
Copy link
Contributor

Kyle-Ye commented Aug 1, 2022

git checkout cc39b0a8becc14c471ebf857e825de4af997433c

git checkout cc39b0a8becc14c471ebf857e825de4af997433c
fatal reference is not a tree:cc39b0a8becc14c471ebf857e825de4af997433c

@heckj Could you please provide a branch for this commit? I can't easily checkout to this commit.

image

@heckj
Copy link
Member Author

heckj commented Aug 1, 2022

Absolutely @Kyle-Ye - I made a branch analyze_error from that commit and pushed it up just now.

The command git clone https://github.com/swiftviz/scale -b analyze_error

should clone the repo and get you to that specific commit in one command.

@heckj
Copy link
Member Author

heckj commented Aug 5, 2022

I'm doing a bit more debugging on this, and realized I should have included the backtrace (bt) earlier in order to make sure of how we got to hitting the failed assertion:


* thread #1, queue = 'com.apple.main-thread', stop reason = Fatal error: Reference does not have an associated documentation node.
  * frame #0: 0x00000001b424132c libswiftCore.dylib`_swift_runtime_on_report
    frame #1: 0x00000001b42d68d8 libswiftCore.dylib`_swift_stdlib_reportFatalErrorInFile + 208
    frame #2: 0x00000001b3ef9424 libswiftCore.dylib`Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 304
    frame #3: 0x00000001007951d0 docc`DocumentationContext.sourceLanguages(reference=SwiftDocC.ResolvedTopicReference @ 0x000000016fdf1838, self=0x0000000102705600) at DocumentationContext.swift:2236:13
    frame #4: 0x00000001007f735c docc`closure #1 in static GeneratedDocumentationTopics.createCollectionNode(identifier=SwiftDocC.ResolvedTopicReference @ 0x000000016fdf1888, context=0x0000000102705600) at GeneratedDocumentationTopics.swift:106:92
    frame #5: 0x00000001007f94e8 docc`partial apply for closure #1 in static GeneratedDocumentationTopics.createCollectionNode(parent:title:identifiers:context:bundle:) at <compiler-generated>:0
    frame #6: 0x00000001b4075d20 libswiftCore.dylib`Swift.Sequence.flatMap<τ_0_0 where τ_1_0: Swift.Sequence>((τ_0_0.Element) throws -> τ_1_0) throws -> Swift.Array<τ_1_0.Element> + 864
    frame #7: 0x00000001007f57dc docc`static GeneratedDocumentationTopics.createCollectionNode(parent=SwiftDocC.ResolvedTopicReference @ 0x000000016fdf32b0, title="Equatable Implementations", identifiers=3 values, context=0x0000000102705600, bundle=SwiftDocC.DocumentationBundle @ 0x000000016fdf8490, self=SwiftDocC.GeneratedDocumentationTopics) at GeneratedDocumentationTopics.swift:106:60
    frame #8: 0x00000001007f8bdc docc`static GeneratedDocumentationTopics.createInheritedSymbolsAPICollections(relationships=1603 values, context=0x0000000102705600, bundle=SwiftDocC.DocumentationBundle @ 0x000000016fdf8490, self=SwiftDocC.GeneratedDocumentationTopics) at GeneratedDocumentationTopics.swift:266:21
    frame #9: 0x00000001007817b4 docc`closure #1 in DocumentationContext.registerSymbols(bundle=SwiftDocC.DocumentationBundle @ 0x000000016fdf8490, documentationCacheBasedLinkResolver=0x0000600000c01830, symbolGraphLoader=SwiftDocC.SymbolGraphLoader @ 0x000000016fdf8550, self=0x0000000102705600) at DocumentationContext.swift:1272:46
    frame #10: 0x00000001007a0480 docc`partial apply for closure #1 in DocumentationContext.registerSymbols(from:symbolGraphLoader:) at <compiler-generated>:0
    frame #11: 0x00000001bb966ad4 libswiftObjectiveC.dylib`ObjectiveC.autoreleasepool<τ_0_0>(invoking: () throws -> τ_0_0) throws -> τ_0_0 + 64
    frame #12: 0x000000010077e5f8 docc`DocumentationContext.registerSymbols(bundle=SwiftDocC.DocumentationBundle @ 0x000000016fdf95d0, symbolGraphLoader=SwiftDocC.SymbolGraphLoader @ 0x000000016fdf8880, self=0x0000000102705600) at DocumentationContext.swift:1098:20
    frame #13: 0x000000010078c718 docc`DocumentationContext.register(bundle=SwiftDocC.DocumentationBundle @ 0x000000016fdf95d0, self=0x0000000102705600) at DocumentationContext.swift:1867:59
    frame #14: 0x000000010076c134 docc`closure #1 in DocumentationContext.dataProvider(bundle=SwiftDocC.DocumentationBundle @ 0x000000016fdf95d0, self=0x0000000102705600) at DocumentationContext.swift:315:22
    frame #15: 0x000000010078db50 docc`partial apply for closure #1 in DocumentationContext.dataProvider(_:didAddBundle:) at <compiler-generated>:0
    frame #16: 0x0000000100629a90 docc`benchmark<E, Result>(event=0x10076c01c, log=0x0000600002108640, body=0x10078db34) at Benchmark.swift:135:20
    frame #17: 0x000000010076bfa8 docc`DocumentationContext.dataProvider(dataProvider=0x0000600001705780, bundle=SwiftDocC.DocumentationBundle @ 0x000000016fdf9940, self=0x0000000102705600) at DocumentationContext.swift:311:13
    frame #18: 0x000000010079964c docc`protocol witness for DocumentationContextDataProviderDelegate.dataProvider(_:didAddBundle:) in conformance DocumentationContext at <compiler-generated>:0
    frame #19: 0x00000001008340d4 docc`DocumentationWorkspace.registerProvider(provider=SwiftDocC.LocalFileSystemDataProvider @ 0x0000600001700b90, options=SwiftDocC.BundleDiscoveryOptions @ 0x000000016fdf9dc0, self=0x0000600001705780) at DocumentationWorkspace.swift:123:27
    frame #20: 0x00000001007a99c8 docc`DocumentationConverter.convert<OutputConsumer>(outputConsumer=SwiftDocCUtilities.ConvertFileWritingConsumer @ 0x000000016fdfda10, self=SwiftDocC.DocumentationConverter @ 0x000000016fdfea18) at DocumentationConverter.swift:207:23
    frame #21: 0x0000000100af1754 docc`ConvertAction.perform(logHandle=standardOutput, self=SwiftDocCUtilities.ConvertAction @ 0x000000016fdfe910) at ConvertAction.swift:369:68
    frame #22: 0x0000000100af43bc docc`protocol witness for Action.perform(logHandle:) in conformance ConvertAction at <compiler-generated>:0
    frame #23: 0x0000000100b1e834 docc`Action.performAndHandleResult(self=SwiftDocCUtilities.ConvertAction @ 0x000000016fdfe910) at Action+performAndHandleResult.swift:25:26
    frame #24: 0x0000000100b4c230 docc`Docc.Convert.run(self=SwiftDocCUtilities.Docc.Convert @ 0x00000001026054b0) at Convert.swift:338:31
    frame #25: 0x0000000100b506e0 docc`protocol witness for ParsableCommand.run() in conformance Docc.Convert at <compiler-generated>:0
    frame #26: 0x0000000100042224 docc`static ParsableCommand.main(arguments=nil, self=SwiftDocCUtilities.Docc) at ParsableCommand.swift:97:19
    frame #27: 0x000000010004233c docc`static ParsableCommand.main(self=SwiftDocCUtilities.Docc) at ParsableCommand.swift:107:10
    frame #28: 0x0000000100c49c8c docc`docc_main at main.swift:14:6
    frame #29: 0x000000010238508c dyld`start + 520

@d-ronnqvist
Copy link
Contributor

On main I can reproduce the same preconditionFailure even if I remove the --analyze and --experimental-documentation-coverage --level brief flags, so we can rule those out.

@Kyle-Ye
Copy link
Contributor

Kyle-Ye commented Aug 8, 2022

I could not reproduce it under both Swift 5.6 toolchain (The default toolchain bundled by Xcode 13.4) and Swift 5.7 toolchain (The default toolchain bundled by Xcode 14 beta 4)

swift-driver version: 1.45.2 Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12)
Target: arm64-apple-macosx12.0
swift-driver version: 1.62.1 Apple Swift version 5.7 (swiftlang-5.7.0.123.7 clang-1400.0.29.50)
Target: arm64-apple-macosx12.0

Although the result is a little strange.

➜  scale git:(analyze_error) $(xcrun --find docc) convert 
<Warnings Info>
   --- Experimental coverage output enabled. ---
                | Abstract        | Curated         | Code Listing
Types           | (0/0)           | (0/0)           | (0/0)
Members         | (0/0)           | (0/0)           | (0/0)
Globals         | (0/0)           | (0/0)           | (0/0)

I'm running the following code cc @heckj

git clone https://github.com/swiftviz/scale -b analyze_error
cd scale
$(xcrun --find docc) convert Sources/SwiftVizScale/Documentation.docc --analyze --fallback-display-name SwiftVizScale --fallback-bundle-identifier com.github.swiftviz.SwiftVizScale --fallback-bundle-version 0.1.9 --additional-symbol-graph-dir .build/symbol-graphs --experimental-documentation-coverage --level brief

And I'll get the right result if I run the ./docreport.bash script.

<Warnings Info>
   --- Experimental coverage output enabled. ---
                | Abstract        | Curated         | Code Listing
Types           | 88% (63/72)     | 75% (54/72)     | 6.9% (5/72)
Members         | 55% (609/1108)  | 50% (558/1108)  | 12% (134/1108)
Globals         | 19% (11/57)     | 84% (48/57)     | 0.0% (0/57)

@d-ronnqvist
Copy link
Contributor

It's understandable that this wouldn't reproduce in the 5.6 toolchain. The sourceLanguages(for:) function that has this precondition is part of the multi-language feature that was added in the 5.7 release.

Like @franklinsch pointed out in the Forums topic this build setup is providing symbol graph files for multiple modules to DocC which isn't officially supported. This means that DocC is treats all 7 modules as a single unit and computes the documentation coverage for both SwiftVizScale and its dependencies (Collections, ComplexModule, DequeModule, Numerics, OrderedCollection, and RealModule) as one unit.

Passing only the SwiftVizScale symbol graph files produces the coverage information for only that module (see for example that there are 188 members instead of 1108):

   --- Experimental coverage output enabled. ---
                | Abstract        | Curated         | Code Listing
Types           | 100% (29/29)    | 100% (29/29)    | 0.0% (0/29)
Members         | 95% (178/188)   | 89% (167/188)   | 0.0% (0/188)
Globals         | 7.7% (1/13)     | 100% (13/13)    | 0.0% (0/13)

Building documentation for only SwiftVizScale will avoid this precondition failure and it will output the coverage information that I think you're looking for.

I'll update the title of this issue to reflect the cause of the crash.

@d-ronnqvist d-ronnqvist changed the title convert --analyze function fails (intermittently) without error message Intermittent preconditionFailure when building documentation for multiple modules in one docc convert call. Aug 8, 2022
@heckj
Copy link
Member Author

heckj commented Aug 8, 2022

@d-ronnqvist Thank you!! I was just following up and finding that the main branch also hit that precondition, and didn't know about (or understand) the constraint that I should only be providing the symbol graph files for the specific target I was after. I'd erroneously thought that it only grabbed what it needed, but in hind sight it becomes clear these older docc convert commands don't use --target which narrows it down to the specific symbol graph, and which I'd become used to seeing with the docc-plugin scripts.

Thank you, this gives me a much easier way to work around things and get reporting!

@d-ronnqvist
Copy link
Contributor

Since this was using the experimental coverage feature it's probably the same issue that was fixed by #697.

Feel free to reopen this issue, or open a new one, if this crash continues to happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants