-
-
Notifications
You must be signed in to change notification settings - Fork 608
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
Add Valgrind GC integration #15304
Add Valgrind GC integration #15304
Conversation
|
Thanks for your pull request, @CyberShadow! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + dmd#15304" |
|
This relies on the Valgrind API, which is defined in the How we can approach this for the D side:
I'm going to go with option 3 as it seems the most flexible and least troublesome. |
This is not portable, and memcheck complains about this.
Add the BSD-licensed C header files which provide the API for controlling Valgrind from within programs executed under it. The files are from Valgrind v3.21.0.
We will use these in the GC implementation to tell Valgrind which memory operations are OK or not.
Allow the conservative GC to scan memory, whether it has been initialized by the application or not.
9517710
to
8361858
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
druntime/src/etc/valgrind/valgrind.d
Outdated
| void _d_valgrind_make_mem_defined (const(void)* addr, size_t len); | ||
| } | ||
|
|
||
| void makeMemNoAccess (const(void)[] mem) nothrow { _d_valgrind_make_mem_noaccess (mem.ptr, mem.length); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add ddoc comments to public functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Done.
|
Awesome! CC @JohanEngelen does this gives some lights about compiler-rt ASAN being aware of the GC? I think valgrind interfaces are very similar |
ImportC currently replaces instances of GNU asm with I'm interested in any and all problems with ImportC. |
Okay, but that doesn't help us very much because the critical parts are all in inline assembly.
The remaining parts (about 20%) wrap the assembly code to create the public API.
I don't understand what that would mean in this context.
This is what the implementation in this PR does. |
|
I think it would help if I explained how the Valgrind client API works. Valgrind is a binary retranslation tool. You give it a compiled program containing x86_64 etc. instructions, and before running it, Valgrind translates it to a different x86_64 program, with some instrumentation added. As such, it is something akin to both a VM and a JIT. As it is translating the program, it instruments it for additional functionality, depending on the tool used. Among other things, the The client API controls the Valgrind retranslator. When Valgrind encounters these special instructions while translating our program's code, it will understand these as requests to adjust its internal state accordingly (i.e. to pretend that a copy of some value is defined just this once, or mark some memory range as undefined). The header file contains these instructions. Worth pointing out that the instructions are "junk" no-op instructions that don't do anything if the program isn't running under Valgrind, so one thing we could actually do is enable Valgrind for our debug Phobos builds. At the cost of a very small slowdown, that will allow users to just run debug builds of D programs under Valgrind and get correct diagnostics about invalid memory operations. |
c31b0d2
to
ed43197
Compare
The two share the same goal: mark memory which should not be accessed any more.
The GC stores free lists in the cells of the objects on the list. We would like to allow the GC to work with these lists, but still raise a warning if application code attempts to access them.
Freshly allocated memory should be writable but not readable. Explicitly deallocated or GC-ed memory should be neither readable or writable.
Copy/adapt the documentation in memcheck.h.
Run the Druntime Valgrind integration tests. libc6-dbg is needed to allow Valgrind to redirect certain functions.
Although the GC is the primary user, this is not a restriction of these Valgrind API wrappers.
Trick the optimizer to pretend we're doing something with the result of those invalid memory accesses.
Indeed. I have similar unfinished work. |
|
|
||
| ``` | ||
| git clone -b v2.105.0 --depth=1 https://github.com/dlang/dmd | ||
| dmd -g -debug=VALGRIND program.d -Idmd/druntime/src dmd/druntime/src/{core/internal/gc/impl/conservative/gc,rt/lifetime,etc/valgrind/valgrind}.d |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this, and it results in undefined reference to '_d_valgrind_make_mem_noaccess' etc., because it doesn't tell you to cc -c druntime/src/etc/valgrind/valgrind.c -o valgrind.a and include that as a source file. Other than that, works like a charm!
This documentation should not be only in the changelog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The C parts should be compiled into libphobos.a everywhere on Posix. Check that you're using libphobos.a built from master, maybe?
I think valgrind.d could have version (Posix): instead of debug (VALGRIND): at the top to avoid having to recompile it too, but I did not experiment with it too much. There's some issues like the D file pulling in the C declarations even when the D declarations are not used by anything on some platforms...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, the dmd command launches v2.104.0 from my package manager, but when I use dmd built from master, it includes the valgrind symbols.
Agreed. I think we also need a centralized place for us to document the |
Resurrecting some old work from 2015.
Hopefully may help with problems such as https://issues.dlang.org/show_bug.cgi?id=23978.
What this does
This integrates Valgrind (specifically, the
memchecktool) with the D GC. It allows catching bad code such as the following:The integration makes it so that harmless memory operations (such as those done by the GC) don't emit spurious warnings, and invalid memory operations (such as in the example above) do emit warnings.
How to use it
WIP (will add docs)See changelog; the goal is to be able to do essentiallyto get the integration. (I.e., add the GC-related parts of Druntime to the compilation of your program so that it is rebuilt with
-debug=VALGRIND).