GCC中通过--wrap选项使用包装函数
在使用GCC編譯器時,如果不想工程使用系統的庫函數,例如在自己的工程中可以根據選項來控制是否使用系統中提供的malloc/free, new/delete函數,可以有兩種方法:
(1). 使用LD_PRELOAD環境變量:可以設置共享庫的路徑,并且該庫將在任何其它庫之前加載,即這個動態庫中符號優先級是最高的。
(2). 使用GCC的--wrap選項:對symbol使用包裝函數(wrapper function),任何對symbol未定義的引用(undefined reference)會被解析成__wrap_symbol,而任何對__real_symbol未定義的引用會被解析成symbol。即當一個名為symbol符號使用wrap功能時,工程中任何用到symbol符號的地方實際使用的是__wrap_symbol符號,任何用到__real_symbol的地方實際使用的是真正的symbol。注意:當__wrap_symbol是使用C++實現時,一定要加上extern “C”,否則將會出現”undefined reference to __wrap_symbol”。
以下是對--wrap使用的測試代碼:
wrap_symbol.hpp:
#ifndef FBC_LINUX_CODE_TEST_WRAP_SYMBOL_HPP_
#define FBC_LINUX_CODE_TEST_WRAP_SYMBOL_HPP_#include <stdlib.h>extern "C" {void* __wrap_malloc(size_t size);
void __wrap_free(void* ptr);void* __real_malloc(size_t size);
void __real_free(void* ptr);int foo();
int __wrap_foo();// c++filt: _Znwm ==> operator new(unsigned long)
void* __wrap__Znwm(unsigned long size);
// c++filt _ZdlPv ==> operator delete(void*)
void __wrap__ZdlPv(void* ptr);void* __real__Znwm(unsigned long size);
void __real__ZdlPv(void* ptr);} // extern "C"#endif // FBC_LINUX_CODE_TEST_WRAP_SYMBOL_HPP_
wrap_symbol.cpp:
#include "wrap_symbol.hpp"
#include <stdio.h>
#include <stdlib.h>void* __wrap_malloc(size_t size)
{fprintf(stdout, "call __wrap_malloc function, size: %d\n", size);return __real_malloc(size);
}void __wrap_free(void* ptr)
{fprintf(stdout, "call __wrap_free function\n");__real_free(ptr);
}int foo()
{fprintf(stdout, "call foo function\n");return 0;
}int __wrap_foo()
{fprintf(stdout, "call __wrap_foo function\n");return 0;
};void* __wrap__Znwm(unsigned long size)
{fprintf(stdout, "call __wrap__Znwm funtcion, size: %d\n", size);return __real__Znwm(size);
}void __wrap__ZdlPv(void* ptr)
{fprintf(stdout, "call __wrap__ZdlPv function\n");__real__ZdlPv(ptr);
}
test_wrap_symbol.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "wrap_symbol.hpp"int main()
{fprintf(stdout, "===== test start =====\n");char* p1 = (char*)malloc(4);free(p1);foo();int* p2 = new int;delete p2;fprintf(stdout, "===== test finish =====\n");return 0;
}
build_gcc_sh:
#! /bin/bashreal_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"new_dir_name=${dir_name}/buildif [[ -e ${new_dir_name} ]]; thenecho "rm build dir"rm -rf build
fimkdir -p ${new_dir_name}
cd ${new_dir_name}g++ -c ../*.cpp
g++ -o test_wrap_symbol *.o -O2 -Wall -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=foo -Wl,--wrap=_Znwm -Wl,--wrap=_ZdlPv./test_wrap_symbolcd -
將終端定位到Samples_C/wrap_symbol目錄下,執行:$ ./build_gcc.sh
運行結果如下:
GitHub:?https://github.com/fengbingchun/Linux_Code_Test?
總結
以上是生活随笔為你收集整理的GCC中通过--wrap选项使用包装函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吴恩达老师深度学习视频课笔记:序列模型和
- 下一篇: 决策树的C++实现(CART)