M4GNV5 / PointerScript

Scripting language with pointers and native library access.
European Union Public License 1.2
29 stars 4 forks source link

Calling realloc with 0 size detected by valgrind #7

Closed mingodad closed 3 months ago

mingodad commented 3 months ago

When trying to test Pointerscript under valgrind I was getting:

valgrind ./ptrs /home/mingo/dev/c/A_programming-languages/PointerScript/examples/fib.ptrs 
==5946== Memcheck, a memory error detector
==5946== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==5946== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==5946== Command: ./ptrs /home/mingo/dev/c/A_programming-languages/PointerScript/examples/fib.ptrs
==5946== 
==5946== realloc() with size 0
==5946==    at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==5946==    by 0x19AEE4: detach_edge_dst (jit-block.c:271)
==5946==    by 0x19BC04: eliminate_block (jit-block.c:635)
==5946==    by 0x19BC04: eliminate_unreachable (jit-block.c:685)
==5946==    by 0x19BC04: _jit_block_clean_cfg (jit-block.c:876)
==5946==    by 0x14D7C3: optimize.part.0 (jit-compile.c:89)
==5946==    by 0x14DB17: optimize (jit-compile.c:70)
==5946==    by 0x14DB17: compile (jit-compile.c:852)
==5946==    by 0x14E3FD: jit_compile.part.0 (jit-compile.c:962)
==5946==    by 0x14E594: jit_compile (jit-compile.c:1074)
==5946==    by 0x14E594: jit_function_compile (jit-compile.c:1075)
==5946==    by 0x13E057: ptrs_jit_buildFunction (call.c:817)
==5946==    by 0x13244E: ptrs_handle_function (statements.c:615)
==5946==    by 0x131258: ptrs_handle_body (statements.c:51)
==5946==    by 0x13E195: ptrs_compile (run.c:48)
==5946==    by 0x13E348: ptrs_compilefile (run.c:78)
==5946==  Address 0x5a01d50 is 0 bytes inside a block of size 8 alloc'd
==5946==    at 0x4C37F23: calloc (vg_replace_malloc.c:1554)
==5946==    by 0x19B391: alloc_edges (jit-block.c:203)
==5946==    by 0x19B391: _jit_block_build_cfg (jit-block.c:784)
==5946==    by 0x14D7BB: optimize.part.0 (jit-compile.c:86)
==5946==    by 0x14DB17: optimize (jit-compile.c:70)
==5946==    by 0x14DB17: compile (jit-compile.c:852)
==5946==    by 0x14E3FD: jit_compile.part.0 (jit-compile.c:962)
==5946==    by 0x14E594: jit_compile (jit-compile.c:1074)
==5946==    by 0x14E594: jit_function_compile (jit-compile.c:1075)
==5946==    by 0x13E057: ptrs_jit_buildFunction (call.c:817)
==5946==    by 0x13244E: ptrs_handle_function (statements.c:615)
==5946==    by 0x131258: ptrs_handle_body (statements.c:51)
==5946==    by 0x13E195: ptrs_compile (run.c:48)
==5946==    by 0x13E348: ptrs_compilefile (run.c:78)
==5946==    by 0x12A86A: main (main.c:161)
==5946== 
Error:
  unknown error code 14

Memcheck: the 'impossible' happened:
   unknown error code in mc_eq_Error

