GCC编译器原理(一)03------GCC 工具:gprof、ld、libbfd、libiberty 和libopcodes

发布者:EternalSunset最新更新时间:2024-08-22 来源: cnblogs关键字:GCC编译器  GCC  工具 手机看文章 扫描二维码
随时随地手机看文章

1.3.7 gprof:性能分析工具

gprof是GNU profile工具,可以运行于linux、AIX、Sun等操作系统进行C、C++、Pascal、Fortran程序的性能分析,用于程序的性能优化以及程序瓶颈问题的查找和解决。通过分析应用程序运行时产生的 'flat profile',可以得到每个函数的调用次数,每个函数消耗的处理器时间,也可以得到函数的 '调用关系图' ,包括函数调用的层次关系,每个函数调用花费了多少时间。

  • Gprof具有以下优缺点:

    • 需要编译选项支持:

    • 调试多线程程序只能统计主线程的信息(所以不能用于 kingbase)。

    • 例如:gcc -pg -o test test.cpp ,编译器会自动在目标代码中插入用于性能测试的代码片断,这些代码在程序运行时采集并记录函数的调用关系和调用次数,并记录函数自身执行时间和被调用函数的执行时间。

    • 执行编译后的可执行程序,如:./test。该步骤运行程序的时间会稍慢于正常编译的可执行程序的运行时间。程序运行结束后,会在程序所在路径下生成一个缺省文件名为 gmon.out 的文件,这个文件就是记录程序运行的性能、调用关系、调用次数等信息的数据文件。

    • 使用 gprof 命令来分析记录程序运行信息的 gmon.out 文件,如:gprof test gmon.out 则可以在显示器上看到函数调用相关的统计、分析信息。上述信息也可以采用 gprof test gmon.out > gprofresult.txt 重定向到文本文件以便于后续分析。

    • 使用 gcc/cc 或 g++ 编译和链接时需要加入 -pg 选项;

    • 使用 ld 链接时需要用 /lib/gcrt0.o 代替 crt0.o 作为第一个 input 文件

    • 如果要调试 libc 库需要使用 -lc_p代替 -lc 参数

    • GNU工具,人手一个;

    • 混合方法采集信息。

    • 优点:

    • 缺点:

命令行选项如下:

选项

描述

-b

不再输出统计图表中每个字段的详细描述。

-q

只输出函数的调用图(Call graph的那部分信息)。

-p

只输出函数的时间消耗列表。

-e Name

不再输出函数 Name 及其子函数的调用图(除非它们有未被限制的其它父函数)。可以给定多个 -e 标志。一个 -e 标志只能指定一个函数。

-E Name

不再输出函数 Name 及其子函数的调用图,此标志类似于 -e 标志,但它在总时间和百分比时间的计算中排除了由函数 Name 及其子函数所用的时间。

-f Name

输出函数 Name 及其子函数的调用图。可以指定多个 -f 标志。一个 -f 标志只能指定一个函数。

-F Name

输出函数 Name 及其子函数的调用图,它类似于 -f 标志,但它在总时间和百分比时间计算中仅使用所打印的例程的时间。可以指定多个 -F 标志。一个 -F 标志只能指定一个函数。-F 标志覆盖 -E 标志。

-z

显示使用次数为零的例程(按照调用计数和累积时间计算)。

例子:

 1 #include

 2 #include

 3 int a(void)

 4 {

 5     int i=0,g=0;

 6     while(i++ < 100000)

 7     {

 8         g+=i;

 9     }

10     

11     return g;

12 }

13 

14 int b(void)

15 {

16     int i=0,g=0;

17     

18     while(i++ < 400000)

19     {

20         g +=i;

21     }

22     

23     return g;

24 }

25 

26 int main(int argc, char** argv)

27 {

28     int iterations;

29     

30     if(argc != 2)

31     {

32         printf('Usage %s n', argv[0]);

33         exit(-1);

34     }

35     else

36         iterations = atoi(argv[1]);

37     printf('No of iterations = %dn', iterations);

38     

39     while(iterations--)

40     {

41         a();

42         b();

43     }

44 }

 

