GCC中用__wrap拦截connect/stat函数出现链接错误的原因咨询
--wrap Fails for connect() and stat() (But Works for malloc()/socket()) Great question—this is a common gotcha with the linker's --wrap mechanism, and it boils down to two main reasons tied to how certain libc functions are handled by compilers and linkers. Let’s break this down clearly:
1. Compiler Built-ins Are Replacing Standard Function Calls
GCC (and most modern compilers) provide optimized built-in versions of functions like stat() and connect(). When you call these functions in your code, the compiler might replace the standard call with a built-in intrinsic (e.g., __builtin_stat()) instead of generating a reference to the actual libc stat() function.
Since --wrap only intercepts explicit function references (not compiler intrinsics), the linker never sees a call to stat() or connect() to wrap. Worse, when your __wrap_stat() tries to invoke __real_stat(), the linker can’t find the original libc symbol because it was never pulled into the binary (the compiler used the built-in instead).
Fix for Built-ins
Compile your code with flags to disable these built-ins, forcing the compiler to generate direct calls to standard libc functions:
gcc -fno-builtin-stat -fno-builtin-connect -Wl,--wrap=stat -Wl,--wrap=connect your_code.c -o your_program
2. Platform-Specific Versioned Aliases/Macros
On systems like Linux, functions such as stat() are often macros that alias to versioned functions (e.g., __stat64 for 64-bit file support). When you write stat() in your code, the preprocessor replaces it with the versioned name before the linker ever processes your code.
For example, checking your preprocessed code with gcc -E your_code.c | grep stat might output something like:
__stat64("/path/to/file", &stat_buf);
In this case, wrapping stat does nothing—you need to target the actual underlying function name instead.
Fix for Aliases
- First, find the real function name by inspecting preprocessed output:
gcc -E your_code.c | grep -E "(stat|connect)" | head -10 - Update your linker flags and wrap functions to match the alias. For example, if
stataliases to__stat64:- Linker flag:
-Wl,--wrap=__stat64 - Wrap function:
int __wrap___stat64(const char *path, struct stat *buf) { // Your interception logic here return __real___stat64(path, buf); }
- Linker flag:
Why Does This Work for malloc()/socket()?
Functions like malloc() and socket() are less likely to be replaced by built-ins (or their built-ins are disabled by default), and they don’t use versioned aliases on most platforms. The linker sees direct references to these functions, so --wrap behaves as expected.
内容的提问来源于stack exchange,提问作者a_pradhan