host stacktrace:
==5946==    at 0x5804771A: show_sched_status_wrk (m_libcassert.c:406)
==5946==    by 0x58047837: report_and_quit (m_libcassert.c:477)
==5946==    by 0x58047AEC: panic (m_libcassert.c:553)
==5946==    by 0x58047AEC: vgPlain_tool_panic (m_libcassert.c:568)
==5946==    by 0x5803D518: vgMemCheck_eq_Error (mc_errors.c:1067)
==5946==    by 0x580425BF: eq_Error (m_errormgr.c:307)
==5946==    by 0x580425BF: vgPlain_maybe_record_error (m_errormgr.c:765)
==5946==    by 0x5803CF80: vgMemCheck_record_realloc_size_zero (mc_errors.c:896)
==5946==    by 0x58005E8A: vgMemCheck_realloc (mc_malloc_wrappers.c:583)
==5946==    by 0x580AC5EA: do_client_request (scheduler.c:1987)
==5946==    by 0x580AC5EA: vgPlain_scheduler (scheduler.c:1542)
==5946==    by 0x580F62A5: thread_wrapper (syswrap-linux.c:102)
==5946==    by 0x580F62A5: run_a_thread_NORETURN (syswrap-linux.c:155)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 5946)
==5946==    at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==5946==    by 0x19AEE4: detach_edge_dst (jit-block.c:271)
==5946==    by 0x19BC04: eliminate_block (jit-block.c:635)
==5946==    by 0x19BC04: eliminate_unreachable (jit-block.c:685)
==5946==    by 0x19BC04: _jit_block_clean_cfg (jit-block.c:876)
==5946==    by 0x14D7C3: optimize.part.0 (jit-compile.c:89)
==5946==    by 0x14DB17: optimize (jit-compile.c:70)
==5946==    by 0x14DB17: compile (jit-compile.c:852)
==5946==    by 0x14E3FD: jit_compile.part.0 (jit-compile.c:962)
==5946==    by 0x14E594: jit_compile (jit-compile.c:1074)
==5946==    by 0x14E594: jit_function_compile (jit-compile.c:1075)
==5946==    by 0x13E057: ptrs_jit_buildFunction (call.c:817)
==5946==    by 0x13244E: ptrs_handle_function (statements.c:615)
==5946==    by 0x131258: ptrs_handle_body (statements.c:51)
==5946==    by 0x13E195: ptrs_compile (run.c:48)
==5946==    by 0x13E348: ptrs_compilefile (run.c:78)
==5946==    by 0x12A86A: main (main.c:161)
client stack range: [0x1FFEFFD000 0x1FFF000FFF] client SP: 0x1FFEFFDE80
valgrind stack range: [0x1002DB2000 0x1002EB1FFF] top usage: 11216 of 1048576

Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

Making the changes shown bellow allow me to run Poinerscript under valgrind:

diff --git a/jit/jit-block.c b/jit/jit-block.c
index c0cfc8f..eb62cbf 100644
--- a/jit/jit-block.c
+++ b/jit/jit-block.c
@@ -260,6 +260,7 @@ detach_edge_dst(_jit_edge_t edge)
 {
    jit_block_t block;
    int index;
+   size_t rsize;

    block = edge->dst;
    for(index = 0; index < block->num_preds; index++)
@@ -268,8 +269,9 @@ detach_edge_dst(_jit_edge_t edge)
        {
            --block->num_preds;
            block->preds[index] = block->preds[block->num_preds];
-           block->preds = jit_realloc(block->preds,
-               block->num_preds * sizeof(_jit_edge_t));
+           rsize = block->num_preds * sizeof(_jit_edge_t);
+           if(rsize == 0) {free(block->preds); block->preds = NULL;}
+           else block->preds = jit_realloc(block->preds, rsize);
            return;
        }
    }
M4GNV5 commented 3 months ago

Very good find. This seems to be an issue with libjit when optimizing the control flow of a function.

I will close this issue here, but it is definitly a good idea to merge your changes into my libjit fork as well as upstream libjit. While according to git blame this code seems to be modified by myself, it does seem to exist in upstream libjit.

AFAIK Aleksey accepts PRs on his github mirror and then pushes them to GNU savannah. Do you want to create a PR there, making you an official GNU libjit contributor?

mingodad commented 3 months ago

Thank you for reply ! I've looked at https://github.com/ademakov/libjit/blob/604d64b0b86ef77103e93bfa1001d166d82e633c/jit/jit-block.c#L236-L255 and your https://github.com/M4GNV5/libjit/blob/6074a2e20cbc667ed292ff82ed3600371f1081d4/jit/jit-block.c#L259-L276 and they differ a bit and I'm not sure if the same problem would happen in the origin.

mingodad commented 3 months ago

I've just cloned and built https://github.com/ademakov/libjit and executed dpas under valgrind and didn't got any warning/error.

mingodad commented 3 months ago

But when I replace your code with the original one and rebuild I still get the same error/warning with valgrind.