These are chat archives for Snaipe/Criterion

23rd
Mar 2017
Jakob Klepp
@truh
Mar 23 2017 18:39

It's me again. Liked criterion so far pretty well. I'm trying to build some tests to make sure my memory management works. Problem is mcheck.h doesn't seem to play well with criterion.

By that I mean mcheck(NULL) returns -1, indicating an error. mprobe calls return MCHECK_DISABLED.

It works normally in my normal (non-test) code.

Do you maybe have an idea what might cause this?

Franklin Mathieu
@Snaipe
Mar 23 2017 18:41
That doesn't ring a bell at the moment, so I don't think I'd know without debugging that
It might be a boxfort-related issue, where the inheritable heap messes up with malloc
but then that should have hit valgrind or address sanitizer on my end
do you have a snippet to reproduce the issue?
Jakob Klepp
@truh
Mar 23 2017 18:44
#include <criterion/criterion.h>
#include <mcheck.h>

Test(mcheck, mcheck) {
    cr_assert_null(mcheck(NULL), "mcheck has to return zero.");
}
Franklin Mathieu
@Snaipe
Mar 23 2017 18:54
I can reproduce it. Not sure if/when I can fix that though. I'd advise you use -fsanitize=address for your consistency checks in the meantime, as the address sanitizer will abort the test when an error occurs
Franklin Mathieu
@Snaipe
Mar 23 2017 19:00
yeah I have no idea what's up. I just linked with -lmcheck to ensure that mcheck() is called before main() during the libc init, and attached with a debugger to see if it hit, and sure enough it does, but still returns -1. I'm not doing anything to the process at this point since boxfort does his thing after the libc init, so I'm pretty stumped.
Franklin Mathieu
@Snaipe
Mar 23 2017 19:05
Ah nevermind, I was debugging the wrong process. with -lmcheck, mcheck still doesn't seem to get called, so I guess this is supposed to happen later on
right, seems that something happens in boxfort because manually calling mcheck at the hijacked main makes everything work again
Franklin Mathieu
@Snaipe
Mar 23 2017 19:11
ah well.
seems to be nanomsg's fault
not sure why though
Ah! nevermind, got it
mcheck probably fails when called after the first malloc()
and nanomsg might be doing plenty of that
Jakob Klepp
@truh
Mar 23 2017 19:15
I tried calling mcheck after malloc before asking here. Maybe a single malloc was not enough to break it though.
Franklin Mathieu
@Snaipe
Mar 23 2017 19:16
Right. Here's a gcc/clang workaround if you need one https://ptpb.pw/ukxr/c
Don't think I'll be able to fix that soundly in criterion because mcheck isn't always there, and I'd prefer it to be opt-in rather than opt-out
I guess a better workaround would be to have that __attribute__((constructor)) in a dedicated shared lib and link the tests with it
It's a shame they're not doing that with libmcheck.a
Jakob Klepp
@truh
Mar 23 2017 19:34
Works great. Thank you.
Jakob Klepp
@truh
Mar 23 2017 19:42
Well ... seems to be more of a works great sometimes but sometimes also it crashes and prints impressive backtraces-situation
Franklin Mathieu
@Snaipe
Mar 23 2017 19:42
That's... not normal. Does the backtrace come from criterion/boxfort/nanomsg?
Jakob Klepp
@truh
Mar 23 2017 19:46
backtrace is like 1:30 chance. Other errors come up as well. It starts with:
munmap_chunk(): invalid pointer: 0x00007f5e1c000940

Other errors include:

================= error 1:
criterion: Could not spawn test instance: Protocol error

Process finished with exit code 6

================= error 2:
memory clobbered before allocated block

Process finished with exit code 6

================= error 3:
Process finished with exit code 11

sometimes it also works.

Franklin Mathieu
@Snaipe
Mar 23 2017 19:48
huh
the protocol error here means that something has gone wrong in the initialization of the process by boxfort
so I guess it's doing something that mcheck doesn't like
again, do you have something to reproduce that (even at a 1:30 chance)?
oh actually nevermind, my example seems do be doing that on my end
Jakob Klepp
@truh
Mar 23 2017 20:01

Compile

gcc -shared -o libmcheck_workaround.so mcheck_workaround.c
gcc -lmcheck_workaround -lcriterion -I$HOME/include -L$PWD -L$HOME/lib test.c

mcheck_workaround.c

#include <stddef.h>
#include <mcheck.h>

__attribute__((constructor))
void init_mcheck(void) {
    mcheck(NULL);
}

test.c

#include <criterion/criterion.h>
#include <mcheck.h>

Test(test, trueistrue) {
    cr_assert(true, "true is true.");
}
That's basically it
Franklin Mathieu
@Snaipe
Mar 23 2017 20:03
Thanks. Could you maybe open an issue on the github repo with the code above, so I can remember to debug that when I have a bit more time?
Jakob Klepp
@truh
Mar 23 2017 20:03
Sure
Franklin Mathieu
@Snaipe
Mar 23 2017 21:16
@truh it turns out this is unfixable
the problem comes mainly from nanomsg, which uses threads internally
however, mcheck & mprobe aren't thread safe, at all
I'd recommend you use valgrind or -fsanitize=address with criterion
Jakob Klepp
@truh
Mar 23 2017 21:43
Thank you for looking into it.