-
-
Notifications
You must be signed in to change notification settings - Fork 672
A specific pattern of pushes to array causes a runtime error in ~lib/rt/tlsf/insertBlock #1042
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
Comments
A reduced example: const tracing: i32[] = [ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 16, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 11, 0, 11, 0, 11, 0, 11, 0, 11, 0, 11, 0, 11, 0, 11, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 17, 0, 17, 0, 17, 0, 17, 0, 17, 0, 17, 0, 17, 0, 17, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 13 ];
const arrayBuffer: Array<i32[]|null> = new Array( 32 );
arrayBuffer.fill( null );
function push( arrayId: i32 ): void {
let array = arrayBuffer[ arrayId ];
if ( array === null ) {
array = [];
arrayBuffer[ arrayId ] = array;
}
array.push( 0 );
}
for ( let j = 0; j < 2; j++ ) {
for ( let i = 0; i < tracing.length; i++ ) {
push( tracing[ i ] );
}
} |
It seems problem with alignment for data memory section. If comment last 8 bytes in tracing array issue is gone: |
minimal example: EDITED const tracing = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1];
const arrayBuffer = new Array<i32[] | null>(2);
for (let j = 0; j < 2; j++) {
for (let i = 0; i < tracing.length; i++) {
let id = tracing[i];
let arr = arrayBuffer[id];
if (!arr) arr = arrayBuffer[id] = [];
arr.push(0);
}
} |
@MaxGraey it seems like in your example |
Yeah, good catch! fixed this (see EDITed version) |
Reduced a little more {
let arrays = new Array<i32[] | null>(2);
for (let i = 0; i < 18; i++) {
let id = i % 2;
let arr = arrays[id];
if (!arr) arr = arrays[id] = new Array();
arr.push(0);
}
} From toying around with it it seems that this might have something to do with |
I'm not sure if this is related or not, but I've also found another bug: let arrays = new Array<i32[]>(1);
const x = arrays[0]; This will fail in |
This error is expected because the value type is a non-nullable |
Got it, thanks for explanation, @dcodeIO |
Reduced the example a little more: {
let arrays: i32[][] = [ [], [] ];
for (let i = 0; i < 18; i++) {
let id = i % 2;
arrays[id].push(0);
}
} |
{
let a1 = new Array<i32>(); // 2128, buf=2160
let a2 = new Array<i32>(); // 2192, buf=2224
// ALLOC 2256 \
// FREE 2160 @ 1 | grow a1, buf=2256
// ++ 2256 @ 0->1 /
// ALLOC 2304 \
// FREE 2224 @ 1 | grow a2, buf=2304
// ++ 2304 @ 0->1 /
// ALLOC 2352 \
// FREE 2256 @ 1 | grow a1, buf=2352
// ++ 2352 @ 0->1 /
// ALLOC 2224 \
// abort | grow a2?
a1.push(0);
a1.push(0);
a1.push(0);
a1.push(0);
a1.push(0);
a1.push(0);
a1.push(0);
a1.push(0);
a2.push(0);
a2.push(0);
a2.push(0);
a2.push(0);
a2.push(0);
a2.push(0);
a2.push(0);
a2.push(0);
a1.push(0);
a2.push(0); // here
} |
The assertion should be fixed now, but when I tested the initial code sample I noticed that there's some leaking going on that I can't yet explain. |
Turned out there was an issue with RTrace not accounting for some realloc changes, leading to false reporting of leaks. Initial example looks fine in tracing now. |
Going ahead and closing this issue. Please let me know if there's still something wrong :) |
This is another of "randomly occurred after a couple of seconds" errors. This time it was caused by pushing into an array. As you can see from the code, I've basically recorded and replicated a pattern of pushes that lead to an error.
Webassembly studio: https://webassembly.studio/?f=ul7d4jxj0rd
Code:
Stack trace:
The text was updated successfully, but these errors were encountered: