Mocking C functions in MSVC (Visual Studio) - c

I am reading several articles on mocking C functions (like CMock, or CMocka), but I am not sure how the actual functions are replaced with mocked functions in this process. For example, CMocka relies on automatic wrapping using a GNU compiler, which supports parameters like --wrap to append the __wrap prefix to function calls, or weak symbols which allow you to override any symbol you like.
But how do you do this in Visual Studio, for pretty much all other frameworks?
For example, CMock has an example similar to this (simplified a lot here):
// myfunc.c
#include <parsestuff.h>
// this is the function we would like to test
int MyFunc(char* Command)
{
// this is the call to the function we will mock
return ParseStuff(Command);
}
There is also the actual implementation, which contains the actual function the linker should find in the actual application:
// parsestuff.c
int ParseStuff(char* cmd)
{
// do some actual work
return 42;
}
Now, during testing the Ruby script creates mock functions like:
// MockParseStuff.c (auto created by cmock)
int ParseStuff(char* Cmd);
void ParseStuff_ExpectAndReturn(char* Cmd, int toReturn);
But if the VS project already includes parsestuff.c, how will it be possible that the call from myfunc.c ends up in MockParseStuff.c?
Does this mean I cannot have parsestuff.c included in the unit testing project? But if this is the case, then it's also impossible to mock, for example, MyFunc from myfunc.c in any tests, since I already had to include the file it in order to test it?
(Update) I am also aware that I can include the .c file instead of the .h file, and then do some preprocessor stuff to replace the original call, like:
// replace ParseStuff with ParseStuff_wrap
#define ParseStuff ParseStuff_wrap
// include the source instead of the header
#include <myfunc.c>
#undef ParseStuff
int ParseStuff_wrap(char* cmd)
{
// this will get called from MyFunc,
// which is now statically included
}
but this seems like a lot of plumbing, and I don't even see it mentioned anywhere.

Here's a simple and short solution with hippomocks:
I created an empty Win32 console application with
main.cpp
myfunc.c + myfunc.h
parsestuff.c, parsestuff.h
and added the code from your example.
With help of hippomocks, you can mock every C-Function. Here's how my main.cpp looks like:
#include "stdafx.h"
#include "myfunc.h"
#include "hippomocks.h"
extern "C" int ParseStuff(char* cmd);
int _tmain(int argc, _TCHAR* argv[])
{
MockRepository mocks;
mocks.ExpectCallFunc(ParseStuff).Return(4711);
char buf[10] = "";
int result = MyFunc(buf);
return result; //assert result is 4711
}
HippoMocks is a free, simple and very powerful one-header framework and can be downloaded on GitHub.
Hope I've earned the bounty :)
UPDATE, How it works:
HippoMocks gets the func pointer to ParseStuff
HippoMocks builds a replacement func pointer to a template function with same signature and own implementation.
Hippomocks patches the jmp opcode from the function call prologue in memory, so that it points to the replaced function.
Replacement and memory patch are released after call or in destructor.
Here's how it looks like on my machine:
#ILT+3080(_ParseStuff):
00D21C0D jmp HippoMocks::mockFuncs<char,int>::static_expectation1<0,char *> (0D21DB1h)
If you watch the memory address 00D21C0D (may differ from run to run) in memory window, you will see, that it gets patched after the call of ExpectCallFunc.

I have not dealt with the C mocking libraries or Visual Studio, but I have thought about this in my own project. The Feathers book suggests the preprocessor seam or the link seam as a tool for dealing with this. You already mentioned the preprocessor seam, so I'll focus on the link seam.
The link seam requires the mocked function to be in a library, and the mock function to be in a library. The test can link against the mock function library while the target application can link against the original library.
Of course, as you mention, to mock MyFunc() you will have to create another library and a separate test application to link against it (or dynamically load and unload libraries in the test application).
It sounds quite laborious which is why I am procrastinating adding tests in my own application!
Hope this helps!

Related

DLL dependency to static library

I currently build a purely static library MainLib for our customers that contains all symbols so that they can intrgrate it into their program. For several reasons, I now need to deliver a DLL version of MainLib that contains parts of the symbols alongside a static library FeatureLib that contains the remaining symbols. One reason is that we want to avoid bad guys using our software by simply stealing the DLL that is provided via the program of our customer. This wouldn't work if parts of the symbols are integrated within the calling software via a static library. The user of the package shall only be able to use the DLL if he added the symbols of FeatureLib into his application.
For Linux, I can make this work like a charm,i.e. the symbol doFeature() is not within libMainLib.so, but I don't succeed on this for Windows.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(MainLib)
add_library(FeatureLib STATIC src/FeatureLib.c)
target_include_directories(FeatureLib PUBLIC include
PRIVATE src)
add_library(MainLib SHARED src/MainLib.c)
target_include_directories(MainLib PUBLIC include
PRIVATE src)
# I don't want to include symbols from FeatureLib into shared MainLib
#target_link_libraries(MainLib PRIVATE FeatureLib)
add_executable(MainLibDemo src/demo.c)
target_link_libraries(MainLibDemo MainLib FeatureLib) #resolve symbol doFeature()
FeatureLib.h:
extern int doFeature(int input);
MainLib.h:
extern __declspec(dllexport) int MainLib(int input);
FeatureLib.c:
#include "FeatureLib.h"
int doFeature(int input) {return 4;}
MainLib.c:
#include "FeatureLib.h"
#include "MainLib.h"
__declspec(dllexport) int MainLib(int input)
{
if (input > 2) {
return doFeature(input);
} else {
return doFeature(0);
}
}
demo.c:
#include <stdio.h>
#include <stdlib.h>
#include "MainLib.h"
int main(int argc, char **argv)
{
if(argc > 1)
return MainLib(atoi(argv[1]));
else
return 0;
}
With this, I get the following compilation error:
"C:\Daten\tmp\DemoProject\simple\build\ALL_BUILD.vcxproj" (Standardziel) (1) ->
"C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj" (Standardziel) (4) ->
(Link Ziel) ->
MainLib.obj : error LNK2019: unresolved external symbol _doFeature referenced in function _MainLib [C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj]
C:\Daten\tmp\DemoProject\simple\build\Debug\MainLib.dll : fatal error LNK1120: 1 unresolved externals [C:\Daten\tmp\DemoProject\simple\build\MainLib.vcxproj]
0 Warnung(en)
2 Fehler
Is this even possible with Windows? What do I have to do to make it work and how can I verify it other than not linking FeatureLib to MainLibDemo. Any ideas are very welcome.
Kind regards,
Florian
The way you do it under Linux will not work under Windows
because dynamic linking works differently here.
Here is one strategy that could work.
In MainLib.dll code, instead of directly calling doFeature
you need to define a global pointer variable of proper function
pointer type and use it to call the function.
This will allow to build MainLib.dll without errors.
Now you need to set this pointer variable. One way would be:
Add exported function to MainLib.dll that takes pointers
to all functions that the DLL needs from the executable.
In FeatureLib.lib code add an initialisation function
that the application will need to call before using
your DLL which will pass pointers to its peers to the DLL.
This is basically the way most programs with plugins use to
give the plugins access to their facilities.
Another way would be to (Warning! I have not tested this specific
solution):
Declare the functions in FeatureLib.lib as exported
with __declspec(dllexport). This way they will be exported
from executable.
In MainLib.dll before first using the pointers use
GetModuleHandle and GetProcAddress to obtain the pointers.
It would best be done in some initialisation function for the
library. Otherwise you need to take care to avoid race conditions.
Hope this will help.
Though I do not think your copy protection scheme will work.
Andrew Henle is right in his comment: it is not hard
to extract the needed code from one executable and include it
in another.

Link with custom function instead of crt one

I'm working on an application which defines it's own printf() to get around differences between the different CRTs out there or because some other platforms don't have it.
When building the application with gcc this automatically seems to work and the custom printf is used instead of libc's one; if I understand it correctly this is because of the order in which object files/libraries appear in the link command or maybe because object files are always searched before CRT libs, correct?
I'd like to do the same using msvc. Just building the project gives the expected 'LNK2005: _printf already defined in printf.obj' because printf is also in msvcrtd.lib. Fair enough. I know about /NODEFAULTLIB but that excludes everything resulting in unresolved references for everything but printf. I scanned through the other linker settings but couldn't find anything which allows this (apart from /FORCE maybe, but the 'might produce an invalid executable' comment doesn't make it sound like a good idea). Also nothing in the module definition file docs; the latter got me thinking it might be possible to create a stub library which has all exports from msvcrt.lib except printf but that seems a brittle solution even if it works.
In the end the question is simple: how do I tell msvc's linker it should skip msvcrt's printf definition and use the one from my printf.obj instead. Basically /NODEFAULTFUNCTION:printf or so. Just an answer for one single executable is ok, though I'd also be interested to know if and how it can be done when building a dll instead where the custom printf is exported: how to tell the linker it should use the export from my .lib instead of msvcrt.lib?
edit simplest repo I could find: create a file main.c:
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello");
return 0;
}
and a file printf.c:
int printf(const char *fmt, ...)
{
write(1, "ok\n", 3);
return 3;
}
For VS2013 (though the other versions might work as well): create a new empty C++ project and add both files then build. (For gcc: just gcc main.c printf.c and the resulting a.out prints 'ok')
The culptrit for VS is #include : without that it works ok but I have yet to find out if the original code allows getting rid of it in some way. But even if it does I'd still want to know if this can be solved at the link level.

Using Go code in an existing C project

Ever since Go 1.5 came out, I started taking another look at how I could integrate it into an existing project of mine.
The project's codebase is written entirely in C for low level access to to hardware and other fun stuff. However, some of the higher level things are tedious, and I would like to start writing them in a higher level language (Go)
Is there any way I can call Go code from a C program? I installed Go 1.5, which added -buildmode=c-archive (https://golang.org/s/execmodes) which I am trying to get working.
However, I can't seem to get Go to generate the appropriate header files to allow my project to actually compile. When I generate the archive, I see the function in the exported symbols (using objdump), but without the header files to include gcc complains about the function not existing (as expected)
I'm quite new to Go - however, I love the language and would like to make use of it. Is there any idiomatic way ("idiomatic" gets used a lot in the world of Go I see...) to get this to play nicely with each other?
The reason I asked this question and specifically mentioned Go 1.5 is that according to this document, https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5ytjfcoke
Go 1.5 added support for non-Go programs to call Go code. Specifically, mentioned under the section "Go code linked into, and called from, a non-Go program"
To build an archive callable from C, you will need to mark them as exported CGo symbols.
For example, if I create a file foo.go with the following contents:
package main
import (
"C"
"fmt"
)
//export PrintInt
func PrintInt(x int) {
fmt.Println(x)
}
func main() {}
The important things to note are:
The package needs to be called main
You need to have a main function, although it can be empty.
You need to import the package C
You need special //export comments to mark the functions you want callable from C.
I can compile it as a C callable static library with the following command:
go build -buildmode=c-archive foo.go
The results will be an archive foo.a and a header foo.h. In the header, we get the following (eliding irrelevant parts):
...
typedef long long GoInt64;
...
typedef GoInt64 GoInt;
...
extern void PrintInt(GoInt p0);
...
So that's enough to call the exported function. We can write a simple C program that calls it like so:
#include "foo.h"
int main(int argc, char **argv) {
PrintInt(42);
return 0;
}
We can compile it with a command like:
gcc -pthread foo.c foo.a -o foo
The -pthread option is needed because the Go runtime makes use of threads. When I run the resulting executable it prints 42.
The code above work just fine, but gcc will complain about functions and headers.
The includes should be:
#define _GNU_SOURCE
#include <stdio.h>
#include "mygopkg.h"
If you forget the #define _GNU_SOURCE, the gcc will complain:
warning: implicit declaration of function 'asprintf'; did you mean 'vsprintf'? [-Wimplicit-function-declaration]
If you forget the #include "mygopkg.h", the gcc will complain:
warning: implicit declaration of function 'PrintString' [-Wimplicit-function-declaration]
The last but not less important. The build command line I recommend for production code is:
go build -ldflags "-s -w" -buildmode c-archive -o mygopkg.a
It'll save you 53% size of final mygopkg.a.

Error compiling Linux kernel module using custom system calls

I'll walk you through step by step
First I edit 3 files in my Linux kernel directory
Open LINUX_DIRECTORY/arch/x86/syscalls/syscall_64.tbl and add the custom calls i'm implementing – using the appropriate format
Declare them here: LINUX_DIRECTORY/include/linux/syscalls.h – using the appropriate format:
Open LINUX_DIRECTORY/Makefile and add the directory I'm storing my new system calls to the core-y line:
core-y := usr/ my_system_call_directory/
Here's where I'm having issues. Inside LINUX_DIRECTORY/my_system_call_directory I add a C file with my custom system call definitions and its corresponding Makefile. I leave the definitions empty because inside the C file for my kernel module I declare an extern function (my custom system call) and define a separate function which is set to my extern function:
extern long (*start_shuttle)(void);
long my_start_shuttle(void) {
// stuff here
}
int init_module(void) {
// stuff here
start_shuttle = my_start_shuttle;
// more stuff
}
After recompiling the kernel I try to make the kernel module and get a no definition for start_shuttle error.
Is this because I left the definition for start_shuttle blank in my_system_call_directory? Should it match exactly the my_start_shuttle I defined in the kernel module or is there something special I'm supposed to add? I'm asking dumb questions in advance because it takes so long for my machine to recompile Linux and I'm not sure what to change. Thanks
Figured it out. For anyone as slow as me, you have to use a wrapper and a stub.
So for this example, in the my_system_call_directory, in the c file for your new system call definitions, you need something like this:
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/export.h>
// initialize the stub function to be NULL
long (*start_shuttle)(void) = NULL;
EXPORT_SYMBOL(start_shuttle);
// wrapper
asmlinkage long sys_start_shuttle(void)
{
if (start_shuttle)
return start_shuttle();
else
return -ENOSYS;
}

Mac sandbox: running a binary tool that needs /tmp

I have a sandboxed Cocoa app that, during an export process, needs to run a third party command-line tool. This tool appears to be hardcoded to use /tmp for its temporary files; sandboxing doesn't permit access to this folder, so the export fails.
How can I get this tool to run? I don't have access to its source code, so I can't modify it to use NSTemporaryDirectory(), and it doesn't appear to respect the TMP or TEMPDIR environment variables. For reasons I don't understand, giving myself a com.apple.security.temporary-exception.files.absolute-path.read-write entitlement doesn't seem to work, either.
Is there some way to re-map folders within my sandbox? Is there some obscure trick I can use? Should I try to patch the tool's binary somehow? I'm at my wit's end here.
I was able to get user3159253's DYLD_INSERT_LIBRARIES approach to work. I'm hoping they will write an answer describing how that works, so I'll leave the details of that out and explain the parts that ended up being specific to this case.
Thanks to LLDB, elbow grease, and not a little help from Hopper, I was able to determine that the third-party tool used mkstemp() to generate its temporary file names, and some calls (not all) used a fixed template starting with /tmp. I then wrote a libtmphack.dylib that intercepted calls to mkstemp() and modified the parameters before calling the standard library version.
Since mkstemp() takes a pointer to a preallocated buffer, I didn't feel like I could rewrite a path starting with a short string like "/tmp" to the very long string needed to get to the Caches folder inside the sandbox. Instead, I opted to create a symlink to it called "$tmp" in the current working directory. This could break if the tool chdir()'d at an inopportune time, but fortunately it doesn't seem to do that.
Here's my code:
//
// libtmphack.c
// Typesetter
//
// Created by Brent Royal-Gordon on 8/27/14.
// Copyright (c) 2014 Groundbreaking Software. This file is MIT licensed.
//
#include "libtmphack.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
//#include <errno.h>
#include <string.h>
static int gbs_has_prefix(char * needle, char * haystack) {
return strncmp(needle, haystack, strlen(needle)) == 0;
}
int mkstemp(char *template) {
static int (*original_mkstemp)(char * template) = NULL;
if(!original_mkstemp) {
original_mkstemp = dlsym(RTLD_NEXT, "mkstemp");
}
if(gbs_has_prefix("/tmp", template)) {
printf("libtmphack: rewrote mkstemp(\"%s\") ", template);
template[0] = '$';
printf("to mkstemp(\"%s\")\n", template);
// If this isn't successful, we'll presume it's because it's already been made
symlink(getenv("TEMP"), "$tmp");
int ret = original_mkstemp(template);
// Can't do this, the caller needs to be able to open the file
// int retErrno = errno;
// unlink("$tmp");
// errno = retErrno;
return ret;
}
else {
printf("libtmphack: OK with mkstemp(\"%s\")\n", template);
return original_mkstemp(template);
}
}
Very quick and dirty, but it works like a charm.
Since #BrentRoyal-Gordon has already published a working solution I'm simply duplicating my comment which inspired him to produce the solution:
In order to fix a program behavior, I would intercept and override some system calls with the help of DYLD_INSERT_LIBRARIES and a custom shared library with a custom implementation of the given system calls.
The exact list of the syscalls which need to be overridden depends on nature of the application and can be studied with a number of tools built upon MacOS DTrace kernel facility. E.g. dtruss or Hopper. #BrentRoyal-Gordon has investigated that the app can be fixed solely with an /appropriate/ implementation of mkstemp.
That's it. I'm still not sure that I've deserved the bounty :)
Another solution would be to use chroot within the child process (or posix_spawn options) to change its root directory to a directory that is within your sandbox. Its “/tmp” will then be a “tmp” directory within that directory.

Resources