Override C function defined in static library

I have a static C file library compiled from g ++ on Cygwin. I want unit test one function defined in a library. This function calls another function defined in this library, and I want to override the dependency in order to replace it with my own version of this function. I cannot change what is in the static library, so this solution [ Override function call in C ] does not apply.

Usually I can write the .cpp file and include the .c file containing the function that I want to use unit test, which essentially extends this file with the code that I add. This is a dirty trick that I would never use for production code, but it is convenient for unit testing C files, because it gives my test code access to static things in this C file. Then I can write in my fake version of the dependency my unit test function, which calls the function that I am testing. I compile my.cpp to get my.o and then link it to a static library. Theoretically, since the linker found a definition of an already dependent dependency (the one I provide), it will not look in the library, and there will be no conflict. This usually works, but now I get a "multiple definition" error when the linker first finds my fake and then finds the real one. I do not know what can cause this and I do not know what to look for. I also cannot weld this with a simple example, because my simple examples do not have this problem.

Ideas please?

+6
source share
3 answers

One possibility (though ugly, but ...) is to extract individual object files from a static library. If the function you are calling and the function you are calling are in separate object files, you can link them to an object file that contains the function you want to call, but not against the one that contains the function it calls.

This only gives you granularity at the level of complete object files, so if the two functions involved are in the same object file, this will not work. If you really need to make it work and not mind making minor modifications to the object file in question, you can use the binary editor to designate the second function as a weak external, which means it will be used in the absence of any other external with the same name, but if provided another, it will be used instead.

Regardless of whether the latter refers to the β€œmodification of the library" or not, it depends a little on your point of view. It does not modify the code in the library, but modifies the wrapper bit of the object file around this code. I assume that you would rather not do this, but this may be the cleanest way out of a situation that might otherwise be untenable.

+5
source

It turns out that the reason the linker detected both errors of the function is because the falsified function file sets the variable that is in its header file. This unresolved external header file caused the linker to link the fake function object file (all of this) to the checked function file inside the library. Thus, it is not possible to determine the definition of the test function without determining the dependency.

What I ended up was like Overriding a function call in C , where I used a different function name instead of the same one, and a preprocessor directive to exchange two. I put the preprocessor directive and the fake function in a separate file, which can be included in the unit test, so the production code in the library does not need to be touched. Also, if I want to fake the same function for another unit test in another place, I can reuse the new file.

0
source

Depending on your platform and performance requirements, you can use pin to dynamically change the application and replace one function with another at runtime.

There is no direct example in the manual, but you can easily change one of the proxy output tools for this.

0
source

Source: https://habr.com/ru/post/900735/


All Articles