-
-
Notifications
You must be signed in to change notification settings - Fork 415
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
Format function SegFaulting at Runtime when negative width string is specified #2013
Comments
Possibly relevant comments from the 2017-JULY-07 IRC follow: [15:20] <@jemc> the cause is that |
I've confirmed this on 0.14.0-8781b65. $ ponyc --version |
This is the key part for addressing the segault.
|
The segfault is happening within the while loop here What's happening is that the Changing the code to this: while pre > 0 do
Debug.out(pre)
s.append(fills)
pre = pre - 1
end ...results in this:
I'm not sure what the proper response to a negative width should be though 🛩 🍐 |
@charlesetc - as you've noted I think the only consistent thing we can do is to assume that they really did mean |
Interesting - so is the segfault here from allocating too much memory? |
@charlesetc According to @Praetonus' comment above, the issue is that the string is allocating an extra byte for the null terminator, leading it to allocate not The allocation logic needs to be special-cased to not add |
Gotcha - does the segfault in the while loop that I'm seeing go along with that? |
This certainly is a good solution for this particular edge case, but I think we need to discuss on a way to handle the general issue of "overflowing" collections, i.e. what should happen when one tries to add more elements to a collection than logically possible. Since these are very uncommon edge cases, one possible way to handle the issue could be to take the "performance over safety" route and not handle it at all, similar to how we're currently not handling memory exhaustion. This would also raise the issue of whether @charlesetc Yes. It's segfaulting because the |
Minimal reproduction: actor Main
new create(env:Env) =>
let s = recover String end
s.reserve(-1)
// s.reserve(1_000_000_000) also works fine
var n: USize = 129 // 128 is fine, 129 results in SEGFAULT
while n > 0 do
s.append(" ")
n = n - 1
end
DoNotOptimise[String tag](s)
DoNotOptimise.observe() Output:
|
The issue is not in However, the fix shown below reveals a bigger issue here which is that On my system --- a/src/libponyrt/mem/heap.c
+++ b/src/libponyrt/mem/heap.c
@@ -416,6 +416,8 @@ void* ponyint_heap_alloc_small_final(pony_actor_t* actor, heap_t* heap,
void* ponyint_heap_alloc_large(pony_actor_t* actor, heap_t* heap, size_t size)
{
size = ponyint_pool_adjust_size(size);
+ if(size == 0)
+ size = (size_t) - 1;
chunk_t* chunk = (chunk_t*) POOL_ALLOC(chunk_t);
chunk->actor = actor;
diff --git a/src/libponyrt/mem/pool.c b/src/libponyrt/mem/pool.c
index c89b743a5..2f2436782 100644
--- a/src/libponyrt/mem/pool.c
+++ b/src/libponyrt/mem/pool.c
@@ -914,6 +914,8 @@ void* ponyint_pool_alloc_size(size_t size)
return ponyint_pool_alloc(index);
size = ponyint_pool_adjust_size(size);
+ if(size == 0)
+ size = (size_t) - 1;
void* p = pool_alloc_size(size);
return p; |
Thanks to @malte for identifying the root cause of ponylang#2013. This PR fixes things so that if there's a request for a `size_t` sized allocation, it actually tries to allocate it instead of pretending that it allocated it while not actually allocating anything which results in memory clobbering and segfaults. resolves ponylang#2013
Thanks to @malte for identifying the root cause of #2013. This PR fixes things so that if there's a request for a `size_t` sized allocation, it actually tries to allocate it instead of pretending that it allocated it while not actually allocating anything which results in memory clobbering and segfaults. resolves #2013
While attempting to use the Format package on a U128, I managed to create a run-time segfault, by accidentally passing in a negative width value. I was using position-based arguments when this occurred, but it also occurs with named arguments, as shown below.
Building builtin -> /usr/local/Cellar/ponyc/0.14.0/packages/builtin
Building . -> /Users/thomasjohnson/Projects/pony/FormatStringSizeCrash
Building format -> /usr/local/Cellar/ponyc/0.14.0/packages/format
Building collections -> /usr/local/Cellar/ponyc/0.14.0/packages/collections
Building ponytest -> /usr/local/Cellar/ponyc/0.14.0/packages/ponytest
Building time -> /usr/local/Cellar/ponyc/0.14.0/packages/time
Generating
Reachability
Selector painting
Data prototypes
Data types
Function prototypes
Functions
Descriptors
Optimising
Writing ./FormatStringSizeCrash.o
Linking ./FormatStringSizeCrash
Regular output. n=42
00000000000000101010
Before runtime fault. Segment fault 11 on Mac OS X.
/bin/bash: line 1: 31076 Segmentation fault: 11 ./FormatStringSizeCrash
[Finished in 4.0s with exit code 139]
[shell_cmd: ponyc && ./FormatStringSizeCrash]
I've confirmed this issue on both Mac OSX and on the Pony Playground.
0.14.0 [release]
compiled with: llvm 3.9.1 -- Apple LLVM version 8.1.0 (clang-802.0.42)
0.14.0 [release]
compiled with: llvm 3.9.1 -- cc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
The text was updated successfully, but these errors were encountered: