Skip to content
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

Memory management in nested lambdas is not working properly #1416

Open
TimDeve opened this issue Apr 12, 2022 · 1 comment
Open

Memory management in nested lambdas is not working properly #1416

TimDeve opened this issue Apr 12, 2022 · 1 comment

Comments

@TimDeve
Copy link
Contributor

TimDeve commented Apr 12, 2022

Allocating inside a lambda an using the value in a nested lambda results in double free:

(Debug.sanitize-addresses)

(defn main []
  ((fn []
    (let [s @"Ok"]
      ((fn [] (println* s)))))))
Ok
=================================================================
==10746==ERROR: AddressSanitizer: attempting double-free on 0x602000000010 in thread T0:
    #0 0x4c0a47 in free (/home/tim/dev/sandbox/match/out/Untitled+0x4c0a47)
    #1 0x4fafb4 in String_delete /home/tim/dev/other/Carp/core/carp_string.h:20:5
    #2 0x556109 in _Lambda__Lambda_NAKED_LAMBDA_23_env_20_env_ty_delete /home/tim/dev/sandbox/match/out/main.c:11227:5
    #3 0x53fd4a in Function_delete__void /home/tim/dev/sandbox/match/out/main.c:8050:7
    #4 0x555ea7 in _Lambda_NAKED_LAMBDA_23_env /home/tim/dev/sandbox/match/out/main.c:11208:9
    #5 0x5565b9 in main /home/tim/dev/sandbox/match/out/main.c:11261:61
    #6 0x7fe9aa2abe09 in __libc_start_main /builddir/glibc-2.32/csu/../csu/libc-start.c:314:16
    #7 0x41c739 in _start /builddir/glibc-2.32/csu/../sysdeps/x86_64/start.S:120

0x602000000010 is located 0 bytes inside of 3-byte region [0x602000000010,0x602000000013)
freed by thread T0 here:
    #0 0x4c0a47 in free (/home/tim/dev/sandbox/match/out/Untitled+0x4c0a47)
    #1 0x4fafb4 in String_delete /home/tim/dev/other/Carp/core/carp_string.h:20:5
    #2 0x54e02b in StringCopy_str /home/tim/dev/sandbox/match/out/main.c:10990:5
    #3 0x55600e in _Lambda__Lambda_NAKED_LAMBDA_23_env_20_env /home/tim/dev/sandbox/match/out/main.c:11213:18
    #4 0x555dce in _Lambda_NAKED_LAMBDA_23_env /home/tim/dev/sandbox/match/out/main.c:11207:19
    #5 0x5565b9 in main /home/tim/dev/sandbox/match/out/main.c:11261:61
    #6 0x7fe9aa2abe09 in __libc_start_main /builddir/glibc-2.32/csu/../csu/libc-start.c:314:16

previously allocated by thread T0 here:
    #0 0x4c0d3f in malloc (/home/tim/dev/sandbox/match/out/Untitled+0x4c0d3f)
    #1 0x4fb2ba in String_copy /home/tim/dev/other/Carp/core/carp_string.h:67:18
    #2 0x555c01 in _Lambda_NAKED_LAMBDA_23_env /home/tim/dev/sandbox/match/out/main.c:11196:21
    #3 0x5565b9 in main /home/tim/dev/sandbox/match/out/main.c:11261:61
    #4 0x7fe9aa2abe09 in __libc_start_main /builddir/glibc-2.32/csu/../csu/libc-start.c:314:16

SUMMARY: AddressSanitizer: double-free (/home/tim/dev/sandbox/match/out/Untitled+0x4c0a47) in free
==10746==ABORTING
[RUNTIME ERROR] 'out/Untitled' exited with return value 1.

With Matches

Using match confuses the compiler

(defn main []
  ((fn []
    (let [r (Just @"Ok")]
      (match r
        (Just s) ((fn [] (println* s)))
        _ ())))))

Compiler output:

carp: Too many variables with the same name in set: [(ProperDel String.delete  "s"),(FakeDel "s")]
CallStack (from HasCallStack):
  error, called at src/Memory.hs:512:24 in CarpHask-0.5.4.0-JdeTIwgYM2SBeF4dr02mnA:Memory

While using match-ref results in a badly emitted C source:

(defn main []
  ((fn []
    (let [r (Just @"Ok")]
      (match-ref &r
        (Just s) ((fn [] (println* s)))
        _ ())))))

Output:

out/main.c:11292:18: error: use of undeclared identifier 's'
    _35_env->s = s;
                 ^
1 error generated.
carp: callCommand: clang  -o out/Untitled -I /home/tim/dev/other/Carp/core/  -fPIC -g -std=c99 -D_DEFAULT_SOURCE -Wall -Werror -Wno-unused-variable -Wno-self-assign -lm out/main.c (exit 1): failed
@scolsen
Copy link
Contributor

scolsen commented Apr 12, 2022

copying over some thoughts from chat:

this is similar to issue #597 but what's probably happening here is s gets too different types in the match clause and body, which results in it being assigned two different deleters. We can probably handle this similarly to the way shadows were handled in #597 and use a new state for the body scope that we pop afterwards.

For the double-free issue, the problem is sort of the opposite phenomenon where a variable that should be treated as the same is being treated as distinct. This might be because of the state popping happening in let bindings now, but I'm not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants