Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
libc/test/integration/loader/linux/cxx_globals_test.cpp | ||
---|---|---|
17 | __cxa_atexit is a alternative for the .fini_array, it doesn't use it | |
24 | The compiler has no requirement that this constructor be placed in the .init_array. It seems the better way to test this would be to either use __attribute__(({destructor,constructor})) on a function or __attribute__((section(secname))) on a function pointer to explicitly put things in {preinit,init,fini}_array sections. The later being the only way I would know how to get something in .preinit_array |
Address comments.
libc/test/integration/loader/linux/cxx_globals_test.cpp | ||
---|---|---|
17 | I am not sure I understand this comment. My intention here was to say we cannot yet have a non-trivial destructor as it will lead to a call to __cxa_atexit which we do not yet have. | |
24 | All good ideas so I have incorporated them. When you said that the "compiler has no requirement that this constructor be placed in the .init_array", I suppose you mean that the object initialization can be inlined, eliminating the need for an explicit constructor call (may be at -O3)? I have expanded the constructor a little bit to reduce the chance for such a possibility. Also, when we include a non-trivial destructor, an .init_array entry will be added anyway so I have left the test below as is. |
If libc would support Lit tests, then you could:
- compile the test binary exactly as you like it
- inspect the binary with llvm-objdump
- run the binary and observe the execution as you see fit
it would give you higher confidence than forcing loader tests into unit tests.
In general, we are taking small steps (sometimes incomplete) to understand the various infrastructure needs. May be one day we will start using lit-tests. But, unit tests are still very nice :)
Got these comments in a little late, oops
libc/loader/linux/x86_64/start.cpp | ||
---|---|---|
93 | It's not clear to me why these take argc, argv and env. .init_array functions wouldn't take these because in the general they would only be meaningful when loading an executable and not a shared object. I suppose it isn't harmful to pass arguments to a function which doesn't take them, though it seems surprising given likely no constructor functions in the wild take these. | |
118 | These should happen in reverse order. | |
libc/test/integration/loader/linux/cxx_globals_test.cpp | ||
17 | I see sorry, I thought it was specific to .fini_array | |
libc/test/integration/loader/linux/init_fini_array_test.cpp | ||
39 ↗ | (On Diff #449395) | If the integration tests check that the process exited normally you could return 1 from main and _Exit(0) here to ensure this is called. Additionally it might make sense to specify a priority to destructor and constructor, like destructor(num) to ensure they are called in the right order. |
libc/loader/linux/x86_64/start.cpp | ||
---|---|---|
93 | Neither do I know of any practical examples. Most libcs do not pass any args to the init functions. However, this patch matches glibc behavior. $ cat init.cpp #include <stdio.h> __attribute__((constructor)) void initfunc(int argc, char **argv, char **envp) { printf("argc: %d\n", argc); for (int i = 0; i < argc; ++i) { printf("\targ[%d] = %s\n", i, argv[i]); } } int main() { return 0; } $ clang++ init.cpp $ ./a.out argc: 1 arg[0] = ./a.out $ ./a.out abc def ghi argc: 4 arg[0] = ./a.out arg[1] = abc arg[2] = def arg[3] = ghi | |
118 | Oops, yes! I will fix it in the next pass. I am working on the __cxa_atexit hook up anyway so will fix it in that pass. | |
libc/test/integration/loader/linux/init_fini_array_test.cpp | ||
39 ↗ | (On Diff #449395) | OK - I will add more tests with destructor priority which I think would be better than what we have. Priorities + the _Exit(0) idea together will make it a complete test I think. |
It's not clear to me why these take argc, argv and env. .init_array functions wouldn't take these because in the general they would only be meaningful when loading an executable and not a shared object. I suppose it isn't harmful to pass arguments to a function which doesn't take them, though it seems surprising given likely no constructor functions in the wild take these.