Skip to content

Complex case leads to free before allocation #997

Open
@scolsen

Description

@scolsen

I've run into a case where a String is freed before it's actually used, here's the code:

(defn binary-partial [f x]
      (fn [y]
        (f x y)))
(doc lift-binary
  "Lifts a binary function into an applicative structure.")
    (defn lift-binary [f cx cy]
      (sequence (fmap &(binary-partial binary-partial f) cx) cy))

(deftype (Box a) [of a])

(defmodule Box
  (implements fmap fmap)
  (defn fmap [f b]
    (let [val (~f @(Box.of &b))]
    (Box.init val)))

  (implements fmap! fmap!)
  (defn fmap! [f b]
    (let [val (~f @(Box.of b))]
    (Box.set-of! b val)))

  (implements lift Box.init)

  (implements sequence seq)
  (defn seq [box-f box]
    (let [f @(Box.of &box-f)
          v @(Box.of &box)]
      (Box.init (f v))))

  (implements sequence! seq!)
  (defn seq! [box-f box]
    (let [f @(Box.of box-f)
          v @(Box.of box)]
      (Box.set-of! box (f v))))

)

Loading up this code and then running:

鲤 (defn foo [] (Applicative.lift-binary (fn [x y] (String.append &x &y)) (Box.init @"foo") (Box.init @"bar")))
鲤 (foo)
Compiled to 'out/Untitled' (executable)
Untitled(3776,0x10c0a7dc0) malloc: *** error for object 0x7fc502c05830: pointer being freed was not allocated
Untitled(3776,0x10c0a7dc0) malloc: *** set a breakpoint in malloc_error_break to debug
[RUNTIME ERROR] '"out/Untitled"' exited with return value -6.

It emits a free before allocation here:

void FP__Lambda_binary_MINUS_partial__String_String_String_12_env_delete(FP__Lambda_binary_MINUS_partial__String_String_String_12_env* p) {
    Function_delete__String_String_String(p->f);
    String_delete(p->x);
}

commenting out String_delete(p->x); makes it run fine:

./foo
(Box @"foobar")

I thought this might have to do with capturing vars, but it perhaps doesn't since this works fine:

鲤 (defn foo [] (Applicative.lift-binary (fn [x y] (+ x y)) (Box.init 1) (Box.init 2)))
鲤 (foo)
Compiled to 'out/Untitled' (executable)
(Box 3)
=> 0

Seems specifically related to Strings or String.appendas well, not references in general:

鲤 (defn foo [] (Applicative.lift-binary (fn [x y] (add-ref &x &y)) (Box.init 1) (Box.init 2)))
鲤 (foo)
Compiled to 'out/Untitled' (executable)
(Box 3)
=> 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions