Failed module link leaves orphan var_refs and aborts JS_FreeRuntime (gc_obj_list assertion)
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 45/100
Direzione di ricerca
Start with the module-link failure path and JS_FreeRuntime in quickjs.c, using the provided deep.js and repeat.js reproductions. Trace cleanup of rejected module graphs and the orphan var_ref GC objects, then add or update a regression test that runs these imports with assertions enabled. Done means imports reject normally, runtime teardown leaves the GC list empty, and qjs exits without an assertion.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
A failed module link can leave orphan var_ref GC objects and make JS_FreeRuntime abort, even when the failure is caught through Promise.allSettled. This reproduces in the pure-C qjs CLI, without Rust, an embedding, or retained host values.
Confirmed with assertions enabled on:
- quickjs-ng v0.15.1, commit
fd0a0210b7be00957751871e7e01b8291268fc29 - quickjs-ng master at commit
5271a40beffef45e2eaccc8d22969cac9a4b394c
A backport of the module-lifetime change in PR #1751 onto v0.15.1 does not resolve this separate failed-link abort. It was also reconfirmed on both unpatched v0.15.1 and that backport with ASan+UBSan enabled.
Minimal standalone reproduction
Create these files in one directory (no other dependencies):
// dep.js
export const a = 1;
// shared.js
let s = 1;
export function get() { return s; }
export let live = 2;
export const touch = () => { s += live; return s; };
// mid.js
import { get } from './shared.js';
import { b } from './dep.js'; // intentionally missing export
let m = 0;
export const g = () => m + get() + b;
// main3.js
import { g } from './mid.js';
export const h = () => g();
The following two entry modules independently trigger the abort:
// deep.js
const r = await Promise.allSettled([
import('./shared.js'), import('./main3.js'), import('./mid.js')
]);
print(r.map(x => x.status + ':' + String(x.reason)).join(' | '));
// repeat.js
const r = await Promise.allSettled([import('./main3.js'), import('./main3.js')]);
print(r.map(x => x.status + ':' + String(x.reason)).join(' | '));
Run with assertions enabled:
qjs -m deep.js
qjs -m repeat.js
Exact v0.15.1 output for deep.js (exit status 134):
fulfilled:undefined | rejected:SyntaxError: Could not find export 'b' in module 'dep.js' | rejected:SyntaxError: Could not find export 'b' in module 'dep.js'
qjs: quickjs.c:2348: JS_FreeRuntime: Assertion `list_empty(&rt->gc_obj_list)' failed.
Exact v0.15.1 output for repeat.js (exit status 134):
rejected:SyntaxError: Could not find export 'b' in module 'dep.js' | rejected:SyntaxError: Could not find export 'b' in module 'dep.js'
qjs: quickjs.c:2348: JS_FreeRuntime: Assertion `list_empty(&rt->gc_obj_list)' failed.
On master 5271a40, both reach the same assertion at line 2698:
qjs: quickjs.c:2698: JS_FreeRuntime: Assertion `list_empty(&rt->gc_obj_list)' failed.
For comparison, this single-import entry exits normally:
// single.js
const r = await Promise.allSettled([import('./main3.js')]);
print(r.map(x => x.status + ':' + String(x.reason)).join(' | '));
Observations and expected behavior
The first trigger reaches the failing mid.js both directly and through its importer main3.js. The second dynamically imports the same failing graph twice. A separate small embedding using the same graph and the engine's leak dump reports one and two orphan var_ref objects respectively, rather than retained JS objects/functions/promises. The CLI reproduction above removes the embedding entirely.
Expected: the imports reject, the rejections can be handled, and runtime teardown releases the failed graph without aborting. This report concerns failed linking, not native-module finalization. The assertion prevents LeakSanitizer's normal exit check on these failing cases; no claim of a clean leak check is made for that path.
- Lingua principale
- C
- Stelle
- 3.9k
- Fork
- 389
- Merge medio
- 4g 1h
- PR unite (30g)
- 24
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di quickjs-ng/quickjs
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
quickjs-ng/quickjs#1836 ·
I maintainer di solito rispondono entro 2 giorni
-
Array.prototype.find frees an element twice when interrupted between iterationsForse già presa @josefguenther l’ha presa 14 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
quickjs-ng/quickjs#1792 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Object.prototype.propertyIsEnumerable converts `this` before the property keyForse già presa @SomSamantray l’ha presa 10 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
quickjs-ng/quickjs#1772 ·
I maintainer di solito rispondono entro 2 giorni
-
Deserialization corrupts data or returns `undefined` when a RegExp precedes a shared object referenceForse già presa @Sree24-ui l’ha presa 14 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
quickjs-ng/quickjs#1771 · 2 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 72/100
quickjs-ng/quickjs#1835 · 1 reazione ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di quickjs-ng/quickjs
Issue simili
-
v9.6.0: CMake incorrectly enforces presence of libevdevForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
I maintainer di solito rispondono entro 1 giorno
-
IoTSDK
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
Azure/azure-iot-sdk-c#2776 ·
I maintainer di solito rispondono entro 2 giorni
-
[Bug] Unhandled ValueError terminates watchdog thread when GISRC value contains multiple colonsApertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
bug Component component: net
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
RT-Thread/rt-thread#11913 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
contiki-ng/contiki-ng#3289 ·
I maintainer di solito rispondono entro 3 giorni