AP_Common: effectively wrap malloc to zero memory in SITL under Cygwin - #31036
Merged
Conversation
tpwrules
commented
Sep 3, 2025
tpwrules
force-pushed
the
pr/cygwin-zero
branch
from
September 3, 2025 22:22
40d4fbd to
b024d6d
Compare
tpwrules
commented
Sep 4, 2025
This currently does not work, in particular resulting in scripting raising an internal error on stop because it doesn't think all the memory is freed because the allocated counter doesn't start out at zero because the zero on allocation behavior is broken. Cygwin has some support for overriding `malloc` (https://cygwin.com/faq/faq.html#faq.programming.own-malloc), but when this is attempted some logic in the runtime detects this case then forwards all allocator calls (`free`/`calloc`/etc.) to the user provided allocation functions. If only `malloc` is overridden, the other functions just call themselves recursively until the stack overflows. There is no supported way to use the original Cygwin allocator while overriding `malloc`, but we do not want to include our own allocator just for Cygwin. Fortunately, in some sense, there is an unsupported way, and our goal can be achieved by overwriting an internal pointer with our `malloc` implementation after the Cygwin runtime logic checks and believes that no overwrite has occurred, thereby never enabling the redirection and allowing non-`malloc` functions to still work. Our version then calls `calloc` to do the allocation and zeroing. Note that the old wrap of `_malloc_r` was faulty as that symbol is no longer used by newlib; it's just `#define`d to `malloc` these days. Tested that at least the scripting issue is fixed by failing to replicate it, plus tracing execution with `gdb` to confirm that our wrapper function is executed and does its job. The correct solution is to not make ArduPilot call `malloc` at all. We still cannot safely change the semantics to make it returned zeroed memory. This is quite the hack!
This is now accomplished at runtime, and the wrap of `_malloc_r` never worked properly anyway.
tpwrules
force-pushed
the
pr/cygwin-zero
branch
from
September 4, 2025 08:23
b024d6d to
99ae053
Compare
robertlong13
approved these changes
Sep 4, 2025
robertlong13
left a comment
Contributor
There was a problem hiding this comment.
Tested the artifacts with Mission Planner. No issues.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This currently does not work, in particular resulting in scripting raising an internal error on stop because it doesn't think all the memory is freed because the allocated counter doesn't start out at zero because the zero on allocation behavior is broken.
Cygwin has some support for overriding
malloc(https://cygwin.com/faq/faq.html#faq.programming.own-malloc), but when this is attempted some logic in the runtime detects this case then forwards all allocator calls (free/calloc/etc.) to the user provided allocation functions. If onlymallocis overridden, the other functions just call themselves recursively until the stack overflows. There is no supported way to use the original Cygwin allocator while overridingmalloc, but we do not want to include our own allocator just for Cygwin.Fortunately, in some sense, there is an unsupported way, and our goal can be achieved by overwriting an internal pointer with our
mallocimplementation after the Cygwin runtime logic checks and believes that no overwrite has occurred, thereby never enabling the redirection and allowing non-mallocfunctions to still work. Our version then callscallocto do the allocation and zeroing. Note that the old wrap of_malloc_rwas faulty as that symbol is no longer used by newlib; it's just#defined tomallocthese days.Tested that at least the scripting issue is fixed by failing to replicate it, plus tracing execution with
gdbto confirm that our wrapper function is executed and does its job.The correct solution is to not make ArduPilot call
mallocat all. We still cannot safely change the semantics to make it returned zeroed memory. This is quite the hack!Fixes #29563 , despite my protestations. Also fixes #30688 .