zoukankan      html  css  js  c++  java
  • (转)An Introduction to GCC 学习笔记

    2009/02/25 01:27

    An Introduction to GCC 学习笔记:
    作者:吴学军
    内容摘要 注:转载时请注明出处和作者(吴学军 )来源于GNU文档学习手册

    前三章:
    要点

    1。强烈推荐使用-Wall选项;
    注:Warning 的显示格式:    ?le:line-number:message

    2。编译选项
    -o 文件名:直接产生可执行文件
    -c 文件名:只编译为.o的库文件,不链接 (.c => .o )

    在将多个.o连接为一个可执行文件时,仅使用-o指定可执行文件名即可,不需要使用
    -Wall选项,因为链接是一个明确的过程(unambiguous),只有successed或者fail
    两种结果。

    incidentally [InsI5dentElI] adv. 附带地, 顺便提及(学单词一个:)

    分两步处理:
    每个.c文件编译为.o,然后通过linker连接为一个可执行文件;
    这样每次只编译修改过的.c文件,可以缩短整体编译时间:
    An object ?le contains machine code where any references to the memory addresses of functions(orvariables)in other ?les are left unde?ned.This allows source ?les to be compiled without direct reference to each other.The linker ?lls in these missing addresses when it produces the executable.

    3。连接解析顺序:
    在类unix的系统中,编译器和链接器是通过在命令行中从左向右的顺序检索各个文件。这就意味着:
    含有函数定义的.o文件要放在那些调用该函数的.o文件的右边。
    This means that the object ?le which contains the de?nition of a function should appear after any ?les which call that function.

    4。库的连接
    A library is a collection of precompiled object files which can be linked into programs. Libraries are typically stored in special archive files with the extension‘.a’, referred to as static libraries.They are created from object files with a separate tool, the GNU archiver ar, and used by the linker to resolve references to functions at compile-time.

    -l参数:指定欲链接的库名称
    比如我们相连接标准库目录(/usr/lib, /lib)下的数学库libm.a,那么我们可以这样指定:
    -lm (具体见下面的解释)

    In general, the compiler option ‘-lNAME’ will attempt to link object
    files with a library file ‘libNAME.a’ in the standard library directories.
    Additional directories can specified with command-line options and environment
    variables, to be discussed shortly. A large program will typically
    use many ‘-l’ options to link libraries such as the math library, graphics
    libraries and networking libraries.

    5。其他的一些编译选项
    5.1 -I,-L
    假如程序中使用的头文件路经和链接时使用的.a路径不是缺省的系统路径(如下)
    By default, gcc searches the following directories for header files:
    /usr/local/include/
    /usr/include/
    and the following directories for libraries:
    /usr/local/lib/
    /usr/lib/

    则,需要利用 -I 来指定头文件的include路径
    需要利用 -L 来指定.a文件的库文件路径
    (注:不要在文件include中使用绝对路径来避免这个问题,因为这样对移植后的编译不利)

    同时,也可以利用环境变量来解决搜索路径的问题(Environment variables)
    对于include 问题:
    Additional directories can be added to the include path using the environment
    variable C_INCLUDE_PATH (for C header files) or CPLUS_INCLUDE_PATH (for C++ header files).
    举例:
    $ C_INCLUDE_PATH=/opt/gdbm-1.8.3/include
    $ export C_INCLUDE_PATH
    这样这个头文件路经就被添加到了环境变量中了(利用export使得其他模块也可见该变量)

    同样的添加库文件路经:
    additional directories can be added to the link path using the environment variable LIBRARY_PATH.
    举例:
    $ LIBRARY_PATH=/opt/gdbm-1.8.3/lib
    $ export LIBRARY_PATH

    那么,想指定多个路径可以采用下面的格式:
    dir1:dir2:dir3:......
    其中每一个单独的路径用 : 隔开;
    一个点 . 表示当前路径
    举例:
    $ C_INCLUDE_PATH=.:/opt/gdbm-1.8.3/include:/net/include (含三个路径)
    $ LIBRARY_PATH=.:/opt/gdbm-1.8.3/lib:/net/lib (含三个路径)

    5.2 静态库和共享库(static libraries and shared libraries.)
    库有两种方式存在,
    Static libraries are the ‘.a’ files seen earlier.
    Shared libraries are handled with a more advanced form of linking, which makes the executable file smaller. They use the extension ‘.so’,which stands for shared object.

    [ 短语:in preference to 优先于... ]

    .so的文件是动态链接并执行的。
    当我们指定一个路径下的库文件名时,假如此时同时存在xxx.a和xxx.so的两个库形式,那么
    优先选择.so链接。(共享库优先)

    当执行函数动态链接.so时,如果此文件不在缺省目录下‘/usr/local/lib’ and ‘/usr/lib’.
    那么就需要指定环境变量LD_LIBRARY_PATH (方式和上面include,lib path相同)

    假如现在需要在已有的环境变量上添加新的路径名,则采用如下方式:
    LD_LIBRARY_PATH=NEWDIRS:$LD_LIBRARY_PATH.(newdirs是新的路径串)

    (注:gnu系统可以自动添加在 /etc/ld.so.conf文件中来实现环境变量的设置)

    -static
    使用该选项可以强制编译器生成静态库文件

    6. C语言标准
    -ansi
    the compiler option‘-ansi’ disables those GNU extensions which conflict with the ANSI/ISO standard.

    -pedantic
    The command-line option ‘-pedantic’ in combination with ‘-ansi’ will
    cause gcc to reject all GNU C extensions, not just those that are incompatible
    with the ANSI/ISO standard. This helps you to write portable
    programs which follow the ANSI/ISO standard.

    -std
    The specific language standard used by GCC can be controlled with the‘-std’ option.
    包含有:
    ‘-std=c89’ or ‘-std=iso9899:1990’-- The original ANSI/ISO C language standard
    ‘-std=iso9899:199409’-- The ISO C language standard with ISO Amendment 1, published
    in 1994.
    ‘-std=c99’ or ‘-std=iso9899:1999’-- The revised ISO C language standard,
    published in 1999 (ISO/IEC9899:1999).
    ‘-std=gnu89’ and ‘-std=gnu99’. -- for GNU extensions


    7.关于warning -Wall的具体选项
    以下的一些编译选项都是包含在Wall中的一些具体项目,可以单独使用。
    ‘-Wcomment’ This option warns about nested comments.
    ‘-Wformat’   This option warns about the incorrect use of format strings in functions
    such as printf and scanf, where the format specifier does not agree with the  
    type of the corresponding function argument.
    ‘-Wunused’   This option warns about unused variables.
    ‘-Wimplicit’ This option warns about any functions that are used without being declared.
    ‘-Wreturn-type’ This option warns about functions that are defined without a return
    type but not declared void. It also catches empty return statements in
    functions that are not declared void.

    8. 其他的一些warn编译选项(不包含在Wall中的)
    ‘-W’     This is a general option similar to ‘-Wall’ which warns about a selection of
    common programming errors, such as functions which can return without a value
    (also known as “falling off the end of the function body”), and comparisons
    between signed and unsigned values.
    &An Introduction to GCC 学习笔记:
    作者:吴学军 2004-8      来源:本站原创     发表时间:2006-03-11     浏览次数: 8797      字号:大 中 小
    内容摘要 注:转载时请注明出处和作者(吴学军 )来源于GNU文档学习手册

    nbsp; 一般情况下,-W 和 -Wall同时使用

    ‘-Wconversion’ This option warns about implicit type conversions that could cause
    unexpected results.
    ‘-Wshadow’ This option warns about the redeclaration of a variable name in a scope where
    it has already been declared.
    ‘-Wcast-qual’ This option warns about pointers that are cast to remove a type qualifier,
    such as const.
    ‘-Wwrite-strings’ This option implicitly gives all string constants defined in the program
    a const qualifier, causing a compile-time warning if there is an attempt
    to overwrite them.
    ‘-Wtraditional’   This option warns about parts of the code which would be interpreted
    differently by an ANSI/ISO compiler and a “traditional” pre-ANSI
    compiler.(5)
    上面的这些warn选项都仅仅产生warn,而不会停止编译过程,下面的选项可以将warn视为error并停止编译
    ‘-Werror’ changes the default behavior by converting warnings into errors, stopping
    the compilation whenever a warning occurs.


    第四章:使用预处理器 ( Using the preprocessor )
    GCC的预处理器 cpp属于GCC包的一部分;在原文件被编译之前,GCC会使用cpp将所有的宏扩展。

    4.1定义宏(macro)
    有两种定义的宏的方式:1:其他原文件中;2:在GCC的命令行中使用 -Dxxx
    当这些宏被定义后(#define xxx)
    在系统中使用时:#ifdef xxx 就会被预处理器扩展为有效代码;

    在系统中已经定义了一些系统命名空间内的宏,都是以 __ 开头的(两条下划线)
    使用命令:$ cpp -dM /dev/null 可以查看到所有的预定义宏

    (注:在这些宏中,有一些是GCC系统级的宏,它们都不是以__开头,这些非标准的宏可以使用
    GCC的编译选项 -ansi 使其无效)
    (其实,利用-Dxxx来定义xxx,就是将xxx赋值为1 )

    4.2 定义有值宏
    也是利用 -Dxxx = value的方式来定义

    假如利用-DNAME="" (空)来定义一个宏,则这个宏也被视为被定义的,但是如果按值展开的话,
    则为空;

    4.3 预处理源文件

    The ‘-E’ option causes gcc to run the preprocessor, display the expanded
    output, and then exit without compiling the resulting source code.
    可以利用 -E选项来查看预处理器的工作过程

    可以利用 -save-temps选项来保存预处理器的处理过程日志到临时文件xxxx.i;

    The preprocessed system header files usually generate a lot of output.
    This can be redirected to a file, or saved more conveniently using the gcc
    ‘-save-temps’ option:
    $ gcc -c -save-temps hello.c
    After running this command, the preprocessed output will be available
    in the file ‘hello.i’. The ‘-save-temps’ option also saves ‘.s’ assembly
    files and ‘.o’ object files in addition to preprocessed ‘.i’ files.

    第五章:Compiling for debugging
    一个可执行文件中并不保存任何与其源文件中相关的函数以及变量信息在其中,可执行文件
    只是机器码的集合。
    这样的话,如果系统运行过程中出现错误,我们也不能定位错误。
    利用 -g 编译选项,可以将这些信息保存在执行文件中,使得我们可以利用gdb工具调试;
    保存的信息有:函数名,变量名(及其所有引用)以及它们的相应行号,这些信息都保存
    在叫做符号表的东东中;

    5.1 Core文件
    When a program exits abnormally the operating system can write out a core file,
    usually named ‘core’, which contains the in-memory state of the program at the
    time it crashed.

    当我们运行程序发生错误时,假如提示信息中包含‘core dumped’错误信息时,操作系统
    已经产生了一个叫做core的文件到当前目录(或者/var/coredumps/下)

    (注:In the GNU Bash shell the command ulimit -c controls the maximum
    size of core files. If the size limit is zero, no core files are produced.
    命令$ ulimit -c unlimited 使得任何大小的core文件都可以生成,但是这些设置只在
    当前shell有效)

    使用命令 $ gdb EXECUTABLE-FILE CORE-FILE 来分析


    第六章:优化编译

    6.1 Source-level optimization 代码级优化
    在此只介绍两种:common subexpression elimination和function inlining.

    Common subexpression elimination:(CSE)
    只要优化开关打开,这种优化都会进行,进行这种优化既可以提高速度,又可以减少
    代码大小,例如:
    x = cos(v)*(1+sin(u/2)) + sin(w)*(1-sin(u/2))
    可以写成:
    t = sin(u/2)
    x = cos(v)*(1+t) + sin(w)*(1-t)
    (利用中间变量减少运算次数)

    function inlining:

    6.2 Speed-space tradeoffs 速度-空间权衡

    6.2.1 Loop unrolling
    例如:
    for (i = 0; i < 8; i++)
    {
    y[i] = i;
    }
    很多的时间花费在判断上,可以改写为:
    y[0] = 0;
    y[1] = 1;
    y[2] = 2;
    y[3] = 3;
    y[4] = 4;
    y[5] = 5;
    y[6] = 6;
    y[7] = 7;
    这样可以达到最快的执行速度(没有判断语句,同时可以利用流水线),但是空间也增大了
    另外一例:
    for (i = 0; i < n; i++)
    {
    y[i] = i;
    }
    可以重新写成:
    for (i = 0; i < (n % 2); i++)
    {
    y[i] = i;
    }
    for ( ; i + 1 < n; i += 2) /* no initializer */
    {
    y[i] = i;
    y[i+1] = i+1;
    }
    The first loop handles the case i = 0 when n is odd, and the second loop
    handles all the remaining iterations. Note that the second loop does
    not use an initializer in the first argument of the for statement, since
    it continues where the first loop finishes. The assignments in the second
    loop can be parallelized, and the overall number of tests is reduced by a
    factor of 2 (approximately). Higher factors can be achieved by unrolling
    more assignments inside the loop, at the cost of greater code size.

    6.3 scheduling
    When scheduling is enabled, instructions must be arranged so that
    their results become available to later instructions at the right time, and to
    allow for maximum parallel execution. Scheduling improves the speed of
    an executable without increasing its size, but requires additional memory
    and time in the compilation process itself (due to its complexity).

    6.4 优化等级
    优化等级分为:0 - 3
    编译选项为: -Olevel
    各等级含义如下:

    ‘-O0’ or no ‘-O’ option (default)不优化
    At this optimization level GCC does not perform any optimization
    and compiles the source code in the most straightforward way
    possible. Each command in the source code is converted directly
    to the corresponding instructions in the executable file, without
    rearrangement. This is the best option to use when debugging a
    program.
    The option ‘-O0’ is equivalent to not specifying a ‘-O’ option.

    ‘-O1’ or ‘-O’
    This level turns on the most common forms of optimization that
    do not require any speed-space tradeoffs. With this option the
    resulting executables should be smaller and faster than with ‘-O0’.
    The more expensive optimizations, such as instruction scheduling,
    are not used at this level.
    Compiling with the option ‘-O1’ can often take less time than compiling
    with ‘-O0’, due to the reduced amounts of data that need to
    be processed after simple optimizations.

    ‘-O2’ This option turns on further optimizations, in addition to those
    used by ‘-O1’. These additional optimizations include instruction
    scheduling. Only optimizations that do not require any speed-space
    tradeoffs are used, so the executable should not increase in size. The
    compiler will take longer to compile programs and require more
    memory than with ‘-O1’. This option is generally the best choice
    for deployment of a program, because it provides maximum optimization
    without increasing the executable size. It is the default
    optimization level for releases of GNU packages.

    ‘-O3’ This option turns on more expensive optimizations, such as function
    inlining, in addition to all the optimizations of the lower levels
    ‘-O2’ and ‘-O1’. The ‘-O3’ optimization level may increase the speed
    of the resulting executable, but can also increase its size. Under
    some circumstances where these optimizations are not favorable,
    this option might actually make a program slower.

    ‘-funroll-loops’
    This option turns on loop-unrolling, and is independent of the other
    optimization options. It will increase the size of an executable.
    Whether or not this option produces a beneficial result has to be
    examined on a case-by-case basis.

    ‘-Os’ This option selects optimizations which reduce the size of an executable.
    The aim of this option is to produce the smallest possible
    executable, for systems constrained by memory or disk space. In
    some cases a smaller executable will also run faster, due to better
    cache usage.

    注:For most purposes it is satisfactory to use ‘-O0’ for debugging, and
    ‘-O2’ for development and deployment.

    “optimizations may not necessarily make a program faster in every case.”

    第七章:编译C++程序
    GCC是一个真正的C++编译器,其直接将C++代码编译为汇编代码。

    1。利用g++而不是gcc命令;
    (注:C++ source code should be given one of the valid C++ file extensions ‘.cc’,
    ‘.cpp’, ‘.cxx’ or ‘.C’ rather than the ‘.c’ extension used for C programs.)

    2。C++标准库模板
    The C++ standard library ‘libstdc++’ supplied with GCC provides a wide
    range of generic container classes such as lists and queues, in addition to
    generic algorithms such as sorting。

    3。Explicit template instantiation
    To achieve complete control over the compilation of templates with g++
    it is possible to require explicit instantiation of each occurrence of a template,
    using the option ‘-fno-implicit-templates’.

    第八章:平台相关的选项
    利用 -m 选项来确定不同的开发平台


    获得GCC的帮助文档:
    $ gcc -v --help
    $ gcc -v --help 2>&1 | more
    获得GCC的版本号:
    $ gcc --version
    (注:The ‘-v’ option can also be used to display detailed information about the
    exact sequence of commands used to compile and link a program)

    第十章:编译器相关的工具

    1。 ar工具 Creating a library with the GNU archiver
    The GNU archiver ar combines a collection of object files into a single
    archive file, also known as a library.
    ar工具可以将要发布的多个.o文件组装成一个.a的库文件
    例如:将hello_fn.o和bye_fn.o生成 libhello.a的命令行:
    $ ar cr libhello.a hello_fn.o bye_fn.o
    其中The option ‘cr’ stands for “create and replace”.

    利用 选项 t 可以查看.a文件中所包含的所有.o的信息
    $ ar t libhello.a
    hello_fn.o
    bye_fn.o

    2。程序性能测试工具-gprof
    To use profiling, the program must be compiled and linked with the ‘-pg’
    profiling option:
    $ gcc -Wall -c -pg collatz.c
    $ gcc -Wall -pg collatz.o
    编译和链接的时候添加选项 -pg ,才能使用gprof测试程序性能

    然后运行编译通过的程序,才能产生gprof需要的文件 gmon.out(在当前目录下)
    然后执行:
    $ gprof a.out (假设可执行文件是缺省生成的)

    3。程序覆盖测试工具- gcov
    The GNU coverage testing tool gcov analyses the number of times each
    line of a program is executed during a run. This makes it possible to
    find areas of the code which are not used, or which are not exercised
    in testing. When combined with profiling information from gprof the
    information from coverage testing allows efforts to speed up a program to
    be concentrated on specific lines of the source code.

    编译和链接必须使用相关选项,才可以使用gcov工具。
    例如:
    $ gcc -Wall -fprofile-arcs -ftest-coverage cov.c
    其中
    ‘-ftest-coverage’ adds instructions for counting the number of times
    individual lines are executed,
    ‘-fprofile-arcs’ incorporates instrumentation code for each branch of
    the program. Branch instrumentation records how frequently
    different paths are taken through‘if’ statements and
    other conditionals.
    运行通过编译的程序,产生供gcov使用的文件:
    分别带有后缀:‘.bb’‘.bbg’ and ‘.da’在当前目录下
    然后运行
    $ gcov cov.c (注意:是源代码文件)
    这样会产生一个带有标注的源文件的副本文件,后缀为 .gcov
    在该文件中,标注了每一行代码的执行次数,标注为‘######’的语句为
    未被执行到的语句。
    可以通过命令:
    grep ’######’ *.gcov 查找到所有未被执行到的语句

    第十一章:编译器工作过程

    Compilation is a multi-stage process involving several
    tools, including the GNU Compiler itself (through the gcc or g++ frontends),
    the GNU Assembler as, and the GNU Linker ld. The complete
    set of tools used in the compilation process is referred to as a toolchain.

    toolchain的定义见此:)

    调用GCC的内部过程如下:
    ? preprocessing (to expand macros)                    预处理
    ? compilation (from source code to assembly language) 编译
    ? assembly (from assembly language to machine code)   汇编
    ? linking (to create the final executable)            链接

    详细描述如下:
    1。preprocessing:
    举例:第一步GCC会调用如下命令

    $ cpp hello.c > hello.i

    生成中间文件 hello.i(如果是C++文件的话,就是 hello.ii)
    这种中间文件不会保存到磁盘上的,除非添加了编译选项-save-temps

    2。compilation:
    第二步:调用gcc(或者g++)生成汇编文件而不是.o文件(使用了-S选项)

    $ gcc -Wall -S hello.i

    这样就生成了基于x86 CPU的汇编文件 hello.s

    3.assembly:
    The purpose of the assembler is to convert assembly language into machine
    code and generate an object file. When there are calls to external
    functions in the assembly source file, the assembler leaves the addresses
    of the external functions undefined, to be filled in later by the linker.
    第三步调用

    $ as hello.s -o hello.o

    4。linking:
    The final stage of compilation is the linking of object files to create an
    executable. In practice, an executable requires many external functions
    from system and C run-time (crt) libraries. Consequently, the actual link
    commands used internally by GCC are complicated.

    第四步调用
    $ gcc hello.o

    其实在GCC内部的这一步调用如下:
    $ ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o
    /usr/lib/crti.o /usr/lib/gcc-lib/i686/3.3.1/crtbegin.o
    -L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh
    -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i686/3.3.1/crtend.o
    /usr/lib/crtn.o(非常复杂)

    第十二章:测试编译后文件的工具

    1。Identifying files 鉴别文件 - file 命令
    举例:
    $ file a.out
    a.out: ELF 32-bit LSB executable, Intel 80386,
    version 1 (SYSV), dynamically linked (uses shared
    libs), not stripped

    最后一个not stripped表示该文件含符号表(可以利用命令strip去除符号表)

    2。查看符号表工具 - nm
    2。查看符号表工具 - nm
    举例:
    An Introduction to GCC 学习笔记:
    作者:吴学军 2004-8      来源:本站原创     发表时间:2006-03-11     浏览次数: 8798      字号:大 中 小
    内容摘要 注:转载时请注明出处和作者(吴学军 )来源于GNU文档学习手册

    vides maximum optimization
    without increasing the executable size. It is the default
    optimization level for releases of GNU packages.


    ‘-O3’ This option turns on more expensive optimizations, such as function
    inlining, in addition to all the optimizations of the lower levels
    ‘-O2’ and ‘-O1’. The ‘-O3’ optimization level may increase the speed
    of the resulting executable, but can also increase its size. Under
    some circumstances where these optimizations are not favorable,
    this option might actually make a program slower.

    ‘-funroll-loops’
    This option turns on loop-unrolling, and is independent of the other
    optimization options. It will increase the size of an executable.
    Whether or not this option produces a beneficial result has to be
    examined on a case-by-case basis.

    ‘-Os’ This option selects optimizations which reduce the size of an executable.
    The aim of this option is to produce the smallest possible
    executable, for systems constrained by memory or disk space. In
    some cases a smaller executable will also run faster, due to better
    cache usage.

    注:For most purposes it is satisfactory to use ‘-O0’ for debugging, and
    ‘-O2’ for development and deployment.

    “optimizations may not necessarily make a program faster in every case.”

    第七章:编译C++程序
    GCC是一个真正的C++编译器,其直接将C++代码编译为汇编代码。

    1。利用g++而不是gcc命令;
    (注:C++ source code should be given one of the valid C++ file extensions ‘.cc’,
    ‘.cpp’, ‘.cxx’ or ‘.C’ rather than the ‘.c’ extension used for C programs.)

    2。C++标准库模板
    The C++ standard library ‘libstdc++’ supplied with GCC provides a wide
    range of generic container classes such as lists and queues, in addition to
    generic algorithms such as sorting。

    3。Explicit template instantiation
    To achieve complete control over the compilation of templates with g++
    it is possible to require explicit instantiation of each occurrence of a template,
    using the option ‘-fno-implicit-templates’.

    第八章:平台相关的选项
    利用 -m 选项来确定不同的开发平台


    获得GCC的帮助文档:
    $ gcc -v --help
    $ gcc -v --help 2>&1 | more
    获得GCC的版本号:
    $ gcc --version
    (注:The ‘-v’ option can also be used to display detailed information about the
    exact sequence of commands used to compile and link a program)

    第十章:编译器相关的工具

    1。 ar工具 Creating a library with the GNU archiver
    The GNU archiver ar combines a collection of object files into a single
    archive file, also known as a library.
    ar工具可以将要发布的多个.o文件组装成一个.a的库文件
    例如:将hello_fn.o和bye_fn.o生成 libhello.a的命令行:
    $ ar cr libhello.a hello_fn.o bye_fn.o
    其中The option ‘cr’ stands for “create and replace”.

    利用 选项 t 可以查看.a文件中所包含的所有.o的信息
    $ ar t libhello.a
    hello_fn.o
    bye_fn.o

    2。程序性能测试工具-gprof
    To use profiling, the program must be compiled and linked with the ‘-pg’
    profiling option:
    $ gcc -Wall -c -pg collatz.c
    $ gcc -Wall -pg collatz.o
    编译和链接的时候添加选项 -pg ,才能使用gprof测试程序性能

    然后运行编译通过的程序,才能产生gprof需要的文件 gmon.out(在当前目录下)
    然后执行:
    $ gprof a.out (假设可执行文件是缺省生成的)

    3。程序覆盖测试工具- gcov
    The GNU coverage testing tool gcov analyses the number of times each
    line of a program is executed during a run. This makes it possible to
    find areas of the code which are not used, or which are not exercised
    in testing. When combined with profiling information from gprof the
    information from coverage testing allows efforts to speed up a program to
    be concentrated on specific lines of the source code.

    编译和链接必须使用相关选项,才可以使用gcov工具。
    例如:
    $ gcc -Wall -fprofile-arcs -ftest-coverage cov.c
    其中
    ‘-ftest-coverage’ adds instructions for counting the number of times
    individual lines are executed,
    ‘-fprofile-arcs’ incorporates instrumentation code for each branch of
    the program. Branch instrumentation records how frequently
    different paths are taken through‘if’ statements and
    other conditionals.
    运行通过编译的程序,产生供gcov使用的文件:
    分别带有后缀:‘.bb’‘.bbg’ and ‘.da’在当前目录下
    然后运行
    $ gcov cov.c (注意:是源代码文件)
    这样会产生一个带有标注的源文件的副本文件,后缀为 .gcov
    在该文件中,标注了每一行代码的执行次数,标注为‘######’的语句为
    未被执行到的语句。
    可以通过命令:
    grep ’######’ *.gcov 查找到所有未被执行到的语句

    第十一章:编译器工作过程

    Compilation is a multi-stage process involving several
    tools, including the GNU Compiler itself (through the gcc or g++ frontends),
    the GNU Assembler as, and the GNU Linker ld. The complete
    set of tools used in the compilation process is referred to as a toolchain.

    toolchain的定义见此:)

    调用GCC的内部过程如下:
    ? preprocessing (to expand macros)                    预处理
    ? compilation (from source code to assembly language) 编译
    ? assembly (from assembly language to machine code)   汇编
    ? linking (to create the final executable)            链接

    详细描述如下:
    1。preprocessing:
    举例:第一步GCC会调用如下命令

    $ cpp hello.c > hello.i

    生成中间文件 hello.i(如果是C++文件的话,就是 hello.ii)
    这种中间文件不会保存到磁盘上的,除非添加了编译选项-save-temps

    2。compilation:
    第二步:调用gcc(或者g++)生成汇编文件而不是.o文件(使用了-S选项)

    $ gcc -Wall -S hello.i

    这样就生成了基于x86 CPU的汇编文件 hello.s

    3.assembly:
    The purpose of the assembler is to convert assembly language into machine
    code and generate an object file. When there are calls to external
    functions in the assembly source file, the assembler leaves the addresses
    of the external functions undefined, to be filled in later by the linker.
    第三步调用

    $ as hello.s -o hello.o

    4。linking:
    The final stage of compilation is the linking of object files to create an
    executable. In practice, an executable requires many external functions
    from system and C run-time (crt) libraries. Consequently, the actual link
    commands used internally by GCC are complicated.

    第四步调用
    $ gcc hello.o

    其实在GCC内部的这一步调用如下:
    $ ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o
    /usr/lib/crti.o /usr/lib/gcc-lib/i686/3.3.1/crtbegin.o
    -L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh
    -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i686/3.3.1/crtend.o
    /usr/lib/crtn.o(非常复杂)

    第十二章:测试编译后文件的工具

    1。Identifying files 鉴别文件 - file 命令
    举例:
    $ file a.out
    a.out: ELF 32-bit LSB executable, Intel 80386,
    version 1 (SYSV), dynamically linked (uses shared
    libs), not stripped

    最后一个not stripped表示该文件含符号表(可以利用命令strip去除符号表)

    2。查看符号表工具 - nm
    举例:
    $ nm a.out
    08048334 t Letext
    08049498 ? _DYNAMIC
    08049570 ? _GLOBAL_OFFSET_TABLE_
    ........
    080483f0 T main
    08049590 b object.11
    0804948c d p.3
    U

    其中: T表示该函数在此文件中有定义
    U表示未定义的函数(需要link的外部函数)
    所以,nm最常用的地方在于,查看这个文件中是否包含某函数的定义

    3。寻找所需的动态链接库工具 - ldd

    例如:
    $ gcc -Wall hello.c
    $ ldd a.out
    libc.so.6 => /lib/libc.so.6 (0x40020000)
    /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

    给命令同样可以用于动态链接库本身,来查找其所需要的链接库

    -- End --

    (坚持不懈地往一个方向前进,不要浮躁的四处张望!)Go!!!

    An Introduction to GCC 学习笔记:
    作者:吴学军 2004-8      来源:本站原创     发表时间:2006-03-11     浏览次数: 8799      字号:大 中 小
    内容摘要 注:转载时请注明出处和作者(吴学军 )来源于GNU文档学习手册

    >$ nm a.out
    08048334 t Letext
    08049498 ? _DYNAMIC
    08049570 ? _GLOBAL_OFFSET_TABLE_
    ........
    080483f0 T main
    08049590 b object.11
    0804948c d p.3
    U


    其中: T表示该函数在此文件中有定义
    U表示未定义的函数(需要link的外部函数)
    所以,nm最常用的地方在于,查看这个文件中是否包含某函数的定义

    3。寻找所需的动态链接库工具 - ldd

    例如:
    $ gcc -Wall hello.c
    $ ldd a.out
    libc.so.6 => /lib/libc.so.6 (0x40020000)
    /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

    给命令同样可以用于动态链接库本身,来查找其所需要的链接库

    -- End --

    (坚持不懈地往一个方向前进,不要浮躁的四处张望!)Go!!!

  • 相关阅读:
    在linux CentOS7 安装Nginx 部署vue
    VS Code 用Vue Cli创建项目
    CentOS8通过命令设置IP地址
    C# .net Core WebApi 系列(一)创建与使用
    JS、C#编码解码
    C#通用类库--数字转为人民币汉字大写表示
    CheckUtil类
    Windows服务用bat命令安装与卸载
    突然的兴趣,我想写一个提取图片中特定颜色图像的程序
    一些常用的基础操作记录
  • 原文地址:https://www.cnblogs.com/yysblog/p/2779130.html
Copyright © 2011-2022 走看看