Snaipe / Mimick

A KISS, cross-platform C mocking library
MIT License
152 stars 43 forks source link

Test failing with `mimick: Could not find GOT entry for function fn_vv` #6

Closed niess closed 5 years ago

niess commented 5 years ago

Hello,

I am trying to use Mimick for unit testing some parts of my C code. I was seduced by the way it allows to plug in mock functions on the fly, without having to modify the base library, or auto-generating extra code.

But, I could not get it to work so far, on Debian 9 with gcc 6.3.0. I always get the following error: Could not find GOT entry for function .... Note that I have the same when running mmk_test with v0.3.0. Below is how I compile Mimick and how I run the test:

git clone https://github.com/diacritic/Mimick.git mimick
mkdir -p mimick/build && cd mimick/build
cmake ..
make
cd test && ./mmk_test

Am I doing something wrong? Should I pass extra options to CMake? This is what I get as ouptut:

$ cmake ..
-- The C compiler identification is GNU 6.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/cc
-- Looking for __stdio_common_vfprintf
-- Looking for __stdio_common_vfprintf - not found
-- Looking for _r_debug
-- Looking for _r_debug - found
-- Looking for _DYNAMIC
-- Looking for _DYNAMIC - found
-- Performing Test HAVE_ELF_AUXV_T
-- Performing Test HAVE_ELF_AUXV_T - Success
-- Performing Test HAVE_ELF_AUXINFO
-- Performing Test HAVE_ELF_AUXINFO - Failed
-- Looking for mmap
-- Looking for mmap - found
-- Looking for MAP_ANONYMOUS
-- Looking for MAP_ANONYMOUS - found
-- Looking for MAP_ANON
-- Looking for MAP_ANON - found
-- Configuring done
-- Generating done
-- Build files have been written to: ...

$ make
Scanning dependencies of target strdup
[  5%] Building C object sample/strdup/CMakeFiles/strdup.dir/strdup.c.o
[ 10%] Linking C shared library libstrdup.so
[ 10%] Built target strdup
Scanning dependencies of target mimick
[ 15%] Building ASM object CMakeFiles/mimick.dir/src/asm/trampoline-x86_64-systemv.S.o
[ 20%] Building C object CMakeFiles/mimick.dir/src/core.c.o
[ 25%] Building C object CMakeFiles/mimick.dir/src/matcher.c.o
[ 30%] Building C object CMakeFiles/mimick.dir/src/mock.c.o
[ 35%] Building C object CMakeFiles/mimick.dir/src/plt.c.o
[ 40%] Building C object CMakeFiles/mimick.dir/src/plt-elf.c.o
[ 45%] Building C object CMakeFiles/mimick.dir/src/stub.c.o
[ 50%] Building C object CMakeFiles/mimick.dir/src/trampoline.c.o
[ 55%] Building C object CMakeFiles/mimick.dir/src/verify.c.o
[ 60%] Building C object CMakeFiles/mimick.dir/src/vitals.c.o
[ 65%] Building C object CMakeFiles/mimick.dir/src/when.c.o
[ 70%] Linking C static library libmimick.a
[ 70%] Built target mimick
Scanning dependencies of target strdup_test
[ 75%] Building C object sample/strdup/CMakeFiles/strdup_test.dir/test.c.o
[ 80%] Linking C executable strdup_test
[ 80%] Built target strdup_test
Scanning dependencies of target foo
[ 85%] Building C object test/CMakeFiles/foo.dir/libfoo.c.o
[ 90%] Linking C shared library libfoo.so
[ 90%] Built target foo
Scanning dependencies of target mmk_test
[ 95%] Building C object test/CMakeFiles/mmk_test.dir/test.c.o
[100%] Linking C executable mmk_test
[100%] Built target mmk_test
Scanning dependencies of target mimick_tests
[100%] Built target mimick_tests

$ cd test && ./mmk_test
mimick: Could not find GOT entry for function fn_vv.
Aborted
Snaipe commented 5 years ago

What does nm -D --defined-only ./libfoo.so from the test directory say? There should be a GOT entry for the fn_vv, fn_ii, and fn_va functions.

Would you mind attaching here your generated libfoo.so? (you might need to tar-gz it up first)

niess commented 5 years ago

Hello,

In libfoo.so, I have the following symbols:

$ nm -D --defined-only libfoo.so 
0000000000201028 B __bss_start
0000000000201028 D _edata
0000000000201030 B _end
00000000000008a4 T _fini
00000000000007b2 T fn_ii
0000000000000847 T fn_ii_va
00000000000007d6 T fn_ili
00000000000007a9 T fn_iv
0000000000000799 T fn_vi
00000000000007ea T fn_vi_va
00000000000007c2 T fn_vli
0000000000000790 T fn_vv
0000000000000640 T _init

I attached gzips of the library and of the generated binary as well: mmk_test.gz libfoo.so.gz

Snaipe commented 5 years ago

I can reproduce this locally. It looks like the relocation type changed for these functions and they get stuffed in '.rela.dyn' instead of '.rela.plt'.

Snaipe commented 5 years ago

This should be fixed. Please confirm that this works on your end :)

niess commented 5 years ago

Hello Franklin,

It works as well for me :) Thank you.

But to be honest, meanwhile I finally followed a pure C -but more invasive- mocking strategy. I have dedicated tests builds where the mocked functions are overridden with global function pointers, using macros. It does the job for me right now. But I'll keep Mimick in mind for future uses. I would sure learn a lot from it digging further in your mixed C/assembly code :)

Cheers,

Valentin