应用程序包括两个函数:a 和 b,它们通过运行不同次数的循环来消耗不同的CPU时间。

main 函数中采用了一个循环来反复调用这两个函数。函数 b 中循环的次数是 a 函数的 4 倍,因此我们期望通过 gprof 的分析结果可以观察到大概有 20% 的时间花在了 a 函数中,而 80% 的时间花在了 b 函数中。

编译程序:gcc test.c -pg -o test -O2 -lc

运行并传入参数:./test 50000

程序运行完之后,会在目录下生成一个 gmon.out 文件:

使用 gprof 命令分析分析 gmon.out 文件gprof test gmon.out -p

程序运行时间太短,所以 gprof 无效,若是大程序即可使用此来分析。

上面那些参数得含义如下:

名称

含义

%time

函数以及衍生函数(函数内部再次调用的子函数)所占的总运行时间的百分比

cumulative seconds

函数累计执行的时间

self seconds

函数执行占用的时间

calls

函数的调用次数

self ms/call

每一次调用函数花费的时间microseconds,不包括衍生函数的运行时间

total ms/call

每一次调用函数花费的时间microseconds,包括衍生函数的运行时间

name

函数名称

 

1.3.8 ld:GNU 链接器

ld 是 GNU 工具链中的一个软件,主要用于将 obj 文件链接成可执行文件。同时可以使用自己的脚本来控制 ld 的行为,可以通过 -T 选项选择自己的脚本而不是默认的。

选项

描述

-static

静态链接

-l

指定链接某个库

-e name

指定 name 为程序入口

-r

合并目标文件,不进行最终链接

-L

指定链接时查找路径,多个路径之间用冒号隔开

-M

将链接时的符号和地址输出成一个映射文件

-o

指定输出的文件名

-s

清除输出文件中的符号信息

-shared

链接器生成一个 Linux 上使用的动态库

-S

清除输出文件中的调试信息

-T

指定链接脚本文件

-Ttext

指定 text 段的地址

-version-script

指定符号版本脚本文件

-soname

指定输出动态库的 SONAME

-export-dynamic

将全局符号全部导出

-verbose

链接时输出详细信息

-rpath

指定链接时库查找路径

--help

查看链接器的帮助信息

1.3.9 libbfd:二进制文件描述器

libbfd 工具不会在安装 binutils 的时候自动安装,需要在 binutils 安装包的 bfd 文件夹下单独安装。

在安装完 binutils 工具之后就可以看到此工具。安装完成后,会生成如下文件:

  • /usr/local/include/bfd.h

  • /usr/local/lib/libbfd.a

可以利用此工具获取 elf 可执行文件的 section(节) 及 symbol(符号) 信息。

使用此工具需要注意的地方:

  1. 头文件包含

    1. 采用GNU autotools的项目,在编译前一般都会执行一下 configure 脚本,生成 Makefile 及 config.h文 件。

    2. 对于没有使用 GNU autotools 的应用,可以采用如下格式得到 config.h 文件,这个文件的内容,相当于是使用 GNU autotools 开发一个 hello world 项目而得到的 config.h,下面就是 config.h 文件的模板

    3. 程序使用bfd,需要包含bfd.h头文件。但是,在包含 bfd.h 之前,还需要包含 config.h。即代码中需要有如下形式的文件包含:

    4.     #include 'config.h'
          #include 

    5. config.h 不是系统的头文件,也不是bfd库的头文件,而是应用程序自己的头文件。

 

 1 /* config.h.  Generated from config.h.in by configure.  */

 2 /* config.h.in.  Generated from configure.ac by autoheader.  */

 3      

 4 /* Name of package */

 5 #define PACKAGE 'hello'

 6      

 7 /* Define to the address where bug reports for this package should be sent. */

 8 #define PACKAGE_BUGREPORT 'bug-report@address'

 9      

