(这是关于gcc和clang的问题,但可能适用于其他编译器.)
如果我编译我的C或C++代码,并使用生成调试信息-g开关,这是否本身降解以任何方式编译的程序的性能...(1)用最小优化(-O0)?(2.)最大化优化(-O3)?
注意:我并不是说必须解析/加载可执行文件的性能损失,由于额外的内容,这可能会更大; 我指的是运行的代码.
我在Visual Studio 2010中启动了一个空白项目来编写C应用程序.如何将调试信息发送到" 输出"窗口(菜单" 调试" - >" Windows" - >" 输出")?是否有相对简单的方法来实现TRACE或OutputDebugString类似的东西?
我正在使用 valgrind 尝试查找 C-cum-C++ 程序中内存访问违规的原因。即使避免了这种访问(即当一切运行正常时),valgrind 告诉我:
==11436== Memcheck, a memory error detector
==11436== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==11436== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==11436== Command: bin/monetdb-bp-reader /home/eyalroz/dbfarms/monetdb/tpch-sf-1
==11436==
--11436-- WARNING: Serious error when reading debug info
--11436-- When reading debug info from /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24:
--11436-- Ignoring non-Dwarf2/3/4 block in .debug_info
--11436-- WARNING: Serious error when reading debug info
--11436-- When reading debug info from /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24:
--11436-- Last block truncated …Run Code Online (Sandbox Code Playgroud) 我正在努力为我的OSS应用程序添加异常和异常处理.例外从一开始就是一般的想法,但是我想找到一个好的异常框架,并且在开始使用它们之前,要完全理解C++异常处理约定和习惯用法.我在使用C#/ .Net,Python和其他使用异常的语言方面有很多经验.我对这个想法并不陌生(但远非主人).
在C#和Python中,当发生未处理的异常时,用户会获得一个很好的堆栈跟踪,并且通常会获得许多非常有用的无价调试信息.如果你正在开发一个OSS应用程序,让用户将这些信息粘贴到问题报告中......好吧,我只是说我发现没有它就很难生存.对于这个C++项目,我得到"应用程序崩溃",或者来自更明智的用户,"我做了X,Y和Z,然后它崩溃了".但我也想要调试信息!
我已经(并且非常困难)让我感到安心,因为我永远不会看到跨平台和交叉编译的方式获得C++异常堆栈跟踪,但我知道我可以获得函数名称和其他相关信息.
现在我想要那些未经处理的例外情况.我正在使用boost :: exception,他们有这个非常好的diagnostic_information thingamajig,它可以打印出(unmangled)函数名,文件,行,最重要的是,程序员添加到该异常的其他异常特定信息.
当然,我会尽可能地处理代码中的异常,但我认为我不会让一对夫妇溜走(当然是无意的).
所以我想做的是将我的主入口点包装在一个try块中catch,创建一个特殊的对话框,通知用户应用程序中发生了错误,当用户单击"更多"或"调试"时会显示更详细的信息信息"或其他什么.这将包含来自diagnostic_information的字符串.然后,我可以指示用户将此信息粘贴到问题报告中.
但是一种唠叨的直觉感觉告诉我,将一切都包装在一个试块中是一个非常糟糕的主意.我将要做什么愚蠢的事情?如果是(即使不是),有什么更好的方法来实现我想要的?
我试图perf在 Ubuntu 20.04 上进行配置,但问题是许多函数没有出现在其中(可能是因为它们是内联的),或者只出现它们的地址(没有名称等)。我正在使用 CMake 的RelWithDebInfo构建。但有一些模板函数我不知道如何将其引入分析器结果中。我认为noinline如果这在 C++ 中对于模板函数是合法的,那么标记它们可能会有所帮助,但这会破坏代码库并且需要针对每个函数完成。有什么建议如何noinline同时实现所有功能吗?
是否有任何工具可以从 Java .class 文件中删除调试信息,就像/usr/bin/strip可以从 Linux 上的 C/C++ 对象文件中删除一样?
编辑:我喜欢 Thilo 和 Peter Mmm 的回答:Peter 的回答很短,以至于暴露了我对 JDK 附带的内容的无知;Thilo 的 ProGuard 建议无论如何我肯定会检查它似乎提供的所有额外功能。谢谢蒂洛和彼得!
删除发布配置文件中的调试信息将我的板条箱的二进制大小减少了三分之一(从 1.9 MB 到 1.3 MB)。这是我添加的:
[profile.release]
strip = true
# or strip = "symbols"
Run Code Online (Sandbox Code Playgroud)
为什么在发布配置文件中默认禁用剥离?
我阅读了有关带状货物选项的部分,但我仍然对其内部结构有点不确定。
始终在发布配置文件中使用它是否有任何缺点 - 也许只会增加编译时间?
例如:
#include <stdlib.h>
#define A 20
#define B 22
#define C (A+B)
int main()
{
srand(time(0));
int i = (rand()&1) + C;
return i;
}
Run Code Online (Sandbox Code Playgroud)
在gdb中,
(gdb) print C
No symbol "C" in current context.
Run Code Online (Sandbox Code Playgroud)
我怎么知道C是什么?可以gdb告诉我吗?(我添加的rand()所以我们不能轻易推断出它是什么)
预处理器会将 C 替换为(20+22). 这个值可以在 debuginfo 中以某种方式打印吗?
在宏可能非常复杂的真实示例中,我不想浪费时间做预处理器的工作。