困扰几天的问题,这是被 gcc 优化了吗?

13 天前
 aqtata

一个动态库项目,支持 win32 和 arm64 ,编译器是 msvc 和 gcc ( gcc 是自己从源码编译的,版本 15.1.0 ) 对外暴露一个标准 C API ,其内部实现只有一行代码,调用一个内部名称空间内的方法

int my_foo()
{
    return internal::bar();
}

魔幻的事情是,这个 so 文件,我写一个控制台程序去调用它,能顺利进入到bar()中,放到实际项目中bar()根本就没有被调用,于是尝试打印

int my_foo()
{
    std::cout << "111111111111111" << std::endl;
    std::cout << __FUNCTION__ << std::endl;
    std::cout << "internal::bar address: " << (long long)((void*)&internal::bar);
    return internal::bar();
}

好家伙,在 linux 下只能打印前两行,然后函数返回 0 ,但这种情况只发生在项目引用时出现。写一个简单的命令行程序触发完全没问题,win32 下也都没问题。 我想 so 文件已经是二进制了,还能被链接它的程序优化不成?这里卡住了,不知道怎么办 项目均使用了-O2

5593 次点击
所在节点    C++
31 条回复
OBJECTION
13 天前
要不还是加个-g gdb 进去看看? 根据你的描述看不出来啥原因啊
zhyl
13 天前
只打印前两行会不会是没有 flush 输出缓冲区
Niunai
13 天前
前两行都有 std::endl ,第三行没有。#2 说的没毛病。
Niunai
13 天前
再说了,有没有被优化,反汇编来看看不就行了,有功夫上 V2 来问,没工夫反汇编吗?
猜测完了要验证。
xdeng
13 天前
拖到 IDA 里看一下就知道了
tusj
13 天前
你是依据什么判断函数没有被调用的?第 3 行没打印出来,可能是因为你没有 << std::endl;
aqtata
13 天前
没 std::endl 确实,我等下加上。但打印不是问题关键,主要问题时 bar 中的逻辑都没执行,导致接下来其他 api 接口都会调用失败。
但我这里试出来一个解决方法,给 bar 加上一个参数,比如 bar(int x),这样就能进入到 bar 中了,感觉还是和某种优化有关
Ming5Ming
13 天前
既然是一个方法,有没有可能是重载了?
minami
13 天前
怀疑优化问题的话可以关闭优化看看。不过盲猜是动态库导出函数调用约定的问题,可以把 internal::bar();提前不要放到 return 里看看,如果能执行就是这个问题了
Liuuwei
13 天前
程序都跑完了,缓冲区还会不刷新?
nooneanyone
13 天前
是不是动态链接的问题?
a83223676
13 天前
我会先这么写代码试试

int my_foo()
{
std::cout << __FUNCTION__ << std::endl;
std::cout << "before call bar" << std::endl;
int ret = internal::bar();
std::cout << "after call bar.ret:" << ret << std::endl;
return ret;
}
rtv
13 天前
问 ai 回答可能是符号冲突…你回复也说加一个参数就没问题
kita
13 天前
你有无 extern "C" {}; 不然可能 link 时候 symbols 不对
txhwind
13 天前
100%是名字冲突了
Ilavena
13 天前
首先,你自己写了一个控制台程序取调用它,没有问题,说明动态库是正常的,实际项目里面是否存在 internal::bar 接口影响的?
1 ,在 my_fool 用 exectern C 包装一下,重新编译这个动态库。
2 ,在 linux 下建议你尝试使用 dlopen 加载动态库,以及 dlsym 调用对应接口
这样我觉得问题应该能够解决。
请告诉结果哈
Ilavena
13 天前
c++还是蛮有魅力的,我搞了 5 年 c++开发,最近再学深度学习,搞 python ,觉得 python 真的简单易学,也觉得 python 真的牛逼。
weidaizi
13 天前
1. 首先,使用 -O2 也可以加 -g ,遇到这个情况先 debug ,看看代码到底跑哪里去了
2. 其次,这种简单的问题 99.999999% 不是编译器的问题,所以快去做第 1 件事
3. 如果在项目中调试也是确实没跑进去,建议开个 sanitizer 看看有没有出现未定义的行为
hwdq0012
13 天前
感觉是动态库是旧的,看看编译时间
cbythe434
13 天前
internal 命名空间覆盖了吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1142912

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX