Repository navigation
Conversation
When linking fails, js_link_module() resets the modules left on the DFS stack to unlinked but keeps the variable references the partial link took: the import slots of the module function and the var_ref of each local export. The next import of the same module links it again and overwrites them without releasing the old references, so they leak in release builds and JS_FreeRuntime() fails the `list_empty(&rt->gc_obj_list)` assertion in debug builds. Release and clear those references when a module is reset, so it goes back to the state it had before linking. Namespace imports are variables of the module itself and are kept, as are the exports of C modules, which linking does not create. Fixes: quickjs-ng#1833
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When linking fails,
js_link_module()resets the modules left on the DFS stack to unlinked, but keeps the variable references the partial link took: the import slots of the module function (a counted reference to the exported variable, or a new variable for a namespace re-export) and thevar_refof each local export. The next import of the same module links it again and overwrites those pointers without releasing the old references. They leak in release builds, and debug builds fail thelist_empty(&rt->gc_obj_list)assertion inJS_FreeRuntime().This change releases and clears those references when a module is reset after a failed link, so the module goes back to the state it had before linking. Namespace imports are variables of the module itself and are kept, as are the exports of C modules, which linking does not create. The cleared slots are the same ones that
js_bytecode_function_finalizer()andjs_free_module_def()release later, so nothing is freed twice.tests/bug1833.jsimports a two-module cycle that fails to link, twice. It covers an import slot, a local export and a namespace re-export (export * as ns from). Without the fix, the test aborts on the assertion in a Debug build (three leaked var_refs) and LeakSanitizer reports a leak under ASan. With the fix, the test and both reproductions from the issue pass in Debug, ASan+UBSan and GC stress builds. The rest ofmake test, and the test262 module-code, dynamic-import and import directories under ASan+UBSan, show no new failures.