《系统程序员成长计划》阅读笔记--温故之用

《系统程序员成长计划》 下载页面

1.程序在数据存放位置
    1>.bbs 未初始化或者初始化为零的全局变量区 程序运行期间一直有效,占运行时的内存空间,不占目标文件的空间
    2>.data 初始化过的全局变量区 程序运行期间一直有效,既占运行时的内存空间,又占目标文件的空间
    3>.rodata (read only data)常量数据区 有些立即数会和指令编码在一起存放于.text
    4>.text 代码区 存放代码和部分整数常量
    5>stack 栈 存放临时变量和函数参数
    6>heap 堆 存放用户动态分配的内存 malloc realloc new

    检查内存泄露和缓冲区溢出的工具valgrind
    查看程序运行期间的内存的分配情况 cat /proc/self/maps

2.尽管C/C++通常是按值传递参数,而数组是例外,在传递数组参数时,数组退化为指针(即按引用传递),用sizeof无法取得数组大小
    void test( char str[20] ) {...};

3.对于函数内部有多个返回点(返回点需要释放内存或者锁)时,可以用do..while来实现类似goto的功能,在函数末尾统一释放

4.交叉编译是指在一个平台上编译另一个平台运行的程序,如./configure -host=arm-linux

5.automake用于工程管理,用户需要做的是在各个目录编写Makefile.am(am是automake的简称),然后按照流程走下去
  中途需要修改configure.in文件,把相应部分改成实际模块名称、版本号、邮箱、AM_INIT_AUTOMAKE语句
  configure.in文件内部是一系列的宏(系统内置宏),由m4(macro的简称,4表示后面省略四个字母)展开,aclocal命令把这些宏copy到我们的工程中去
  (看到这里才知道m4的真正作用,以前一直不清楚的 libtool是用来封装共享库在不同平台上差异的脚本,这个以前也不清楚)

    《系统程序员成长计划》page86
    helloword/src
    1.touch helloworld/Makefile.am (am是automake的简称,该文件是用来生成Makefile.in的模板)
      touch helleworld/Makefile.am
    2.cd helloworld
      autoscan
      -->helloworld/configure.scan
    3.mv helloworld/configure.scan helloworld/configure.in (autoconf的模板文件)
      该文件由宏组成,这些宏由m4(macro简称,类似于I18n->Internationalization和L10m->Localization)展开得到configure.configure探测系统配置,根据配置生产相应的Makefile.
      该文件需要作如下修改
      AC_INIT(helloworld,0.1,xx@xx.com) #该行是autoconf的初始化脚本
      AM_INIT_AUTOMAKE(helloworld,0.1) #该行是automake的初始化脚本\
    4.aclocal
      -->helloworld/autom4te.cache helloworld/aclocal.m4
      该命令把configure.in中所用到的宏全部拷贝到我们工程中来
    5.autoheader
      -->config.h.in
    6.touch README NEWS AUTHORS ChangeLog
    7.automake -a
      -->COPYING depcomp INSTALL install-sh missing Makefile.in
      automake以Makefile.am为模板产生Makefile.in
    8.autoconf
      -->configure
      autoconf调用m4展开configure.in中的宏,生成configure
    9../configure --prefix=xxx --host=arm-linux
      prefix指定安装目录,linux下默认是/usr/local
      host用于交叉编译,比如x86的PC机上编译在ARM板上运行的程序
    10.make
       编译
    11.make install
       安装
    12.make dist / make distcheck
       -->helloworld-0.1.tar.gz
       发布软件包

6.《系统程序员成长计划》Page93
    pkg-config
       负责查询指定软件报的配置信息,如软件包的名称、说明、版本号、头文件、库和以来关系==
       软件包需要提供一个后缀pc的配置文件.系统中的pkg-config配置文件通常放在/usr/lib/pkgconfig和/usr/local/lib/pkgconfig下.
       
    pc模板文件,helloworld/helloworld.pc.in:
        prefix=@prefix@
        exec_prefix=${prefix}
        libdir=${prefix}/lib
        includedir=${prefix}/include
        Name:@PACKAGE_NAME@
        Description: a basic library
        Version:@VERSION@
        Requires:
        Libs:-L${libdir} -lbase
        Cflags:-I${includedir}/base
    修改helloworld/Makefile.am,新增:
        pkgconfigdir=${libdir}/pkgconfig
        pkgconfig_DATA=helloworld.pc
    修改configure.in,新增:
        AC_OUTPUT([helloworld.pc])

    ./configure
    -->helloworld.pc
    
