Closed gaultier closed 4 days ago
I'm not sure how -default-to-nil-allocators
is supposed to work, so can't tell enough about the bug. Seems like os2 is implemented correctly though.
The crash is happening on this line of code:
For now figuring out what exactly is broken, and whether it's broken at all. I thought that maybe my core:mem
PR was breaking it, but checking out the commit before this PR was merged still reproe'd the bug.
When compiling with -default-to-nil-allocator and setting context.allocator and context.temp_allocator to custom allocators, I expect os2.process_start to use these. But it does not.
Yes, it shouldn't. os2
's temp_allocator()
is supposed to not be affected by context
, that's on purpose. The idea is that if it comes from the context it can break (because we have to handle all allocator errors from user context), but if have a separate allocator just for the things that are alive during the oscall procedure, we don't have to handle allocator errors as much.
Additionally, that means that it is not visible from the signature of the function that it allocates and we cannot provide it a specific allocator just for one call e.g. os.process_start(desc, allocator=foobar).
This is also expected, because process_start()
, actually does not allocate any memory that you have to free in a later call. Everything that this function allocates is deallocated within the same function, so it's all temporary allocations to get the right strings to supply to the OS.
Running hypothesis is that -default-to-nil-allocator
somehow makes os2.temp_allocator()
a nil
allocator.
I believe context.temp_allocator
works despite this because of the when
block at the top of base/runtime/default_temporary_allocator.odin
. However, the user can always overwrite that. This is not the case for the os2
's temp_allocator
.
E: -default-to-nil-allocator
causes runtime.default_allocator
to be the nil_allocator
. The os2
temp_allocator
uses runtime.arena_allocator_proc
. When that requires more memory it requests it from runtime.default_allocator
.
Thank you for the prompt response. The fix should work, I’ll try it when I get back to a computer. (EDIT: I tried, Confirmed to work).
However, one disadvantage to this approach is that if someone wants to prevent any allocations using the default allocators, meaning they want to control how every and any allocation is done (for example on a tiny ARM 32 device), then the current code paired with the option “-default-to-nil-allocator” is misleading, this goal won’t be achieved. Behind the scenes, the default allocators are still being used silently sometimes.
Now I don’t know if this goal is supported by Odin, or if the docs should clarify what this command line option really does?
Context
odin report
output:Expected Behavior
When compiling with
-default-to-nil-allocator
and settingcontext.allocator
andcontext.temp_allocator
to custom allocators, I expectos2.process_start
to use these. But it does not.Current Behavior
os2.process_start
accessestemp_allocator()
meaning the default global temp allocator instead of usingcontext.allocator
orcontext.temp_allocator
. With the build option-default-to-nil-allocator
, that leads eventually to a panic or failed assert.Additionally, that means that it is not visible from the signature of the function that it allocates and we cannot provide it a specific allocator just for one call e.g.
os.process_start(desc, allocator=foobar)
.Steps to Reproduce
Here is a program that sets
context.allocator
andcontext.temp_allocator
to fixed arenas and tries to spawn a process (does not matter which one) withos2.process_start
. It will end up in a failed assert because it tries to use the default general temp allocator to allocate some memory (to convert the executable name to acstring
). This general temp allocator cannot allocate any memory because its backing allocator (the general purpose default allocator) is nil.Failure Logs
Run:
GDB:
Suggestion: A
allocator
should be present as one of the arguments ofos2.process_start
and be used inside it.