process_info(Pid, heap_size) changed between OTP 26 and 27

When executing a testcase for AtomVM, but in this case actually running on the BEAM, where you compare the heap size before and after a garbage collect it has stopped working after OTP 27.
The process_info(Pid, heap_size) now returns the same value before and after the garbage collection.
Changing the selector to process_info(Pid, total_heap_size) gives a smaller size after the gc and the test case starts working again.
I haven’t found any notes in the upgrade documentation on changes in the heap handling or process_info call that would affect this. Do anyone know what has changed?

Seem to be a race in the testcase or somthing like that. When running it just once in 27 and 26 I don’t get any failures, but when running it 1000 times I get failures on both 27 and 26.

If I run it from the erlang shell it works fine for me too.
It is actually run from a wrapper executable and in that case it still fails even if I add a timer:sleep(1000) after the gc. But now it looks to me as if it is the wrapper that causes the issue.

I tested a bit more and it turns out that the testcases are wrapped in an erl command within an -eval switch, composed in c code. The eval string ends with ..., erlang:halt(S). . If the ending period (“.”) is removed likeerlang:halt(S) , the testcase works. I do not know what changed in OTP 27 to cause this, but from the documentation it looks as if the eval strings should not end with a “.” anyway.

1 Like

Thank you for finding out about the dot.

My theory is that the eval string is parsed and evaluated by the very process that runs the start function, and the dot has some consequence on the heap usage of this process. This causes the test to fail because the heap is not totally shrunk. The eval string may be kept somehow from the caller. The test passes if its start function spawns a new process which does run the test code.

I established this after having been able to reproduce the test failure with strings of variable length passed to erl.

docker run -w /mnt -v $PWD:/mnt -it erlang:27 erl -pa . -noshell -eval 'erlang:process_flag(trap_exit, false), io:format("test_gc\n"), 0 = test_gc:start(), io:format("ok 123456789012345678901234567890123456789012345678901234567890\n"), erlang:halt(0).'

passes, while

docker run -w /mnt -v $PWD:/mnt -it erlang:27 erl -pa . -noshell -eval 'erlang:process_flag(trap_exit, false), io:format("test_gc\n"), 0 = test_gc:start(), io:format("ok 1234567890123456789012345678901234567890123456789012345678901234567890\n"), erlang:halt(0).'