ts2c icon indicating copy to clipboard operation
ts2c copied to clipboard

Memory allocation bug

Open jarble opened this issue 3 years ago • 6 comments

When I compile this JavaScript program to C, it prints 0 instead of 1. This appears to be due to a memory allocation bug, where the obj variable is freed before returning from the function:

function return_from_obj(){
  let obj = {key:1};
  return obj.key;
}

console.log(return_from_obj());

This is the compiler's output:

#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
typedef short int16_t;

struct obj_t {
    int16_t key;
};

int16_t return_from_obj()
{
    struct obj_t * obj;
    obj = malloc(sizeof(*obj));
    assert(obj != NULL);
    obj->key = 1;
    free(obj);
    return obj->key;

}

int main(void) {
    printf("%d\n", return_from_obj());

    return 0;
}

It might be possible to solve this problem using a garbage collector (like the Boehm garbage collector or tgc).

jarble avatar Oct 03 '20 17:10 jarble

/cc me I am working on a fix for this. How should the test for this be called? I have it be 'regression1' right now, but perhaps it should be something else.

pitust avatar Nov 27 '20 14:11 pitust

Just for information, this is the valgrind report before the patch:

$ valgrind -s ./x
==671532== Memcheck, a memory error detector
==671532== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==671532== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==671532== Command: ./x
==671532== 
==671532== Invalid read of size 2
==671532==    at 0x1091BE: return_from_obj (in /home/pitust/code/pwg/x)
==671532==    by 0x1091D0: main (in /home/pitust/code/pwg/x)
==671532==  Address 0x4a6d040 is 0 bytes inside a block of size 2 free'd
==671532==    at 0x483B9AB: free (vg_replace_malloc.c:538)
==671532==    by 0x1091B9: return_from_obj (in /home/pitust/code/pwg/x)
==671532==    by 0x1091D0: main (in /home/pitust/code/pwg/x)
==671532==  Block was alloc'd at
==671532==    at 0x483A77F: malloc (vg_replace_malloc.c:307)
==671532==    by 0x10917A: return_from_obj (in /home/pitust/code/pwg/x)
==671532==    by 0x1091D0: main (in /home/pitust/code/pwg/x)
==671532== 
1
==671532== 
==671532== HEAP SUMMARY:
==671532==     in use at exit: 0 bytes in 0 blocks
==671532==   total heap usage: 2 allocs, 2 frees, 1,026 bytes allocated
==671532== 
==671532== All heap blocks were freed -- no leaks are possible
==671532== 
==671532== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==671532== 
==671532== 1 errors in context 1 of 1:
==671532== Invalid read of size 2
==671532==    at 0x1091BE: return_from_obj (in /home/pitust/code/pwg/x)
==671532==    by 0x1091D0: main (in /home/pitust/code/pwg/x)
==671532==  Address 0x4a6d040 is 0 bytes inside a block of size 2 free'd
==671532==    at 0x483B9AB: free (vg_replace_malloc.c:538)
==671532==    by 0x1091B9: return_from_obj (in /home/pitust/code/pwg/x)
==671532==    by 0x1091D0: main (in /home/pitust/code/pwg/x)
==671532==  Block was alloc'd at
==671532==    at 0x483A77F: malloc (vg_replace_malloc.c:307)
==671532==    by 0x10917A: return_from_obj (in /home/pitust/code/pwg/x)
==671532==    by 0x1091D0: main (in /home/pitust/code/pwg/x)
==671532== 
==671532== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

pitust avatar Nov 27 '20 15:11 pitust

^ I submitted a PR to fix this

pitust avatar Nov 27 '20 15:11 pitust

@pitust I tried compiling the program again here, but the output hasn't changed. It still has the same bug.

jarble avatar Jul 13 '21 01:07 jarble

Yeah, the PR is still open.

pitust avatar Jul 15 '21 16:07 pitust

As far I understand, the compiler is capable to detect the object is not used outside the current scope (i.e. the function) and perform the free before exiting (thus not using the "GC" mechanism). In this case, I think would be better to just allocate the object in the stack instead of using heap memory.

brunexgeek avatar Oct 19 '21 03:10 brunexgeek