SU4 WASI `fd_read` always returning error 29, even if read is successful

Version: 1.6.3.0

Frequency: Consistently

Severity: Blocker

Bug description: In SU4, when using fread (so fd_read under the hood), it is consistently returning 0 for number of bytes read, along with the error number 29 regardless of if the operation actually succeeded.

Repro steps:

Try the following snippet in SU4

// Write to a test file and close it
FILE* handle = fopen("\\work\\test.dat", "w");
if (handle) {
    fprintf(handle, "test");
    fclose(handle);
}

// Open it again and try to read
handle = fopen("\\work\\test.dat", "r");
if (handle) {
    char buffer[4];
    int read = fread(buffer, 1, 4, handle);
    printf("Succesfully read %d bytes: %s\n", read, buffer);
    printf("errno = %d", errno); 
    fclose(handle);
}

This should print

Successfully read 4 bytes: test
errno = 0

But it actually prints

Successfully read 0 bytes: test
errno = 29
2 Likes

Hi @jack,

The issue regarding fread setting errno to 29 has been fixed on our end - the fix will be available in 1.6.6.0 or higher (not in the next 1.6.5.0 to be published in the coming days).

After fixing this and implementing unit tests to avoid future regressions, we discovered that fopen would always set errno to 59 when used to open a file for writing. Upon investigating, we realized the issue came from the wasi-libc which we distribute with the SDK.

An issue has been opened on the wasi-libc gitHub and it looks like the bug is confirmed. We will let you know as soon as it is fixed and integrated in the MSFS SDK (we might fix it ourselves and send a PR to the team in charge). In the meantime, I suggest resetting errno to 0 manually after opening a file for writing.

Best regards,

Eric / Asobo

1 Like

Hi Eric,

That is great news, thank you for your prompt resolution! Interesting to see a bug in the official wasi-libc :sweat_smile:

Does your fix also address nread being set to 0? I don’t think I highlighted that well in the initial report

Thanks again,

Jack

Hi Jack,

Here is the test case I used:

UnitTest::Result Test_WriteRead::ExecuteCore()
{

	Log("errno1 = %d", errno); 
	FILE* handle = fopen("\\work\\test.dat", "w");
	if (!handle)
	{
		m_sError = "Could not open file for writing";
		return UnitTest::Result::FAILURE;
	}

	Log("errno2 = %d", errno); 
	fprintf(handle, "test");
	Log("errno3 = %d", errno); 
	fclose(handle);
	Log("errno4 = %d", errno); 

	// Open it again and try to read
	handle = fopen("\\work\\test.dat", "r");
	if (!handle)
	{
		m_sError = "Could not open file for reading";
		return UnitTest::Result::FAILURE;
	}

	char buffer[4];
	Log("errno5 = %d", errno); 
	int read = fread(buffer, 1, 4, handle);
	buffer[4] = 0;
	Log("Succesfully read %d bytes: %s\n", read, buffer);
	Log("errno6 = %d", errno); 
	fclose(handle);

	return UnitTest::Result::SUCCESS;
}

Here is what the console outputs when the code gets executed:

[USER] [TestsModule.wasm] [Test 1] --------------------
[USER] [TestsModule.wasm] [Test 1] Launching Test: WriteRead Test
[USER] [TestsModule.wasm] [Test 1] errno1 = 0
[USER] [TestsModule.wasm] [Test 1] errno2 = 59
[USER] [TestsModule.wasm] [Test 1] errno3 = 59
[USER] [TestsModule.wasm] [Test 1] errno4 = 59
[USER] [TestsModule.wasm] [Test 1] errno5 = 59
[USER] [TestsModule.wasm] [Test 1] Succesfully read 4 bytes: test
[USER] [TestsModule.wasm] [Test 1] errno6 = 59
[USER] [TestsModule.wasm] [Test 1] Finished Test: WriteRead Test - SUCCESS

As you can see the “read” variable is properly set to 4.

One note though: this bit of code is unsafe since we are doing a printf in the Log function with the “%s” format code on a non-null terminated string. :stuck_out_tongue:

Anyway, it looks like the number of bytes read is now correct.

Best regards,

Eric / Asobo

1 Like

Hi @EPellissier ,

I read files but a bit different, via ifstream and write via ofstream. Those functions were affected in the same way? because I am also unable to read data now with SU4.

Glad to see you guys found out what is going on.. haha

Best,
Raul

Ok great :wink:. Thanks for your transparency with this issue!

/ Jack

We discussed this in PM but so that everybody knows: the same fix will fix Raul’s issue. :wink:

Best regards,

Eric / Asobo

1 Like