10 /* Define to the full name of this package. */

11 #define PACKAGE_NAME 'hello'

12      

13 /* Define to the full name and version of this package. */

14 #define PACKAGE_STRING 'hello 1.0'

15      

16 /* Define to the one symbol short name of this package. */

17 #define PACKAGE_TARNAME 'hello'

18      

19 /* Define to the home page for this package. */

20 #define PACKAGE_URL ''

21      

22 /* Define to the version of this package. */

23 #define PACKAGE_VERSION '1.0'

24      

25 /* Version number of package */

26 #define VERSION '1.0'


  1. 链接

    1. 链接的时候需要带上这几个库:bfd iberty dl z

    2. 例如,假设 hello.c 是一个完整的使用 bfd 库的程序,则他的编译方法如:gcc hello.c -lbfd -liberty -ldl -lz

例子如下:

 1 #include

 2 #include

 3 #include 'config.h'

 4 #include

 5 #include

 6 #include

 7 #include

 8 #include

 9  

10 /* 

11    这里定义 3 个 static 变量,并把他们放到一个单独的 section 中。

12    后面,我们通过 bfd 找出这个 section,并得到这 3 个变量的内容。

13    同时,我们还通过符号查找操作,找到 a_haha 这个 static 变量的信息。

14 */

15 static uint64_t  a_haha   __attribute__((section ('my_test_sec'))) =3;

16 static uint64_t  b        __attribute__((section ('my_test_sec'))) =7;

17 static uint64_t  c        __attribute__((section ('my_test_sec'))) =8;

18  

19 /* 获取当前进程自己的elf文件路径 */

20 int get_self_path(char *buf, int buf_len)

21 {

22     int ret = readlink('/proc/self/exe', buf, buf_len);

23     buf[ret]='';

24     return ret; 

25 }

26  

27 void section_proc(bfd *abfd,  asection *sect, PTR obj)

28 {

29     if (strcmp(sect->name, 'my_test_sec')==0)

30         printf('section %s existsn', sect->name);

31 }

32  

33 void search_a_given_symbol(bfd *ibfd, const char *name)

34 {

35          long storage_needed;

36          asymbol **symbol_table;

37          long number_of_symbols;

38          long i;

39          symbol_info symbolinfo ;

40  

41          storage_needed = bfd_get_symtab_upper_bound(ibfd);

42  

43          symbol_table =  (void *)(unsigned long)malloc(storage_needed);

44          number_of_symbols =  bfd_canonicalize_symtab (ibfd, symbol_table);

45  

46         printf('Scanning %ld symbolsn', number_of_symbols);

47         for(i=0;i48         {

49                 if (symbol_table[i]->section==NULL) continue;

50                 

51                 bfd_symbol_info(symbol_table[i], &symbolinfo);

52                 if (strcmp(name, symbolinfo.name))  continue;

53  

54                 printf('Section %s  ', symbol_table[i]->section->name);

55                 printf('Symbol '%s'  value 0x%lxn', symbolinfo.name, symbolinfo.value);

56         }

57 }

58  

59 int main()

60 {

61     char our_self_path[1024];

62     bfd *ibfd;

63     char **matching;

64  

65     asection *psection;

66  

67     bfd_init();

68  

69     get_self_path(our_self_path, sizeof(our_self_path));

70     printf('our elf file path:%sn', our_self_path);

71  

72     ibfd = bfd_openr(our_self_path, NULL);

73     bfd_check_format_matches(ibfd, bfd_object, &matching);

74  

75     printf('number of sections = %dn', bfd_count_sections(ibfd));

76  

77     /* 遍历所有 section,让 section_proc 对每一个 section 进行处理 */

78     bfd_map_over_sections(ibfd, section_proc, NULL);

79  

80     /* 查找特定名称的 section ,打印出其信息 */

81     psection = bfd_get_section_by_name(ibfd, 'my_test_sec');

82     printf('section name=%s; start_address=0x%lx; size=%ldn', psection->name, psection->vma, psection->size);

83  

84     /* 打印出my_test_sec section中的 3 个 uint64_t 变量的值 */

85     {

86         uint64_t *pu64 = (void *) psection->vma;

87         printf('%lu %lu %lu n', pu64[0], pu64[1], pu64[2]);

88     }

89  

90     printf('address of a_haha=%pn', &a_haha);

91  

92     /* 遍历所有符号,以找出名称为 a_haha 的符号 */

93     search_a_given_symbol(ibfd, 'a_haha');

94     return 0;

95 }

 

编译:gcc test.c -lbfd -liberty -ldl -lz

执行如下:

1.3.11 libiberty

包含多个 GNU 程序会使用的途径,包括 getopt、obstack、strerror、strtol 和 strtoul。

[1] [2]
关键字:GCC编译器  GCC  工具 引用地址:GCC编译器原理(一)03------GCC 工具:gprof、ld、libbfd、libiberty 和libopcodes

上一篇:GCC编译器原理(一)04------GCC 工具:nlmconv、nm、objcopy、objdump和 ranlib
下一篇:ARM裸机开发:按键输入实验

推荐阅读最新更新时间:2024-11-12 13:17

STM32F103入门 | 4.Keil 5主窗口工具栏概述
4.1 前言 为了让小伙伴们更快速地上手Keil MDK-ARM V5,本文先让小伙伴们简单了解一下Keil的主窗口界面以及工具栏。之所以有工具栏,是因为有些快捷按钮在编程开发时使用频率较高,所以为了方便使用者使用,就把某些常用的快捷按钮归结在一起,于是就出现了工具栏。 本文主要讲解Keil MDK-ARM V5 的工具栏,Keil系列其他版本也同样适用。 4.2 主窗口界面 为了让小伙伴对Keil集成开发环境有个大概的了解,首先给小伙伴讲述一下Keil默认编辑模式主窗口下的各个小窗口的内容。 主窗口如下图 菜单栏(Menu Bar) 菜单栏跟我们使用的其他软件非常类似,包含File文件、Edit编辑
[单片机]
STM32F103入门 | 4.Keil 5主窗口<font color='red'>和</font><font color='red'>工具</font>栏概述
安全专家演示将智能电视变成监控工具
    NCC Group演示用内部存储器记录30秒钟的会话,会话记录时间可以更长,30秒钟只是用于演示目的。更先进的恶意攻击可以在本地储存长时间的会话记录,然 后再定时上传数据,或者也直接将监听的数据流上传到一台服务器,绕过本地储存。前NSA合同工Edward Snowden在香港期间见律师时都要求将手机放到冰箱里以防止监听。新的研究暗示他可能还需要担心附近的电视。
[安防电子]
STM32 + GCC + J-Link :开源的力量
发现Keil自带的编译器有时候优化有问题,跑得跟没优化时完全不一样。以前使用GCC,现在自然而然想再次使用GCC。 搭配1:Keil+GCC+Ulink2 这类的介绍也较多,主要是一个链接脚本、启动代码、IDE选项配置的问题,大家可以google一下,个人觉得搭配一般般。 搭配2:emIDE+JLink 纯粹的Opensource血统,这个EMIDE已经带了GCC,只需要一个JLink,然后构建好工程就可以debug了,如果发展迅猛,估计Keil也会扛不住了。
[单片机]
arm-linux-gcc的安装
在X86电脑上开发的程序要在ARM系统上运行就必须使用交叉工具链arm-linux-gcc,linux系统上是没有这个工具链的,为此必须自己下载安装,安装步骤为: 1、网上下载个压缩包arm-linux-gcc,这个压缩包网上有很多,版本也有很多,我下载的是arm-linux-gcc-4.4.3-20100728.tar.gz 2、 解压arm-linux-gcc-4.4.3-20100728.tar.gz   #tar -zxvf arm-linux-gcc-4.4.3-20100728.tar.gz -C / 注意:tar命令默认解压缩文件到压缩文件所在的目录下,后面加-C和目录名表示将压缩文件压缩到指定的目录下
[单片机]
奇捷科技厚积薄发,国产EDA企业怎么凭ECO工具逆袭?
在国家的高度重视和国内EDA企业的努力下,长期处于“卡脖子”困境的国产EDA局面有了新的形势变化。 作为芯片设计最上游、最高端的产业,EDA被誉为“芯片之母”,其重要性不言而喻。然而,如此重要的环节却也正是国内芯片产业链最为薄弱的环节。数据显示,EDA工具的国产替代率仅为5%,国产数字芯片EDA工具仅能覆盖全EDA流程的10%。 据了解,国内专注于EDA前端技术,尤其是逻辑层的公司更是少之又少。而国产EDA企业奇捷科技凭借其在形式验证和逻辑综合方面扎实的技术积累,顺势推出Easy ECO工具,打破了国际壁垒,实现国产新突破。 技术深厚 连拿三年ICCAD竞赛冠军 奇捷科技由香港中文大学(CUHK)计算机科学与工程系(CSE)的教授
[手机便携]
谷歌推出阿尔法围棋工具帮助人类提高围棋水平
据消息,由聂卫平围棋道场和谷歌联合推出的“寻找围棋小先锋”活动,在上海世博园万国体育馆举行。聂卫平道场创始人、围棋九段聂卫平先生、谷歌CEO桑达尔·皮查伊先生和谷歌大中华区总裁石博盟先生参加了此次发布会。 如此高规格的嘉宾阵容,足以见得谷歌方面和聂卫平对此次围棋青少年大赛极高的重视程度。 聂卫平和皮查伊 谷歌CEO桑达尔·皮查伊先生 皮查伊在现场讲到:“全国4-18岁的青少年儿童都可以参加此次业余公开挑战赛,获胜者将有机会和全球高手对弈,比赛将在北京进行。谷歌将提供能支持超200名参赛者来参赛的奖学金,以示支持。” 此时,不忘给谷歌打广告的皮查伊先生公布,阿法狗围棋教学(Alpha
[机器人]
号称未来交通工具问世,会飞的摩托当真安全?
据英国媒体报道,下列一组照片是全球首个载人飞行摩托,可由乘客像骑摩托车般驾驶航行。该飞行摩托有望成为未来主要交通工具。         制造商Hoversurf制造的此架单座飞行器天蝎Ⅲ(Scorpion-3),可搭载一名乘客飞行,并完全由其操纵。该设备融合常规摩托设计与 无人机 技术。乘客可在天空中像骑自行车般操纵它。         制造商介绍说,天蝎Ⅲ可承重约133公斤,时速最高达48千米,飞行高度可达10米,可在空中连续飞行27分钟。该飞行摩托售价15万美元。为安全飞行,该飞行摩托内置安全机制以限制最高时速及飞行高度。         制造商欲向业余爱好者及专业驾驶员推广 飞行摩托车 。尽管飞行摩托目前被视为极限
[嵌入式]
送餐机器人 从噱头到工具
2019年12月29日,普渡科技举办“再一次普渡”新品发布会,首次对外公开两款全新的餐饮机器人:送餐机器人“贝拉BellaBot”与回盘机器人“好啦HolaBot”。 成立于2016年1月的普渡科技已经成为了国内领先的室内智能配送机器人企业,2019年其研发的送餐机器人已出货超过5000台,覆盖全球超过20个国家的200余城市的2000多家不同品类的餐厅。 噱头or工具 普渡科技创始人兼CEO张涛在发布会上表示:“ 机器人最重要的技术点有三个,一是移动,包括机器人的自主定位导航,二是操作,也就是机械臂的作业,三是智能交互 。” 因此普渡科技在创业初期,便将底层技术聚焦到了机器人的自主移动上,之所以选择送餐机器人作为切入点,则是
[机器人]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved