快速学习C语言二: 编译自动化, 静态分析, 单元测试,coredump调试,性能剖析

上次的Hello world算是入门了,现在学习一些相关工具的使用

写好程序,首先要编译,就用gcc就好了,基本用法如下

helloworld.c是源码,helloworld.o是编译后的可执行文件,运行的话就用 ./helloworld.o就可以了。

但是如果代码写的多了,每次改动完都手动用gcc编译太麻烦了,所以要用Makefile来 自动化这项工作,在当前目录下创建Makefile文件,大概如下

缩进为0每一行表示一个任务,冒号左边的是目标文件名,冒号后面是生成该目标的依赖 文件,多个的话用逗号隔开,如果依赖文件没有更改,则不会执行该任务。

缩进为1的行表示任务具体执行的shell语句了,.PHONY修饰的目标表示不管依赖文件 有没有更改,都执行该任务。

执行对应的任务的话,就是在终端上输入 make 目标名,如 make lint表示源码检查, make clean表示清理文件,如果只输入make,则执行第一个目标,对于上面的文件就 是生成helloworld.o了。

现在修改完源码,值需要输入一个make回车就行了,Makefile很强大,可以做很多自动化 的任务,甚至测试,部署,生成文档等都可以用Makefile来自动化,有点像前端的 Grunt和Java里的ant,这样就比较好理解了。

静态检查可以帮你提前找出不少潜在问题来,经典的静态检查工具就是lint,具体到 Linux上就是splint了,可以用yum来安装上。

具体使用的话就是 splint helloworld.c就行了,它会给出检查出来的警告和错误,还 提供了行号,让你能很快速的修复。

值得注意的是该工具不支持c99语法,所以写代码时需要注意一些地方,比如函数里声明 变量要放在函数的开始,不能就近声明,否则splint会报parse error。

静态检查工具最好不要忽略warning,但是有一些警告莫名其妙,我看不懂,所以还是 忽略了一些,在使用中我加上了 -temptrans -mustfreefresh -usedef这几个参数。

安装CUnit

了解下单元测试的概念: 一次测试(registry)可以分成多个suit,一个suit里可以有多个 test case, 每个suit有个setup和teardown函数,分别在执行suit之前或之后调用。

下面的代码是一个单元测试的架子,这里测试的是库函数strlen,这里面只有一个suit, 就是testSuite1,testSuit1里里有一特test case,就是testcase,testcase里有一个 测试,就是test_string_length。

整体上就是这么一个架子,suit,test case, test都可以往里扩展。

然后Makefile里增加如下代码

再执行make test就可以执行单元测试了,结果大约如下

可以看到testSuite1下面的test_for_lenth通过测试了。 注意一下,安装完新的动态库后记得ldconfig,否则-l cunit可能会报错 如果还是不行就要 /etc/ld.so.conf 看看有没有 /usr/local/lib , cunit默认把库都放这里了。

就上面的单元测试, 如果使用注释掉那行,执行make test时就会产生coredump。如下

但默认coredump不会保存在磁盘上,需要执 ulimit -c unlimited才可以,然后要 指定一下coredump的路径和格式:

其中%e是可执行文件名,%p是进程id。然后编译这段代码的时候要加上-g的选项,意思 是编译出调试版本的可执行文件,在调试的时候可以看到行号。

在执行./test.o后就会产生一个coredump了,比如是/tmp/core-test.o-16793, 这时候 用gdb去调试该coredump,第一个参数是可执行文件,第二个参数是coredump文件

挂上去后默认会有一些输出,其中有如下

说明程序遇到了段错误,崩溃了,一般段错误都是因为内存访问引起的, 我们想知道 引起错误的调用栈, 输入bt回车,会看到类似如下的显示

这样大概知道是咋回事了,报错在testcase.c的46行上,再往里就是cunit的调用栈了, 我们看不到行号,好像得有那个so的调试信息才可以,目前还不会在gdb里动态挂符号文件 ,所以就先不管了,输入q退出调试器,其它命令用输入help学习下。

就调用了一个CU_register_suites函数,函数本身应该没有错误,可能是传给他从参数 有问题,就是那个suites,该参数构建的代码如下:

是个CU_SuiteInfo的数组,就感觉是构建这个类型没构建对,然后就看他在哪儿定义 的

在/usr/local/include/CUnit/TestDB.h的696行,具体如下

可以看到,该结构有6个成员,但我们定义的时候只有4个成员,没有设置pSetUpFunc和 pTearDownFunc的,所以做如下修改就能修复该问题了。

对了,gdb用yum安装就行了。

好些时候我们要去分析一个程序的性能,比如哪个函数调用了多少次,被谁调用了, 平均每次调用花费多少时间等。这时候要用gprof,gprof是分析profile输出的。 要想执行时输出profile文件编译时要加-pg选项,

执行上面语句后会在当前目录下生成gmon.out文件, 然后用gprof去读取并显示出来, 因为可能显示的比较长,所以可以先重定向到一个文件prof_info.txt里

参数的含义先这么用,具体可以搜,最后查看prof_info.txt里会有需要的信息, 大概 能看懂,具体可以搜。

Original: https://www.cnblogs.com/onlytiancai/p/3847524.html
Author: 蛙蛙王子
Title: 快速学习C语言二: 编译自动化, 静态分析, 单元测试,coredump调试,性能剖析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/536371/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • C语言:stat,fstat和lstat函数

    这三个函数的功能是一致的,都用于获取文件相关信息,但应用于不同的文件对象。对于函数中给出pathname参数,stat函数返回与此命名文件有关的信息结构,fstat函数获取已在描述…

    C语言 2023年5月29日
    070
  • JavaSE assert断言的学习

    在Java中,assert关键字是从JAVA SE 1.4 引入的,为了避免和老版本的Java代码中使用了assert关键字导致错误,Java在执行的时候默认是不启动断言检查的(这…

    C语言 2023年5月29日
    058
  • C语言初学者代码中的常见错误与瑕疵(22)

    posted @2015-02-06 22:17 garbageMan 阅读(666 ) 评论() 编辑 Original: https://www.cnblogs.com/pme…

    C语言 2023年5月29日
    076
  • 项目检出JRE问题(Unbound classpath container: ‘JRE System Library [JavaSE-1.7]’ in project ‘idweb’)

    项目从SVN检出到工作空间后报了很多错误,其中很明显就是一些jar的问题,没有相关的jar或版本问题,看到最后的错误Unbound classpath container: &#8…

    C语言 2023年5月29日
    059
  • C语言:结构体和共用体

    这是很基础的教程,我只是写给自己看,作为一个学习笔记记录一下,如果正在阅读的你觉得简单,请不要批评,可以关掉选择离开 如何学好一门编程语言 掌握基础知识,为将来进一步学习打下良好的…

    C语言 2023年5月29日
    0100
  • 拓扑排序(一)之 C语言详解

    拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列。 这样说,可能理解…

    C语言 2023年5月29日
    059
  • Prim算法(一)之 C语言详解

    普里姆(Prim)算法,和克鲁斯卡尔算法一样,是用来求加权连通图的最小生成树的算法。 基本思想对于图G而言,V是所有顶点的集合;现在,设置两个新的集合U和T,其中U用于存放G的最小…

    C语言 2023年5月29日
    067
  • 互联网世界中的C语言——我的golang学习笔记:1(基础语法快速过)

    wangyishuaideMacBook-Pro:goStu wangyishuai$ rm hello wangyishuaideMacBook-Pro:goStu wangyi…

    C语言 2023年5月29日
    087
  • C语言getopt()的8个用法

    概况 例子1 例子2 例子3 例子4 例子5 例子6 例子7 例子8 概况 做 CSAPP 的 CacheLab 的第一个门槛是学习使用 getopt() 函数。它是 Linux …

    C语言 2023年5月29日
    079
  • 最值得学习阅读的10个C语言开源项目代码

    Webbench Webbench是一个在linux下使用的非常简单的网站压测工具。它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模…

    C语言 2023年5月29日
    070
  • C语言函数知识体系大学霸IT达人

    C语言函数知识体系大学霸IT达人 C语言中的函数会集成一条或多条命令(语句)用于实现指定的一个或多个功能。简单的可以将函数理解为一个工具,例如,锤子。锤子的功能是砸东西,木柄和锤头…

    C语言 2023年5月29日
    050
  • 一道C语言安全编码题目

    1、前言 最近在网上看到一道C语言题目,用C语言实现一个函数,给定一个int类型的整数,函数输出逆序的整数,例如输入123,则输出字符串”321″,,输入-…

    C语言 2023年5月29日
    053
  • 快速学习C语言四: 造轮子,ArrayList

    高级语言里的列表是最常用的数据结构,在C里造个轮子玩玩,C没有泛型,先用int练习。 Collection的ADT一般有hasnext,next,add, remove操作,Lis…

    C语言 2023年5月29日
    084
  • C语言实现粒子群算法(PSO)二

    上一回说了基本粒子群算法的实现,并且给出了C语言代码。这一篇主要讲解影响粒子群算法的一个重要参数—w。我们已经说过粒子群算法的核心的两个公式为: Vid(k+1)=wV…

    C语言 2023年5月29日
    051
  • C语言指针总结大学霸IT达人

    C语言指针总结大学霸IT达人 C语言的指针是C语言区别其它语言的最主要的特定之一。有了指针,C语言就可以抛开所有束缚,直接对内存中的数据进行操作,这样,不单对数据的操作更加快捷,并…

    C语言 2023年5月29日
    054
  • JavaSE 类继承中函数重写

    (1) /** * 继承时重写方法的返回类型可以不一样 * 这时的返回值类型必须是与父类相同或者为子类。 */ class A { public Object func(){ re…

    C语言 2023年5月29日
    068
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球