-
Notifications
You must be signed in to change notification settings - Fork 12
Fix memory leaks #22
Fix memory leaks #22
Conversation
|
FYI: this seems to still need some work. I'm on it, stay tuned (aiming for later today)! |
|
@regexident Thanks for the heads-up. Awesome work so far! I converted this PR to a draft to make sure this doesn't get merged accidentally before it's ready. What else needs to go in? |
|
The remaining issues at hand:
See latest commits. |
|
With these latest commits pushed this PR should be (almost) ready to review/merge. I say "almost" since interestingly now the XCTAssertEqual failed: (
"<p><a href="https://www.un.org/en/universal-declaration-human-rights/" title="View full version">Universal Declaration of
Human Rights</a></p>
"
) is not equal to (
"<p><a href="https://www.un.org/en/universal-declaration-human-rights/" title="View full version"></a></p>
"
)
As you can see the description lacks the title "Universal Declaration of Human Rights" for some weird reason. So to get an idea of where the fault is I added this to the test method: print()
print("Initial:", link)
print()
print("Initial title:", link.title as Any)
print()
print("Commonmark:", commonmark)
print()
print("Decoded:", decoded[0])
print()
print("Decoded title:", decoded[0].title as Any)
print()Which produced the following: So it looks like the title gets lost in the decoding somehow. Which is weird, since it's based on the same call to But wait, it gets even weirder! 🤯 If I call Any idea what's going on here, @mattt? |
Due to the memory leak caused by never setting `self.managed = true` on decoding of `Document` the dangling pointers produced by `Node.init(from:)` did not cause a crash before. The implementation simply decoded a `Document` and then pulled its root node out without properly unlinking it from the document and re-assigning the memory management duties.
Remove implicit internal access modifier
…anaged:` argument
…with `node.drain()`
…'s underlying format anyway
… failing `func testInlineElementCodingRoundTrip()`
|
Running the unit tests with Address Sanitizer enabled shows the root cause of the test failure for |
|
@regexident I spent a good hour or two trying to find anything wrong with the code you wrote. After exhausting all of my leads, I considered whether the memory bug was in cmark itself (as ASAN seemed to indicate). Sure enough, updating to 0.29.0 (#24) resolves the failing test case. |
|
Hah! I spent some time in the cmark code-base looking, too. But mostly looking for things that might point to CommonMark making wrong use of their API, but couldn't find anything. Thanks for the helping hand @mattt! |
Annotate removeChildren with @discardableResult Move removeChildren declaration under remove Rewrite inline comments
Make references to node, inline elements, block structures, and list items consistent
|
LGTM! 💪 |
|
Thanks for your patience and all of your help with this, @regexident. Merging this in now! |
|
Awesome! Glad I could help. 🙂 |
Fixes a memory leak in
Document.init(_:options:), as well as a memory safety bug (dangling pointers) caused by an erroneous implementation ofNode.init(from:), which was hidden by the memory leak.Due to the memory leak caused by never setting
self.managed = trueon decoding ofDocumentthe dangling pointers produced byNode.init(from:)did not cause a crash before.The previous implementation simply decoded a
Documentand then pulled its root node out without properly unlinking it from the document and re-assigning the memory management duties. So when theDocumentgets deinitialized any pointers to its contents are no longer valid (unless the document leaks its contents, which it did).Fixes #19