什么是基于unix的系统中的延迟负载等价物.
我有一个代码foo.cpp,在用gcc编译时,我将它链接到共享对象(共有三个.so文件.).每个.so文件都有不同的选项.
./foo -v需要libversion.so
./foo -update需求libupdate.so
我需要这些库的符号只能在运行时解析.
./foo -v 即使libupdate.so库不存在也不应该破坏.
它在Windows中使用延迟加载选项(在dll的属性中).在Unix系统中它的等价物是什么.
威尔-lazy选项确实在UNIX一样吗?如果是这样,在哪里包含此选项:在makefile中还是在链接器ld中?
我正在尝试将elf文件加载到我制作的MIPS模拟器中.我遇到的问题是我不太明白精灵部分标题偏移背后的含义.当我进行段转储时,段25-31和33-35在0x00000000处"开始",但是标题表明该段以某个值的偏移量开始(例如010190).同样在-S部分的开头,readelf声明头部在内存中以0x107b4开始.但是在-S中可以看到,最早的内存分配(因为段0为空)实际上位于偏移010210的段26中.有人可以解释这里发生了什么吗?我想静态地将所有这个文件分配到一个内存数组中.是否有一些关于抵消的假设阻止我这样做?为什么readelf说0x107b4是标题起点?
另外,.init在将PC放在readelf指定的"入口点"之前,我应该运行吗?
编辑:好的,所以,我做了一个可执行文件的十六进制转储,我现在意识到偏移是指实际elf文件中的位置(包含"地址"0 - 11d48的元素.)所以我现在的问题是. ..如何解决许多内存地址引用地址0x00000000的事实?它们当然有不同的偏移但现在我知道这是特定于文件的,它意味着有几个部分别名.我是否真的在内存寻址中使用偏移量?
第25部分:
0x00000000 00474343 3a202847 4e552920 332e342e .GCC: (GNU) 3.4.
0x00000010 35000047 43433a20 ...
Run Code Online (Sandbox Code Playgroud)
Readelf -S 输出:
There are 36 section headers, starting at offset 0x107b4:
Run Code Online (Sandbox Code Playgroud)
章节标题:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 00400134 000134 00000d 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 00400144 000144 000020 00 A 0 0 4
[ …Run Code Online (Sandbox Code Playgroud) 目前在Windows上的Ubuntu Bash上运行llvm,clang,clang-format和clang-modernize.我想使用谷歌发布的一套清理工具,包括地址,内存和线程清理.fsanitize选项似乎都不起作用.
以下是ASAN的代码示例:
#include <stdlib.h>
int main() {
char *x = (char *)malloc(10 * sizeof(char *));
free(x);
return x[5];// purposely accessing deallocated memory
}
Run Code Online (Sandbox Code Playgroud)
这是windows上bash的clang调用:
$clang++-3.5 -fsanitize=address -o1 -fno-omit-frame-pointer -g main.cpp -o main
$./main
Run Code Online (Sandbox Code Playgroud)
结果
==70==Sanitizer CHECK failed: build/buildd/llvm-toolchain-snapshot-3.5/projects/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_linux.cc:211 ((IsOneOf(*current_, 's', 'p'))) != (0)(0,0)
Run Code Online (Sandbox Code Playgroud)
我喜欢关于如何使其工作的建议,或者我是否缺少工具链的一部分或其他东西.
如果失败,我想我将双启动Ubuntu或Debian,因为Windows的clang缺少像std:out支持这样的简单功能,尽管理想情况下我希望能够为Windows目标和Linux目标编译.我想避免双启动,因为Ubuntu无法安装Windows存储空间,但它们似乎很好地服务于Windows上的Ubuntu bash.
在主程序中,我dlopen和dlclose(LoadLibrary以及FreeLibrary分别)一个共享库.共享库包含一个静态变量,该变量在实例化dlopen和销毁时被实例化dlclose.这种行为在MSVC 2008和2013,GCC 3.4.6和Sunstudio 12.1上是一致的.但是,使用GCC 4.9.1和GCC 5.2.1,析构函数不再被调用dlclose.相反,它在程序退出之前被调用.
静态变量类的特殊性在于,在构造函数中,调用模板化函数get(全局范围)返回本地静态变量.
我能够使用链接到共享库的以下一个cpp文件重现此行为:
#include <iostream>
template <typename T> // In my actual code, i is of type T, however, this has no effect
int get()
{
static int i = 0;
return i;
}
class Dictionary {
public:
Dictionary()
{
std::cout << "Calling Constructor" << std::endl;
get<int>();
}
~Dictionary(){
std::cout << "Calling Destructor" << std::endl;
}
private: …Run Code Online (Sandbox Code Playgroud) lib.so如果在运行时满足特定条件,则需要动态打开共享库。该库包含约700个函数,我需要加载所有符号。
一个简单的解决方案是定义指向其中包含的所有符号的函数指针lib.so,使用加载库dlopen,最后使用来获取所有符号的地址dlsym。但是,鉴于功能的数量,实现此解决方案的代码非常繁琐。
我想知道是否存在一个更优雅,更简洁的解决方案,也许是通过适当地使用宏来定义函数指针。谢谢!
我只是通读 gcc 手册以找出-O3和之间的区别-Ofast。
为了 -O3
-O3
Run Code Online (Sandbox Code Playgroud)Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the following optimization flags: -fgcse-after-reload -fipa-cp-clone -floop-interchange -floop-unroll-and-jam -fpeel-loops -fpredictive-commoning -fsplit-paths -ftree-loop-distribute-patterns -ftree-loop-distribution -ftree-loop-vectorize -ftree-partial-pre -ftree-slp-vectorize -funswitch-loops -fvect-cost-model -fversion-loops-for-strides
虽然 -Ofast
-Ofast
Run Code Online (Sandbox Code Playgroud)Disregard strict standards compliance. -Ofast enables all -O3 optimizations. It also enables optimizations that are not valid for all standard-compliant programs. It turns on -ffast-math, -fallow-store-data-races and the Fortran-specific -fstack-arrays, unless -fmax-stack-var-size is …
非常奇怪的行为发生在我身上.我在Windows 7 64位上分别使用最新的Cygwin32,Cygwin64和MinGW32以及GCC 4.9.2,4.9.2和4.8.1.我也在使用GCC 4.8.2在32位Linux上进行测试.
所以在所有系统上都可行
#include <bits/stdc++.h>
using namespace std;
string s,t;
int main(){
cin>>s>>t;
cout<<s;
}
Run Code Online (Sandbox Code Playgroud)
这很有效
#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
string s="a",t="b";
int main(){
cin>>s>>t;
cout<<s;
}
Run Code Online (Sandbox Code Playgroud)
但是在上面提到的3种配置中输入第一个字符串后,下一个在Windows上崩溃,但在Linux上正常工作:
#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
string s,t;
int main(){
cin>>s>>t;
cout<<s;
}
Run Code Online (Sandbox Code Playgroud)
显然,唯一的区别是字符串在输入之前是空的,并且_GLIBCXX_DEBUG已启用.
首先,这是一个可重现的问题吗?即它是在具有相同配置的每台PC上发生的,还是只发生在我的PC上?第二,问题是什么?我该怎么办?我显然需要 _GLIBCXX_DEBUG在代码中调试其他STL结构.
我们使用以下代码来确定是否-fsanitize=address在编译时为clang和gcc指定了.我们如何确定是否-fsanitize=undefined已指定?
bool isSanitized = false;
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
isSanitized = true;
#endif
#elif defined(__SANITIZE_ADDRESS__)
isSanitized = true;
#endif
Run Code Online (Sandbox Code Playgroud) 我的项目依赖于一个第三方库,该库导出了更多应有的符号。其中一些符号被其他库和主程序无意地覆盖。
如何更改已编译共享对象的函数和变量的可见性?
据我了解,要ASAN_OPTIONS与 clang 一起使用,ASAN_OPTIONS必须在编译之前设置环境变量。
如何在 CMake 脚本中执行此操作而不添加包装器脚本?
仅当使用 clang 编译时,我才需要禁用某个特定测试项目的 ODR 违规检查。所以在CMakeLists.txt文件中我有:
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Clange reports ODR Violation errors in mbedtls/library/certs.c. Need to disable this check.
set(ENV{ASAN_OPTIONS} detect_odr_violation=0)
endif()
Run Code Online (Sandbox Code Playgroud)
但运行后cmake,如果我输入echo $ASAN_OPTIONS,则未设置。
运行后cmake,如果我输入:
export ASAN_OPTIONS=detect_odr_violation=0
make
Run Code Online (Sandbox Code Playgroud)
一切都很好。
是否可以cmake设置一个环境变量,以便它在cmake运行后仍然存在?抱歉我对环境的了解有限!