7.《POSA(面向模式的软件结构)》根据模式粒度把模式分为三类:架构模式,设计模式,惯用手法
    架构模式:分层模式 管道过滤器 微内核模式
    设计模式:代理模式 命令模式 出版-订阅模式
    惯用手法:引用计数 内存预分配

8.《系统程序员成长计划》Page108
    栈是向下增长的,栈顶是低地址,栈底是高地址
    C语言函数调用时,参数按值传递,并从最后一个参数开始压栈
    glibc的backtrace函数可以获取当前函数的backtrace,其backtrace_symbols函数可以把backtrace获取的地址转换成源码的位置(函数名),没有调试信息时不好用
    工具addr2line可以实现地址到源码位置的转换:
    ./file | awk '{print "addr2line "$3" -e file"}'>t.sh;.t.sh;rm -f t.sh
    #file需要把要转换的函数地址输出到stdout,然后awk才可以调用addr2line工具转换
    #对于共享库(动态库)上述方法不能找到源码位置,需要通过/proc/pid/maps找到共享库加载位置,用绝对位置减去加载位置就得到动态库函数偏移地址,然后传递给addr2line可以找到源码位置

    Briian Kernighan和Dennis Ritchie编写的《C语言程序设计》(The C Programming Language)
    《深入理解计算机》
    台湾黑客黄敬群编写的《深入浅出Hello World》

9.LD_DEBUG=symbols ./helloworld
  上述执行显示,查找函数时先在可执行文件查找,然后依次到共享库中查找,使用共享库,可以节省空间,但调用共享库的函数需要额外的开销。
  如果用静态链接的方式连接helloworld,运行速度会快一些,但可执行文件大小增加很多。

  gcc -g -static helloworld.c -o helloworld  #-g是带调式信息 -static是静态链接(输入) -shared是编译成so共享库(输出) ;如何生成静态库和动态库详见另一篇文章http://blog.csdn.net/xiarendeniao/article/details/21259011

-static
   On systems that support dynamic linking, this prevents linking with the shared libraries.  On other systems, this option has no effect.
-shared
   Produce a shared object which can then be linked with other objects to form an executable.  Not all systems support this option.  For
   predictable results, you must also specify the same set of options that were used to generate code (-fpic, -fPIC, or model suboptions) when
   you specify this option.[1]

  共享库的好处取决于共享的次数,次数越多节省的空间越多

(2014.4.26)  编译时要把依赖库(静态库/动态库)链接进去,可用-L path/to/lib -lname在path/to/lib目录下搜索依赖库libname.so或者libname.a,也可直接在gcc命令的后面加上path/to/lib/libname.a或path/to/lib/libname.so (当依赖库同时存在静态库和动态库两个版本时,用第一种方式系统会自动选一个,但第一种方式里面给gcc加上-static选项系统就会排出动态库的链接)。ps: 头文件用-I path/to/include来引入。

(2016.7.5) 忘记上面是从哪儿看来的了,今天做skynet-robot,把一些公用文件变成libcommon.a,然后其他一些luaclib需要打包成so的时候把libcommon.a链进去,只有用-lcommon -L/commondir/才可行,否则,.a里面的符号在.so里面都是undedined.


  LD_PRELOAD=./xx.so ./helloworld
  LD_PRELOAD指定的共享库预先加载,如果出现重名的函数,预先加载的函数被调用,这种方法可以在不修改源码或者没有源码的情况下改变程序的行为    
 
10. 管道过滤器《系统管理员成长计划》Page200
   编译器:
    输入:源程序
    预处理:展开宏、去掉注释
    编译:词法分析、语法分析、语义分析、代码优化、代码生成
    汇编:把汇编代码转换成机器指令,生成目标文件
    链接:把目标文件、静态库、共享库(不拷贝函数和数据)链接成可执行文件/共享库
    输出:可执行文件/共享库
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值