mkirchner / gc Goto Github PK
View Code? Open in Web Editor NEWSimple, zero-dependency garbage collection for C
License: MIT License
Simple, zero-dependency garbage collection for C
License: MIT License
I was trying valgrind test for stress, but we seem to leak for hello world case in readme. Here is a test file:
int main(int argc, char* argv[]) {
// gc_start(&gc, __builtin_frame_address(0));
gc_start(&gc, &argc);
// stress(1024);
int* my_array = gc_calloc(&gc, 1024, sizeof(int));
for (size_t i=0; i<1024; ++i) {
my_array[i] = 42;
}
gc_stop(&gc);
return 0;
}
gcc results:
┌─[root@kubemaster] - [~/gc/test] - [Sat Dec 28, 13:58]
└─[$] <git:(master*)> valgrind ./stress --leak-check=full --track-origins=yes
==101443== Memcheck, a memory error detector
==101443== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==101443== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==101443== Command: ./stress --leak-check=full --track-origins=yes
==101443==
==101443== Use of uninitialised value of size 8
==101443== at 0x109032: gc_allocation_map_get (in /root/gc/test/stress)
==101443== by 0x10993E: gc_mark_alloc (in /root/gc/test/stress)
==101443== by 0x1099EE: gc_mark_stack (in /root/gc/test/stress)
==101443== by 0x109B01: gc_mark (in /root/gc/test/stress)
==101443== by 0x109CE4: gc_stop (in /root/gc/test/stress)
==101443== by 0x109E0B: main (in /root/gc/test/stress)
==101443==
==101443==
==101443== HEAP SUMMARY:
==101443== in use at exit: 0 bytes in 0 blocks
==101443== total heap usage: 4 allocs, 4 frees, 12,448 bytes allocated
==101443==
==101443== All heap blocks were freed -- no leaks are possible
==101443==
==101443== For counts of detected and suppressed errors, rerun with: -v
==101443== Use --track-origins=yes to see where uninitialised values come from
==101443== ERROR SUMMARY: 79 errors from 1 contexts (suppressed: 0 from 0)
Clang result:
┌─[root@kubemaster] - [~/gc/test] - [Sat Dec 28, 13:59]
└─[$] <git:(master*)> valgrind ./stress --leak-check=full --track-origins=yes
==102022== Memcheck, a memory error detector
==102022== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==102022== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==102022== Command: ./stress --leak-check=full --track-origins=yes
==102022==
==102022== Use of uninitialised value of size 8
==102022== at 0x400C54: gc_allocation_map_get (in /root/gc/test/stress)
==102022== by 0x40132F: gc_mark_alloc (in /root/gc/test/stress)
==102022== by 0x401419: gc_mark_stack (in /root/gc/test/stress)
==102022== by 0x401558: gc_mark (in /root/gc/test/stress)
==102022== by 0x40184D: gc_stop (in /root/gc/test/stress)
==102022== by 0x401A82: main (in /root/gc/test/stress)
==102022==
==102022== Invalid read of size 8
==102022== at 0x4013AB: gc_mark_alloc (in /root/gc/test/stress)
==102022== by 0x401419: gc_mark_stack (in /root/gc/test/stress)
==102022== by 0x401558: gc_mark (in /root/gc/test/stress)
==102022== by 0x40184D: gc_stop (in /root/gc/test/stress)
==102022== by 0x401A82: main (in /root/gc/test/stress)
==102022== Address 0x5230139 is 4,089 bytes inside a block of size 4,096 alloc'd
==102022== at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==102022== by 0x401AD9: gc_mcalloc (in /root/gc/test/stress)
==102022== by 0x4008F4: gc_allocate (in /root/gc/test/stress)
==102022== by 0x400AEC: gc_calloc_ext (in /root/gc/test/stress)
==102022== by 0x400AB8: gc_calloc (in /root/gc/test/stress)
==102022== by 0x401A39: main (in /root/gc/test/stress)
==102022==
==102022== HEAP SUMMARY:
==102022== in use at exit: 4,096 bytes in 1 blocks
==102022== total heap usage: 4 allocs, 3 frees, 12,448 bytes allocated
==102022==
==102022== LEAK SUMMARY:
==102022== definitely lost: 4,096 bytes in 1 blocks
==102022== indirectly lost: 0 bytes in 0 blocks
==102022== possibly lost: 0 bytes in 0 blocks
==102022== still reachable: 0 bytes in 0 blocks
==102022== suppressed: 0 bytes in 0 blocks
==102022== Rerun with --leak-check=full to see details of leaked memory
==102022==
==102022== For counts of detected and suppressed errors, rerun with: -v
==102022== Use --track-origins=yes to see where uninitialised values come from
==102022== ERROR SUMMARY: 71 errors from 2 contexts (suppressed: 0 from 0)
Hey @mkirchner, is there a provision like Travis where we can run the CI for all PRs, it's easy to see if we are breaking anything.
Originally posted by @ganesh-k13 in #33 (comment)
We can see that tests are triggered for your PRs like # 43, but in cases such as mine or ssrlive's, it does not.
Am I not creating a PR in a proper fashion, or are we missing something? Sorry if this is a basic question as I am new to github workflows
I change the main
function like this:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define MEM_CHECK_BEGIN() do { _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); } while(0)
#define MEM_CHECK_DUMP_LEAKS() do { _CrtDumpMemoryLeaks(); } while(0)
int main()
{
char *result;
MEM_CHECK_BEGIN();
result = test_suite();
if (result) {
printf("%s\n", result);
} else {
printf("ALL TESTS PASSED\n");
}
printf("Tests run: %d\n", tests_run);
MEM_CHECK_DUMP_LEAKS();
return result != 0;
}
and the debugger report memory leaking.
Hello,
---=[ GC tests
Unreferenced allocs should not be marked
Tests run: 6
1>U:\GarbageCollection\DebugTest\gc.c(170,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 5 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(170,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(170,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 6 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(170,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(177,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 5 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(177,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(177,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 6 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(177,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(207,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 5 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(207,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(207,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 6 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(207,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(207,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 7 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(207,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(224,32): warning C4244: '=': conversion from 'double' to 'size_t', possible loss of data
1>U:\GarbageCollection\DebugTest\gc.c(264,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 5 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(264,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(281,13): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 5 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(281,13): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(293,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 5 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(293,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(354,9): warning C4477: 'fprintf' : format string '%lu' requires an argument of type 'unsigned long', but variadic argument 5 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(354,9): message : consider using '%zu' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(491,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 5 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(491,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(491,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 6 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(491,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(513,9): warning C4477: 'fprintf' : format string '%lu' requires an argument of type 'unsigned long', but variadic argument 6 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(513,9): message : consider using '%zu' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(517,13): warning C4477: 'fprintf' : format string '%lu' requires an argument of type 'unsigned long', but variadic argument 6 has type '__int64'
1>U:\GarbageCollection\DebugTest\gc.c(517,13): message : consider using '%llu' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(517,13): message : consider using '%Iu' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(517,13): message : consider using '%I64u' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(526,5): warning C4477: 'fprintf' : format string '%ld' requires an argument of type 'long', but variadic argument 6 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(526,5): message : consider using '%zd' in the format string
1>U:\GarbageCollection\DebugTest\gc.c(580,17): warning C4477: 'fprintf' : format string '%lu' requires an argument of type 'unsigned long', but variadic argument 6 has type 'size_t'
1>U:\GarbageCollection\DebugTest\gc.c(580,17): message : consider using '%zu' in the format string
1>Generating Code...
1>DebugTest.vcxproj -> U:\GarbageCollection\x64\Debug\GarbageCollection.exe
1>Done building project "DebugTest.vcxproj".
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
The coverage report shows a set of untested functions; fix that.
Hi, I noticed make
failed if clang is not present, can we add a check like this:
CHECK := $(shell which clang)
ifeq ($(CHECK),)
$(warning no clang found, consider apt-get install clang, using gcc now)
CC = gcc
else
$(info using clang over gcc)
CC = clang
endif
How to Stop-The-World with this lib?
I have researched it again. I think I have find out the solve under windows. see below image.
We can use the _AddressOfReturnAddress
as the bos
, and use CONTEXT.Esp
as the top of stack
.
since GetThreadContext
always return a lower CONTEXT.Esp
value than ESP
.
we can use CONTEXT.Esp
as a beginning of searching memory and ending with the value of _AddressOfReturnAddress
.
__declspec(noinline)
void func() {
void* pvAddressOfReturnAddress = _AddressOfReturnAddress();
uintptr_t *bos=(uintptr_t*)(&bos);
CONTEXT *ctx = (CONTEXT *)calloc(1, sizeof(*ctx));
ctx->ContextFlags = CONTEXT_ALL;
GetThreadContext(GetCurrentThread(), ctx);
printf_s("RSP %p\n", ctx->Rsp);
printf_s("RBP %p\n", ctx->Rbp);
printf_s("%p\n", pvAddressOfReturnAddress);
printf_s("%p\n", *((void**)pvAddressOfReturnAddress));
printf_s("%p\n", _ReturnAddress());
free(ctx);
}
Originally posted by @ssrlive in #17 (comment)
test it on Windows / Linux / macOS, all the Release buildings are failed.
ssrlive@ss:~/Desktop/gc/build$ cat ../CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(gc C)
set(CMAKE_C_STANDARD 11)
include_directories(src)
include_directories(test)
add_executable(gc
src/gc.h
src/log.c
src/log.h
test/minunit.h
test/test_gc.c)
ssrlive@ss:~/Desktop/gc/build$ cmake .. -DCMAKE_BUILD_TYPE=Release
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ssrlive/Desktop/gc/build
ssrlive@ss:~/Desktop/gc/build$ make
[100%] Built target gc
ssrlive@ss:~/Desktop/gc/build$ ./gc
---=[ GC tests
Heap allocation referenced from stack should be tagged
Tests run: 5
Having compiled this GC using Visual Studio (CMake, clang-cl-x64), the tests fail:
---=[ GC tests
Unexpected number of collected bytes in strdup
Tests run: 12
However, if the log
function is changed to use printf
instead of fprintf
. and the log level is raised to LOGLEVEL_DEBUG
, tests pass. I don't know what kind of magic this is, but... it is what it is.
When I run the test multiple times, TC 11 fails sometimes: https://gist.github.com/ganesh-k13/62d7745e94df42d579dc05faf05db6f3
system info:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
We don't have any tests for gc_realloc()
in test_gc.c
yet, those would be great to have.
As the issue title said, Can I have below code?
int main(int argc, char* argv[]) {
gc = gc_start(gc, &argc);
...
gc_calloc();
...
ptr = malloc();
free(ptr);
...
gc_stop(gc);
return 0;
}
hi @mkirchner , this post has nothing to do with the topic.
I think we can ignore other valgrind warnings under macOS platform, because it issues the same warnings to any legitimate c program.
Originally posted by @ssrlive in #44 (comment)
Forking the MSVC discussion from the GCC discussion here.
Since I don't have a windows/MSVC setup there is no "official" MSVC support; I added a "help required" badge to highlight that -- contributions are very welcome!
Hi, as discussed previously, I wanted to see if gcc
works. But I was getting this error and a few warnings:
mkdir -p ../build/test/../src
gcc -g -Wall -Wextra -pedantic -I../include -fprofile-arcs -ftest-coverage -MMD -c ../src/log.c -o ../build/tes
t/../src/log.o
mkdir -p ../build/test
gcc -g -L../build/src -L../build/test --coverage ../build/test/test_gc.o ../build/test/../src/log.o -o ../buil
d/test/test_gc
make[1]: Leaving directory '/root/gc/test'
./build/test/test_gc
---=[ GC tests
Heap allocation referenced from stack should be tagged
Tests run: 5
profiling:/root/gc/test/../build/test/test_gc.gcda:Version mismatch - expected A74* got 402*
Makefile:10: recipe for target 'test' failed
make: *** [test] Error 1
I was hoping I can look into this if it is an actual issue and not some local system problem with some dependencies.
Hi,
I'm novice on C. First of all, sorry if the question might look basic, but I'm confused with an error message trying to link LLVM IR code with gc.
Here is the context:
llc -filetype=obj compile.ll
clang compile.o gc/build/src/log.o -o compile
Undefined symbols for architecture arm64:
"_gc", referenced from:
_main in compile.o
_main in compile.o
_.main in compile.o
"_gc_malloc", referenced from:
_.main in compile.o
_.main in compile.o
_.main in compile.o
_.main in compile.o
_.main in compile.o
_.main in compile.o
_.main in compile.o
...
"_gc_start", referenced from:
_main in compile.o
"_gc_stop", referenced from:
_main in compile.o
"_llvm_gcda_emit_arcs", referenced from:
___llvm_gcov_writeout in log.o
"_llvm_gcda_emit_function", referenced from:
___llvm_gcov_writeout in log.o
"_llvm_gcda_end_file", referenced from:
___llvm_gcov_writeout in log.o
"_llvm_gcda_start_file", referenced from:
___llvm_gcov_writeout in log.o
"_llvm_gcda_summary_info", referenced from:
___llvm_gcov_writeout in log.o
"_llvm_gcov_init", referenced from:
___llvm_gcov_init in log.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I'm a missing a gc.o file or is there something else I'm missing?
I have a project to build a compiler for the BASIC (uBasic on GitHub) language that will be compile to run on Web Assembly using the LLVM tool chain. Do you think your library can be use in this architecture?
I find that we can find out the heaps beginning address and size of a process.
In windows, it can from this sample. It can retrive all the heap's start addresses in the memory.
In unix, it's seams that we can from sbrk(0)
. see this article
depends this information, in gc_mark_alloc
function, we can judge the pointer value if a real heap pointer or not.
This can speeds up scanning. Or avoid a lot of complaints from valgrind.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.