
gcc
文章平均质量分 61
工作中对gcc的工作机制的一些总结。
优惠券已抵扣
余额抵扣
还需支付
¥59.90
¥99.00
购买须知?
本专栏为图文内容,最终完结不会低于15篇文章。
订阅专栏,享有专栏所有文章阅读权限。
本专栏为虚拟商品,基于网络商品和虚拟商品的性质和特征,专栏一经购买无正当理由不予退款,不支持升级,敬请谅解。
mzhan017
小张
展开
-
gcc: attribute: packed
在C语言中,enum类型默认占用4个字节的内存空间。然而,通过使用__attribute__((packed))属性,可以强制编译器将enum类型压缩到最小可能的字节数。例如,在给定的代码中,enum类型abc在没有packed属性时占用4个字节,而加上packed属性后,它仅占用1个字节。这是因为packed属性告诉编译器尽可能紧凑地存储数据,减少内存占用。这一特性在处理内存敏感的应用时非常有用,但需要注意可能带来的对齐问题。原创 2025-05-19 14:50:36 · 104 阅读 · 0 评论 -
[晕事]今天做了件晕事75 as: unrecognized option ‘--gdwarf-4‘
说是不认识的as选项。那就是gcc传递进来的这个参数,as不认识,最后调查的原因是在本地手动编译过gcc-11 这个版本,但是as对应的版本是8.5。binutils和gcc的版本不匹配导致。原创 2025-05-08 05:39:58 · 276 阅读 · 0 评论 -
[晕事]今天做了件晕事71,_GNU_SOURCE
通过搜索发现需要include的头文件就是:netinet/in.h。加上这个头文件,还是出现找不到结构体的错误。最后通过仔细查看头文件,发现,这个结构体定义是在宏判断里:#ifdef __USE_GNU。说明要是有gnu相关的扩展功能。原创 2025-04-17 05:18:31 · 88 阅读 · 0 评论 -
[程序员]经典挖坑场景9,gcc代码优化与汇编指令的冲突
原因是gcc做了优化,使用到了浮点类型的指令,这个指令要求是存储地址是16字节对齐,如果不对齐,就会coredump。产生coredump的地址是栈上的一个地址,之前一直没有想明白为什么没有对齐,按照理论是gcc来做对齐,然后gcc做优化使用浮点指令。所以一切都在gcc的操控范围之内,怎么产生不一致的可能?昨天凌晨想通了这个问题,是因为工程里有几个文件是直接使用汇编写的,所以对于栈空间汇编代码自己来做的空间分配。所以下一步方向就是看这一部分汇编代码,看看有没有地方产生不对齐的可能。原创 2025-02-26 20:11:14 · 162 阅读 · 0 评论 -
[晕事]今天做了件晕事65,gcc,cmake, pragam
pragma指令在Unity构建中仍然有效,但需要注意的是,如果多个源文件合并到一个编译单元中,可能会引发#pragma指令的冲突或重复定义问题。总结来说,CMake和Unity构建系统不会直接影响GCC的#pragma指令的行为,但在使用这些构建系统时,需要注意#pragma指令的兼容性和作用范围,以避免潜在的冲突和问题。不同的编译器可能支持不同的#pragma指令。作用范围:#pragma指令的作用范围通常是从指令出现的位置到文件结束或遇到相应的#pragma指令(如#pragma pop)。原创 2025-02-24 08:07:09 · 439 阅读 · 0 评论 -
[晕事]今天做了件晕事64,perf, gcc-O2
从perf抓的数据看每个线程,每个函数的使用都很平均,而且通过反汇编看,也都是正常的业务逻辑。那是为什么比原来程序的CPU使用要多呢?最后幸好这个同事想起来,新的binary是debug版本,而之前的版本是release版本,这就是apple-to-apple的对比标准需要得到落实的原因。在debug版本没有添加gcc的-O2选项,而release版本加了,这个性能差异就出来了。其实也不是这么突然,而是因为换了一个新的binary之后才出现的问题。最近和同事看一个程序突然CPU使用率增加的问题。原创 2025-02-18 12:39:59 · 169 阅读 · 0 评论 -
gcc: 单独给某个函数指定优化选项
第二个是pragma,这个是设置之后,当前编译单元后续的函数都是按照这个设定来编译。第一个是使用attribute。根据文档是有两个方式,原创 2025-02-08 22:08:58 · 76 阅读 · 0 评论 -
C++: glibc: pthread: pthread_cond_destroy,程序hang一例
有的实现可能会导致,pthread_cond_destroy() 将 cond所引用的对象设置为无效值。在其被销毁后,仍然引用该对象的结果是未定义的。程序在退出的时候,调用到了pthread_cond_destroy,但是另一个线程还在pthread_cond_timedwait。代码里的注释,也在强调,应用程序需要在销毁convar的时候,确保没有waiter仍然被block。未定义的行为:指的是程序可能表现出任何行为,包括看似正常工作、崩溃或产生错误结果,这取决于具体的实现和环境。原创 2025-01-03 07:12:36 · 510 阅读 · 0 评论 -
gcc: leaf function/non-leaf function;末节函数,叶子函数
意思:当一个带有这种属性的函数调用外部函数时,外部函数必须通过普通的返回机制(return)或者通过异常处理机制(如 C++ 的 throw 和 catch 机制)返回到当前编译单元。意思:虽然这些函数被称为叶函数,但它们仍然可以调用来自其他编译单元的函数。也就是说,如果当前编译单元向叶函数传递了一个回调函数指针,叶函数不应调用这个回调函数。这意味着叶函数只能调用来自其他编译单元的函数,不能调用当前编译单元中其他的函数。不能调用当前编译单元传递给它的回调函数,也不能调用当前编译单元中的函数;原创 2024-08-25 11:56:10 · 230 阅读 · 0 评论 -
gcc: pragma GCC diagnostic push
通过下面的方式,可以让gcc在部分代码上,不做-Wconversion的校验,也就不上报Warning,警告。但是这种还是有些风险,最好是不用。可以放到宏定义函数的外围。原创 2024-08-20 10:52:29 · 197 阅读 · 0 评论 -
gcc: string.c_str gcc-8.5的一个问题
string的这个成员是返回c类型的一个字符数组指针。但是这个指针所对应的地址有赖于string对象的生命周期。所以如果返回一个函数内的局部string对象的指针,就是危险的。如果是危险的有没有静态代码检查工具可用帮助来检查这种书写的问题。这里需要注意的一个问题是在gcc的4.8版本是可用隐藏这个问题,但是到了8.5这个版本,就不再隐藏了。所以对生命周期比较长的c++工程来说,这是一个非常大的挑战。因为原来这么错误使用也没有问题,那得有多少处这种错误使用呢?原创 2024-08-04 06:35:56 · 191 阅读 · 0 评论 -
gcc: -Q --help=optimizers;可以查看当前默认的优化选项;有变坑的潜力
根据文档看,实际的优化选项,会根据gcc的编译时配置来决定。也就是,如果特定的gcc版本,可能对应的优化选项的默认开关选择是不一样的。所以这也有可能是一个坑。原创 2024-07-14 22:04:25 · 134 阅读 · 0 评论 -
llvm: lldb: 为什么frame variable 不能将局部变量打印出来?dwp/-O/优化
和同事在看一个问题,说编译的envoy二进制文件,因为是使用了-gsplit-dwarf 选项,所以会将debug信息单独生成相应的dwo文件,而且envoy的项目里会将dwo打包称dwp文件。但是在单步调试的时候,就是不能将局部变量打印出来,使用的命令是:frame variable,没有任何输出。后来同事找到了下面的链接,看到符号的debug信息里少了局部变量的信息。中间还要穿插,envoy打包dwo,成dwp的过程。如果缺少必要的debug信息,这个debug的过程就是degraded。原创 2024-07-13 07:13:32 · 525 阅读 · 0 评论 -
gcc: options: -specs
编译器读取了file之后,处理这个文件,是为了覆盖默认的编译选项,这些选项会被gcc驱动传递给cc1/cc1plus/as/ld等程序。可以设置多个-specs文件,但是会根据顺序来处理,从左到右。gcc是一个驾驶员程序。由它控制下一步要执行哪一个编译/链接程序。所以在驱使其他程序的时候,都需要一个spec来指定这个程序应该怎么执行。n. 投机, 投机事业, 规格, 说明书, 专业人员。上面+号代表append到原有的cc1选项列表里。这个specs文件有一定的语法格式。原创 2024-07-10 06:39:40 · 274 阅读 · 0 评论 -
Linux: config: gcov GCOV_KERNEL
内核内嵌的gcov功能,默认是不打开。如果打开,同事需要enable debug_fs,然后才能查看相关的profile数据。第一次看到这个在内核里的功能。原创 2024-07-08 20:59:12 · 232 阅读 · 0 评论 -
gcc: 自身编译: opt;有个变量怎么找不到?
中间经过很多步骤,最终生成了一个options.h 文件。所以可以编译一个,找这个options.h,然后有一个直观的认识。所以下面这个变量的的定义可能是:global_options.x_warn_unused_function。原创 2024-07-06 06:25:38 · 508 阅读 · 0 评论 -
gcc: warning: -Wunused-function;加了选项,为什么就不报警告呢?
下面这个代码段,其中这个函数hton_ext_2byte,在整个程序里就没有使用。经过重新加选项-g编译gcc,使用gdb调试发现了原因。看了gcc的手册之后,其实是可以发现原因的;这就是clang和gcc之间的差异性了。上面这个 分析步骤有点复杂了。原创 2024-07-04 20:21:00 · 561 阅读 · 0 评论 -
C++: version `GLIBCXX_3.4.29‘ not found
通过strace看编译的过程发现了原因:编译sockper使用到的so文件时下面这个路径下的,这个路径下的so是之前自己build gcc的时候安装上去的。解决方法是,将这个目录下的so文件删除,重新编译sockperf。这就想不明白了,在同一个机器怎么可能能编译不能运行呢?原创 2024-06-20 14:41:50 · 282 阅读 · 0 评论 -
[开源软件] CCCoreLib;函数bool Delaunay2dMesh::buildMesh,为什么返回的是false
请参考网址。原创 2024-06-20 05:41:45 · 524 阅读 · 0 评论 -
gcc: attribute: 加constructor属性的函数不能有参数,undefined behavior
【代码】gcc: attribute: 加constructor属性的函数不能有参数,undefined behavior。原创 2024-06-12 06:29:28 · 333 阅读 · 0 评论 -
gcc: 使用新版本的问题
后来去了gcc的官网/bug系统,发现gcc的生命力非常旺盛,还在一直不断的进新的功能。当然带来的另一个问题就是regression的问题非常多,比如下面这个列表。最近遇到一个问题,发现一个功能在gcc 8.5】是好用的,到了11.4上之后,这个功能不好使了。这种问题怎么debug好呢?第一步是要去gcc的bug系统先搜一下(英语的重要性就来了)。上面这个列表就有121个bug被fix。其中很多是regression问题。所以开源软件选择新版本的时候还是要慎重,最好是经过社区的长时soak之后。原创 2024-06-11 05:28:04 · 660 阅读 · 0 评论 -
gcc:coverage:gcda文件没有生成的另一个例子:dlopen
如果是使用dlopen的方式来打开一个函数,需要记录coverage的数据,就需要使用下面这个链接。原创 2024-06-09 09:33:02 · 216 阅读 · 0 评论 -
gcc: coverage: gcda文件没有生成另一例:so文件调用__gcov_dump
那么会造成一个问题,如果想通过so中的某个函数调用gcov_do_dump,会调用so内部的。所以导致某些gcda文件生成不出来。这个时候主程序也是有用–coverage编译链接,那么也会含有一套这个函数。原因是gcc提供的libgcov库是一个静态库。这个so文件里带有gcov需要的很多函数/全局变量(符号),包括gcov_dump,gcov_var,。所以要避免这种方式,最好是不要在so文件里有这些gcov的函数定义。如果使用gcc --coverage选项编译出一个so文件。原创 2024-06-08 06:23:55 · 725 阅读 · 0 评论 -
gcc: coverage: gcda 文件没有生成的问题,又一例,问题被复杂化了
看到现在,发现有一个环境变量可以将gcov程序里的错误打印出来。最近再调试gcda文件没有生成的一个问题,感觉把问题复杂话了。如果将错误打印出来,问题分析就简单了。原创 2024-06-07 10:31:48 · 820 阅读 · 0 评论 -
[晕事]今天做了件晕事36 函数A明明调用了B,但是在汇编里却找不到,static优化
这个迷惑的原因是,gcc的优化对dump_one_gcov这个函数调用进行优化。因为这个函数 静态的,而且只被一个地方调用。gcc会将dump_one_gcov做inline处理,可以省去函数调用的过程,也算是一个优化。最近看gcov的一个问题,在分析二进制文件和源代码的时候发现,这个函数体明明不是很大,但是汇编内容确实巨量。占到~5000个字节。而且这里明明调用了dump_one_gcov,却找不到相关的汇编代码。这个时候还是会纳闷,怎么回事?原创 2024-06-06 04:47:16 · 190 阅读 · 0 评论 -
gcc: gsplit-dwarf 后在gdb里遇到的一个问题:如何dwo文件加载
这个时候如果想使用gdb调试程序,gdb的策略是lazy方式加载dwo文件,而且根据indirect(间接)的路径去找dwo文件,如果找不到,就会导致有些变量打印不出来。需要让gdb自己能通过间接路径找到dwo文件。假如使用了gsplit-dwarf选项,而且选择输出dwarf调试信息,这个时候,为了减小可执行文件的大小。链接器会将dwarf的调试信息,单独放到一个新文件里,后缀是dwo。这个时候还不能使用symbol-file/file加载dwo文件。现在还没找到别的好办法。原创 2024-05-17 20:14:59 · 401 阅读 · 0 评论 -
coredump-x: sanitizer编译出现segmentfault
如果是使用多个sanitizer的功能,比如lsan,asan,ubsan同时使用的时候,就会出现这个错误。看着更像是这三个里面的符号可能有冲突,导致符号的地址出现异常。从上面两个链接,看着已经解决了,需要使用新版本的gcc。原创 2024-04-15 13:08:31 · 189 阅读 · 0 评论 -
c/c++: warning变量未初始化的一个workaround:uninitialized_var
【代码】c/c++: warning变量未初始化的一个workaround:uninitialized_var。原创 2024-02-26 20:15:20 · 193 阅读 · 0 评论 -
Linux: dev: gcc: plugin: annobin
这个的功能是记录一些编译信息在二进制文件里,stip的时候,不会被strip掉,同时也不会被加载到运行时的内存里。方便查看编译信息,有利于问题分析。原创 2023-12-31 21:18:26 · 643 阅读 · 0 评论 -
Linux: dev: gcc: --coverage 迷惑行为最终生成不了gcda文件?
最近和同事看一个问题,就是虽然将所需的选项–coverage加到了产品的编译环境里,但是还是没有生成所希望的文件。而且自己写小程序来验证这个选项,也是没问题,可以产生程序运行时的代码覆盖率统计文件。这两的主要区别就是少了.init_array后面的通配符。那接下来就是要看到底是什么样的改动影响了这个行为。那问题出现到了哪里呢?后来同事经过查看一个链接脚本的更改记录,发现是链接脚本里的改动影响了这个行为。最终导致文件产生不了。原创 2023-12-29 13:43:54 · 1569 阅读 · 0 评论 -
Linux: dev: gcc: gcoverage;代码运行时的覆盖率
前些天写到gcc的instrument,https://mzhan017.blog.csdn.net/article/details/135098562;今天看到这个就是属于这一类,查看代码运行时的覆盖率的功能。可以帮助查看代码运行时的覆盖率需要编译时带上 --coverage选项加上这个之后,gcc编译时就会添加一些全局计数,比如下面的汇编。从文档里看,需要将优化选项去掉,不然有些优化可能导致统计问题。原创 2023-12-28 20:35:09 · 652 阅读 · 0 评论 -
Linux: dev: gcc: Instrumentation 程序的检测仪表/手段
Instrumentation的解释:https://mzhan017.blog.csdn.net/article/details/131621575最近从GCC的文档看到这个说明。其实也可以说明,任何一项技术使用的频率上来之后,大家就会想着如何检测产出的的优劣,为改进提供数据基础。这个程序检测手段也是相同的概念。说GCC可以帮助程序开发者,做一些程序底层的统计分析,比如代码的覆盖率是否完备,哪些代码是运行时的热点等等。当然如果程序员需要其他类似的检测,也可以自己创新出来一个。原创 2023-12-20 06:50:09 · 1126 阅读 · 0 评论 -
[英语单词] intrinsic
其实计算机中也有英语这个单词,讲述的是直接从C语言里,来访问汇编的裸指令(是相对于高级语言C来说的,其下层CPU机器指令),有一个内部,内在的意思;#endifAll of them generate the machine instruction that is part of the name. 这一句话应该添加一个例子,比如xsaveopt。意思就是这两个函数会生成机器指令,这个机器指令是builtin函数的一部分。那如何表达呢?原创 2023-12-13 15:40:19 · 966 阅读 · 0 评论 -
Coredump-X: 假如delete/free一个栈上的变量Wfree-nonheap-object;Wmismatched-new-delete
因为这个栈上内存,没有经过malloc函数的赋型,导致后续free的时候,做检查的时候就通不过,会报错误:munmap_chunk(): invalid pointer。同时会出现SegV(gdb) bt(gdb) c(gdb) bt(gdb) f 5(gdb) p &a。原创 2023-11-14 20:41:55 · 189 阅读 · 0 评论 -
c/c++: 空语句检查;消耗掉空语句分号
这里的疑问就是,这里的问题关键是“The presence of two statements—the compound statement and a null statement—in between the if condition and the else makes invalid C code. ” 空语句和其他语句一块被解释成了多语句,导致if的简写方式出现问题。这种不能消除对于分号的影响。在定义宏的时候,可能会加大括号,此时如果在使用宏的语句后面习惯性的加分号,就可能导致一个空语句的出现。原创 2023-11-05 03:40:40 · 249 阅读 · 0 评论 -
gcc: __linux__
这里可能有的疑问是为什么不直接使用__linux__ 作为判断,非得再来一个新的宏符号?实例是:googletest里有用这个。判断gcc在什么平台的一个方法。原创 2023-11-04 16:03:44 · 283 阅读 · 0 评论 -
gcc: O2编译选项 可以掩盖的一种coredump情况
有时候会决定将其删除。比如:析构函数里的对对象成员的赋值,因为对象都要被析构了,赋值没有意义,就会将赋值语句从实际的二进制文件里去掉。有些代码,如果选择O2选项的话,GCC会认为代码无用,或者根本不会产生任何数据上的变更,没有意义。而不带-O2选项的编译结果,可能会出现一种coredump。这个时候,如果赋值语句如果有问题,就会被O2选项给掩盖掉。原创 2023-10-30 13:44:35 · 297 阅读 · 0 评论 -
gcc: 优化选项:fdevirtualize,polymorphic; inline;
在实际使用中,开发人员可以使用一些编译器标志或注释来提示编译器进行 devirtualization 优化,但这通常需要谨慎的选择和测试,以确保不会引入不正确的行为。在C++中,虚拟函数是通过基类指针或引用来调用的,因此在运行时需要进行动态分发,查找相应的派生类函数。使用 -fdevirtualize 选项,编译器会尝试根据可用的信息来确定是否可以内联虚函数的调用,以提高程序的性能。总之,-fdevirtualize 选项是一种用于内联虚函数调用的编译器选项,而不是一种通用的虚拟函数优化选项。原创 2023-10-27 20:40:01 · 223 阅读 · 0 评论 -
gcc: -O2 优化选项的一个副作用:可以掩盖链接,符号未定义错误 undefined reference to
所以看问题时,需要注意这一点,如果用-O2 编译链接工程,没有问题。并不一定代表去掉 -O2 就可以链接成功。同时如果A函数是个死函数的话,-O2,可能将这个函数A优化为如下的方式,直接返回。看似从未调用这个函数。这个-O2 优化选项,可以掩盖链接错误。因为这个包含130多项的优化选项。里面有关于四代码的优化。假如一个函数A里调用了另一个函数B,但是函数B是外部定义的符号,而且没有定义。原创 2023-10-27 07:47:57 · 566 阅读 · 0 评论 -
[晕事]今天做了件晕事26;gcc对strcmp/strncmp的优化
比如,后面期望通过nm可以查到foo符号的定义及地址。再后来使用disass main之后,发现,main函数的汇编非常的短,就下面两个指令。这里需要提一下,编译的时候使用了-O2。这里可以看到编译器进行了非常大的优化。今天做了一件晕事,写了一个测试小程序,开头的程序例如下面片段。在后续又写了一些代码,进行编译,使用gdb查看可执行文件,怎么都得不到想要的结果,非常的纳闷,非常的奇怪。gcc编译器在编译时,已经判定 strncmp函数调用有问题,直接给了一个ud2的指令,这其实不方便问题的调试。原创 2023-10-25 20:59:13 · 236 阅读 · 0 评论