首页>参考读物>计算机科学与技术>软件与程序设计

高级C/C++编译技术
作者 : [美]米兰·斯特瓦诺维奇(Milan Stevanovic) 著
译者 : 卢誉声 译
丛书名 : C/C++技术丛书
出版日期 : 2015-05-18
ISBN : 978-7-111-49618-2
定价 : 69.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 280
开本 : 16
原书名 : Advanced C and C++ Compiling
原出版社: Apress
属性分类: 店面
包含CD :
绝版 : 未绝版
图书简介

图书特色

本书从多个角度全面、系统地讲解多任务操作系统中编译、链接、装载与库的内幕和技术细节,为深入理解和掌握系统底层技术提供详实参考和实践指南。与纯粹讲解理论与技术细节的书不同,本书一方面对基本的理论进行了阐述,另一方面则聚焦于C/C++使用静态库和动态库的一些注意事项,并举例说明如何解决实际的链接与装载问题。此外,本书尽量使用通俗易懂的语言来阐述这些知识,并补充了大量示例,避免让读者整天纠结于枯燥的理论。
本书共14章,其中第1章至第4章对多任务操作系统、程序生命周期以及代码重用等重要概念进行介绍,为后续内容做铺垫;第5章介绍静态库的使用方法及其设计技巧;第6章至第11章介绍动态库的相关概念,包括不同平台中动态库的技术细节,比如库文件定位、引用解析与符号处理等,以及一些动态库设计的基本方法与原则和不同平台下应当注意的设计细节;第12章至第14章主要给出一些实践方面的总结,便于读者快速查找相关的概念,而且还总结了一些特定平台的二进制文件分析工具。
学习如何编写C/C++代码仅仅是个开始。如果你希望从事系统底层开发,或想深入理解操作系统、编译器及它们之间内在的关联,成为“编程专家”,那么就必须对编译器生成的二进制文件(目标文件、静态库、动态库和可执行文件)的作用和结构进行充分的了解。开源已经在许多方面从根本上改变了软件的原有面貌,越来越多的系统开始采用或集成开源代码,因此对每位开发人员来说,学习和理解这些底层技术也变得十分重要。
本书深入浅出地讲解了构建过程(编译、链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架构设计方法,以及系统开发过程中疑难问题的解决方案。同时,本书也是一本C/C++二进制文件方面的软件工程指南,涵盖中级和专家程序员所需的各方面内容和信息。

通过阅读本书,你将学到:
构建过程(编译和链接)与装载过程的内部原理
静态库、动态库和可执行文件的内部工作机制
面向代码复用和系统集成的软件架构设计方法
编译、链接与运行时出现问题的排查技巧
在Linux和Windows平台下利用二进制文件分析工具进行分析
作者简介
Milan Stevanovic 资深软件顾问,在多个学科的工程领域都有着丰富的经验。他主要从事的领域是Linux和Windows平台下的多媒体压缩格式及其多媒体框架设计。他热衷于开源,而且是avxsynth开源项目的主要贡献者,对C/C++底层技术有着深入的研究。
译者简介
卢誉声 软件工程师,现就职于思科系统(中国)研发中心云产品研发部。他曾参与服务器后端、前端以及SDK的设计与研发工作,在分布式系统设计与实现、性能调优、高可用性和自动化等方面积累了丰富的敏捷实践与开发经验。此外,他还从事C/C++设计与研发工作,对JavaScript、Lua和移动开发平台等也有一定研究。

图书前言

我花了相当长的时间才认识到,计算机编程艺术与烹饪艺术之间存在着惊人的相似性。
说到烹饪和编程的比较,我的脑海中首先浮现出来的是烹饪专家和程序员的工作目标非常相似:都是为了满足特定对象的需求。对一个厨师来说,他的服务对象是食客,他需要使用大量的食材,一方面满足人们的温饱与营养需求,另一方面则要让人们享受到美食带来的快乐。而对一个程序员来说,其服务对象是微处理器,程序员使用大量不同的程序来为其提供代码,不仅要让微处理器产生有意义的动作,还需要以最优的形式将代码交付给微处
理器。
虽说这种对比看起来有些牵强而且过于简单,但我们会在本书中列出一些更加合适和更具说服力的对比。
介绍烹饪方法的食谱的数量繁多。几乎所有的流行杂志都会开设专栏来介绍形形色色的美食和烹饪方法,无论是快餐式的食谱还是精致复杂的食谱、注重食材的食谱还是注重搭配稀有食材的食谱,你都能够找到。
但如果你希望自己成为烹饪大师,就会发现很难找到可供参考的资料,比如食品行业经营(批量生产、饭店或餐饮企业的经营)、食品生产的供需管理、选料和食材保鲜方面的指南或资料。很显然,这就是业余烹饪爱好者和专业食品企业之间的区别。
这种情况与程序设计其实非常相似。
我们可以轻松地从成千上万的书籍、杂志、文章、网络论坛和博客中搜集到编程语言方面的各类信息,无论是入门教程,还是“谷歌编程面试指南”这样的技巧。
但是,这类主题所涵盖的内容只能满足成为专业软件工程师一半的要求。我们不能一直沉浸在因程序实际执行(且执行正确)而带来的喜悦当中,而需要着重考虑接下来的问题:如何组织代码结构以便将来修改、如何从功能模块中提取出可重用代码,以及如何让程序能够适应不同的运行环境(无论是不同的人类语言和字符,还是在不同的操作系统环境中
运行)。
相较于其他编程主题来说,人们很少讨论这类问题。时至今日,这类问题变成了只有计算机科学专业人士(绝大多数软件架构师和构建工程师)和大学课堂上讲解编译器、链接器设计时,才会了解的“黑科技”。
由于Linux市场份额增加,而且越来越多的人都将Linux作为其编程环境,这促使开发人员开始关注Linux编程的相关问题。与在一些封装良好的平台(在Windows和Mac平台上利用IDE和SDK将程序员从一些特定的编程细节问题中解放出来)开发软件的开发人员不同,Linux开发人员在日常工作中需要将来自不同项目且编码风格迥异的代码组合起来,这需要开发人员充分理解编译器、链接器的内部工作机制和程序装载机制,以及不同库的设计细节和使用方法。
本书将许多零碎的知识点进行汇总,并讨论其中那些有价值的内容,这些内容则通过一系列精心设计的简单示例进行验证。需要注意的是,本书的作者并非计算机科学科班出身。20世纪90年代末至今的数字革命中,作者作为电气工程师供职于硅谷的一家多媒体行业高新技术企业,并因此掌握了相关领域的知识。希望本书的主题和内容能够让更多读者受益。
读者对象
作为一名软件设计实践顾问(虽然很忙,但我还是非常自豪的),我经常会与不同专业背景和资历的人群沟通。我在工作周中需要经常在不同的办公环境中工作,因此接触了许多开发人员(绝大多数来自硅谷),这也让我更加了解了本书的受众群体。其中包括以下几类人群。
第一类受众群体是来自不同工程领域的C/C++开发人员(电气工程、机械、机器人技术和系统控制、航天、物理和化学等领域),这类人需要在日常工作中通过编程来解决问题。对缺乏正规计算机科学课程和理论教学的人来说,本书所提供的资料弥足珍贵。
第二类受众群体是具有计算机科学教育背景的初级程序员。本书能够帮助大家将主修课程中学到的知识具体化,并注重实践。将第12章~第14章的内容作为手册查阅,对资深工程师而言,也会有所受益。
第三类受众群体是操作系统集成和定制的爱好者。理解二进制文件及其内部工作机制将有助于在解决问题的过程中扫除障碍。
关于本书
我最初并没有计划去写这么一本书,甚至都没有打算写一本计算机科学领域的书。(我有可能会去编写信号处理或程序设计艺术方面的书,但编写计算机科学方面的书?不……)
在职业生涯中,我经常处理当时我认为别人已经解决好的一些问题,而实际上这些问题并没有得到根本性解决,这是我写作此书的唯一原因。
很久以前,我决定成为一名从事高科技领域的“刺客”,将许多看似平静且体面的高科技公司从“恐怖分子”——复杂多媒体设计问题和大量严重缺陷所造成的破坏中解救出来。选择这样一个职业的结果就是,我并没有多少时间处理自己的生活,比如说孩子们想吃鸡肉而不是豌豆,我很难满足他们的这些需求。虽然我更倾向于使用傅里叶变换算法、小波、Z变换、FIR和IIR滤波器、倍频程、半音程、插值和抽取算法来解决问题(与C/C++编程一起使用),但我还是要解决那些我并不喜欢解决的问题。总要有人去做这些事情吧。
出乎意料的是,在搜索一些非常简单明了的问题的答案时,我只能找到一些散乱的网络文章,而且绝大多数都只是泛泛而谈。我很耐心地把这些散乱的内容组织到一起,不仅完成了我手头的设计任务,而且学习总结了很多资料。
在一个天朗气清的日子里,我开始整理设计笔记(记录我工作中经常遇到的一些问题和解决方案)。但在整理工作完成的时候,这些笔记看起来就像……嗯……就像一本书——就是这本书。
不管怎么说……
就目前就业市场的情况而言,我认为(自2005年左右开始)熟悉C/C++语言的复杂性,甚至是算法、数据结构和设计模式,对于找到一份好工作都是远远不够的。
在开源盛行的今天,专业开发人员在日常工作中所编写的代码越来越少,取而代之的是将现有代码集成到项目中。这不仅要求开发人员能够读懂其他人编写的代码(使用不同的代码风格和实践),还需要了解如何才能以最好的方式将现有的包(绝大多数以二进制文件(库)和导出头文件的形式提供)集成到代码中。
我希望本书能够兼具教学(对亟须这些知识的读者而言)和快速查询的功能(对分析C/C++二进制文件相关工作的工程师而言)。
为何采用Linux进行演示?
选择Linux并非我个人的偏好。实际上了解我的人都知道,我过去是多么喜欢使用Windows作为开发环境(原本这是我首选的设计平台),原因是Windows平台具有编写良好的文档、完善的支持和符合规范的认证组件。我设计过许多专业化软件(曾为Palm公司设计开发了Windows Mobile平台的GraphEdit,其中包含了许多最为复杂的功能,随后又开发了多个媒体格式和DSP分析软件),在当时我对Windows的技术了如指掌,并感叹Windows相关技术所带来的改变。
与此同时, Linux的时代到来了。有关Linux的技术随处可见,而对开发人员来说,也必须顺应这种趋势去学习和使用它。
Linux软件开发环境具有开放、透明和简单明了的特点。在Linux中,我们可以对每个程序设计阶段进行控制。同时,Linux提供了完善的文档,再加上网络上提供的资源,就可以轻松地使用GNU工具链。
实际上,由于Linux C/C++开发经验可以直接适用于Mac OS平台的底层开发,因此我最终决定选用Linux/GNU作为本书所涵盖的主要开发环境。
别急!Linux与GNU完全是两回事!
实际上,Linux是内核,而GNU中包含了Linux内核之上的所有软件。除了GNU编译器(可以在其他操作系统上使用,比如Windows上的MinGW)以外,在绝大多数情况下,GNU与Linux的关系其实非常紧密。为了简单起见,同时为了符合一般开发人员对开发场景的认识,特别是为了将Linux与Windows进行对比,本书将GNU与Linux作为一个整体,简称为“Linux”。
章节概览
第2章~第5章讲解的内容主要为后续内容做铺垫。拥有计算机科学背景的读者可以快速阅读这些章节(幸运的是,这些章节的内容并不长)。实际上,任何计算机科学方面的教科书都会对这些内容进行类似介绍,而且内容会更为详细。我个人推荐由Bryant和O’Hallaron编写的《深入理解计算机系统》(《Computer Systems—A Programmer’s Perspective》)一书,原因是本书对很多主题都进行了非常有条理的梳理和总结。
第6章~第11章是本书的核心章节。为求整体内容简洁明了,我花费了相当大的精力,并尝试使用一些日常生活中常见事物的文字和图片,来阐述那些最为重要的核心概念。如果你不是计算机科学科班出身,那么有必要先理解这些内容。其实这些章节是本书主题的要点。
第12章~第14章主要概括了一些实践方面的内容,便于读者快速查找相关的概念。这些章节针对一些特定平台的二进制文件分析工具进行了总结,然后在实践部分涵盖了完成独立任务的方法。

上架指导

计算机\程序设计

封底文字

学习如何编写C和C++代码仅仅是个开始。如果你希望从事系统底层开发,或想深入理解操作系统、编译器及它们之间内在的关联,成为“编程专家”,那么就必须对编译器生成的二进制文件(目标文件、静态库、动态库和可执行文件)的作用和结构进行充分的了解。开源已经在许多方面从根本上改变了软件的原有面貌,越来越多的系统开始采用或集成开源代码,因此对每位开发人员来说,学习和理解这些底层技术也变得十分重要。
本书深入浅出地讲解了构建过程(编译、链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架构设计方法,以及系统开发过程中疑难问题的解决方案。同时,本书也是一本C和C++二进制文件方面的软件工程指南,涵盖中级和专家程序员所需的各方面内容和信息。

通过阅读本书,你将学到:
 构建过程(编译和链接)与装载过程的内部原理
 静态库、动态库和可执行文件的内部工作机制
 面向代码复用和系统集成的软件架构设计方法
 编译、链接与运行时出现问题的排查技巧
 在Linux和Windows平台下利用二进制文件分析工具进行分析

作者简介

[美]米兰·斯特瓦诺维奇(Milan Stevanovic) 著:暂无简介

译者简介

卢誉声 译:暂无简介

译者序

虽说计算机软件编程领域的技术发展日新月异,但我始终坚信所有程序开发技术演进都万变不离其宗,其本质自始至终从未发生过改变。就编程语言来说,无论抽象到何种层次,使用何种风格,最终都会回归到本质——机器代码。而在我们常用的高级语言中,最贴近机器及操作系统底层的恐怕就是C语言了。
从一定程度上来讲,C语言堪称一门革命性的语言,它完美平衡了语言中机器相关与机器无关的部分,使得我们可以用机器无关的方式来处理程序逻辑,但必要时又可以直接控制底层硬件,C语言被广泛运用在操作系统开发中正是这一点的绝佳例证。同时,C语言的核心是非常简单的,一切细节都暴露在程序员面前,不会因为某种语法构造而导致隐藏的性能消耗。这使得C语言成为程序员在追求程序效率时的一个绝佳选择。C语言为了保证核心语言的简单(包括标准库的简单)与高效,没有将很多必要的现代语言特性融入标准中,比如C语言自身没有提供任何反射机制。这是一把双刃剑,也就是说,如果想在C语言中实现任何动态语言特性,必须使用和系统相关的特性,尤其是在动态库、共享库、插件等概念日益重要的今天,这给C程序员带来很多麻烦。虽说现在各种主流操作系统中都很好地支持动态库或共享库,也提供了相应接口,但是不同平台中的概念都会有细微差别,而且在具体技术细节上也会不同,这使得程序员在处理跨平台问题时会遇到很多问题。
C++的出现则让这一切变得更加错综复杂。
C++是一门多范式语言,在提供了面向对象和泛型编程的同时,为了保证效率,依然坚持不加入任何动态特性,或者提供某些非常有局限性的动态特性(比如RTTI),为了实现多态则采用了虚函数表这种折中方法。除了C++语法给编译器实现带来的复杂性之外,受到更大挑战的则是C++的链接器和装载器实现。符号名称修饰、全局对象管理、模板支持等各种特性使得链接器和装载器为了支持C++需要付出更多的努力。
同时,C++程序员处理动态库或共享库时也同样需要更加细心、耐心。很多时候,我们一不留意就会被各种链接器或者装载器错误提示搅得心如乱麻,而查遍代码也找不出问题所在。编译器优化的不确定因素更加剧了这种情况。另一方面,现在的计算机教育中,包括程序设计语言课程、编译原理课程、操作系统课程,但并没有一门关于链接和装载的课程,链接和装载往往只是在这些课程中一带而过。或许这是由于链接和装载是非常纯粹的技术性话题,并不像其他课程那样需要传授各种理论,但这导致很多人对链接和装载一知半解,根本没有系统认识。
这些因素叠加起来的后果是,许多初级C/C++程序员遇到链接和装载问题时感到束手无策,根本不知问题出在何处。如果说Windows平台下的程序员得益于Visual Studio这种强大的IDE,在处理动态链接库时颇为方便,那么对Linux程序员来说,这便是一场噩梦。他们需要手动集成各种第三方库,有的是开源的,有的是非开源的,有的只提供了源代码,有的只提供了二进制文件,有的文档详尽,有的文档匮乏……他们永远不知道会遇到什么情况。即便是使用IDE的初级程序员,有时也不得不手动解决各种链接问题,但往往由于他们满足于IDE的良好封装,而忽略其底层编译链接的细节,因而在处理这些问题时更加盲目。在这种情况下,对链接和装载(其实也包括C/C++语言本身以及编译过程)认识并不深刻的那些程序员在日常工作中很容易在处理这类问题时“触礁”。由于缺乏系统认知,他们需要在一次又一次的失败实践中总结,这会走许多弯路。
由于我本人在大规模分布式实时系统研发方面具有一定的经验,因此许多人在C/C++开发中遇到问题时会咨询我,其中一部分问题出在C++语法上,而更多的问题则出在链接和装载上。本书在这些方面进行了翔实总结和讨论。与纯粹讲解理论与技术细节的书不同,本书一方面阐述基本的理论,另一方面则聚焦于C/C++使用静态库和动态库的一些注意事项,并举例说明如何解决实际的链接与装载问题。此外,本书尽量使用通俗易懂的语言来阐述这些知识,并补充了大量示例,避免让读者纠结枯燥的理论。
相信你会和我一样,在本书中发掘出大量有价值的资料,以便在日后的工作中游刃有余,并在处理C/C++相关问题的时候厘清思路,排除障碍。
在翻译本书的过程中,我不仅查阅了大量国内外的相关资料,还与英文原著作者进行了深入沟通,力求做到专业词汇准确权威,书本内容正确,意译部分既无偏差又不失原著
意境。在翻译过程中得到了很多人的帮助,这里一一感谢。感谢我的家人,他们是我学习和前进的动力。感谢鲁昌华教授,他在我的成长道路上给予了很大的支持和鼓励。感谢我在思科系统(中国)研发的同事们,他们在我的学习、工作中给予了很大帮助。感谢我的好友金柳颀,感谢他在我翻译本书过程中与我的通力合作。还要感谢机械工业出版社的陈佳媛编辑对我的信任。
现在我怀着期盼和忐忑的心情将这本译著呈献给大家,我渴望得到你的认可,更渴望和你成为朋友,如果你有任何问题或建议,请与我联系(samblg@me.com),让我们一起探讨、共同进步。

卢誉声

图书目录

译者序
前言
第1章 多任务操作系统基础 1
1.1 一些有用的抽象概念 1
1.2 存储器层次结构与缓存策略 2
1.3 虚拟内存 3
1.4 虚拟地址 5
1.5 进程的内存划分方案 5
1.6 二进制文件、编译器、链接器与装载器的作用 6
1.7 小结 7
第2章 程序生命周期阶段基础 8
2.1 基本假设 8
2.2 编写代码 9
2.3 编译阶段 11
2.3.1 基本概念 11
2.3.2 相关概念 11
2.3.3 编译的各个阶段 12
2.3.4 目标文件属性 23
2.3.5 编译过程的局限性 24
2.4 链接 26
2.4.1 链接阶段 26
2.4.2 链接器视角 31
2.5 可执行文件属性 33
2.5.1 各种节的类型 34
2.5.2 各种符号类型 36
第3章 加载程序执行阶段 37
3.1 shell的重要性 37
3.2 内核的作用 39
3.3 装载器的作用 39
3.3.1 装载器视角下的二进制文件(节与段) 39
3.3.2 程序加载阶段 40
3.4 程序执行入口点 43
3.4.1 装载器查找入口点 43
3.4.2 _start()函数的作用 43
3.4.3 __libc_start_main()函数的作用 44
3.4.4 栈和调用惯例 44
第4章 重用概念的作用 46
4.1 静态库 46
4.2 动态库 48
4.2.1 动态库和共享库 49
4.2.2 动态链接详解 51
4.2.3 Windows平台中动态链接的特点 54
4.2.4 动态库的特点 56
4.2.5 应用程序二进制接口(ABI) 56
4.3 静态库和动态库对比 57
4.3.1 导入选择条件的差异 57
4.3.2 部署难题 59
4.4 一些有用的类比 61
4.5 结论:二进制复用概念所产生的影响 63
第5章 使用静态库 64
5.1 创建静态库 64
5.1.1 创建Linux静态库 64
5.1.2 创建Windows静态库 65
5.2 使用静态库 65
5.3 静态库设计技巧 66
5.3.1 丢失符号可见性和唯一性的可能性 66
5.3.2 静态库使用禁忌 67
5.3.3 静态库链接的具体规则 68
5.3.4 将静态库转换成动态库 68
5.3.5 静态库在64位Linux平台上的问题 68
第6章 设计动态链接库:基础篇 70
6.1 创建动态链接库 70
6.1.1 在Linux中创建动态库 70
6.1.2 在Windows中创建动态链接库 72
6.2 设计动态库 75
6.2.1 设计二进制接口 75
6.2.2 设计应用程序的二进制接口 79
6.2.3 控制动态库符号的可见性 82
6.2.4 完成链接需要满足的条件 94
6.3 动态链接模式 94
6.3.1 加载时动态链接 95
6.3.2 运行时动态链接 95
6.3.3 比较两种动态链接模式 98
第7章 定位库文件 99
7.1 典型用例场景 99
7.1.1 开发用例场景 99
7.1.2 用户运行时用例场景 100
7.2 构建过程中库文件的定位规则 101
7.2.1 Linux平台构建过程中的库文件定位规则 101
7.2.2 Windows构建过程中的库文件定位规则 105
7.3 运行时动态库文件的定位规则 109
7.3.1 Linux运行时动态库文件的定位规则 110
7.3.2 Windows运行时动态库文件的定位规则 114
7.4 示例:Linux构建时与运行时的库文件定位 115
第8章 动态库的设计:进阶篇 119
8.1 解析内存地址的必要性 119
8.2 引用解析中的常见问题 120
8.3 地址转换引发的问题 122
8.3.1 情景1:客户二进制程序需要知道动态库符号地址 122
8.3.2 情景2:被装载的库不需要知道其自身符号地址 123
8.4 链接器-装载器协作 124
8.4.1 总体策略 125
8.4.2 具体技术 126
8.4.3 链接器重定位提示概述 127
8.5 链接器-装载器协作实现技术 128
8.5.1 装载时重定位(LTR) 129
8.5.2 位置无关代码(PIC) 129
第9章 动态链接时的重复符号处理 134
9.1 重复的符号定义 134
9.2 重复符号的默认处理 137
9.3 在动态库链接过程中处理重复符号 140
9.3.1 处理重复符号问题的一般策略 142
9.3.2 链接器解析动态库重复符号的模糊算法准则 143
9.4 特定重复名称案例分析 144
9.4.1 案例1:客户二进制文件符号与动态库ABI函数冲突 144
9.4.2 案例2:不同动态库的ABI符号冲突 147
9.4.3 案例3:动态库ABI符号和另一个动态库局部符号冲突 151
9.4.4 案例4:两个未导出的动态库符号冲突 153
9.5 小提示:链接并不提供任何类型的命名空间继承 161
第10章 动态库的版本控制 162
10.1 主次版本号与向后兼容性 162
10.1.1 主版本号变更 162
10.1.2 次版本号变更 163
10.1.3 修订版本号 163
10.2 Linux动态库版本控制方案 163
10.2.1 基于soname的版本控制方案 163
10.2.2 基于符号的版本控制方案 169
10.3 Windows动态库版本控制 190
10.3.1 DLL版本信息 191
10.3.2 指定DLL版本信息 192
10.3.3 查询并获取DLL版本信息 193
第11章 动态库:其他主题 202
11.1 插件 202
11.1.1 导出规则 203
11.1.2 一些流行的插件架构 204
11.2 提示和技巧 204
11.2.1 使用动态库的实际意义 204
11.2.2 其他主题 205
第12章 Linux工具集 211
12.1 快速查看工具 211
12.1.1 file实用程序 211
12.1.2 size实用程序 212
12.2 详细信息分析工具 212
12.2.1 ldd 212
12.2.2 nm 214
12.2.3 objdump 215
12.2.4 readelf 223
12.3 部署阶段工具 229
12.3.1 chrpath 229
12.3.2 patchelf 230
12.3.3 strip 231
12.3.4 ldconfig 231
12.4 运行时分析工具 232
12.4.1 strace 232
12.4.2 addr2line 233
12.4.3 gdb(GNU调试器) 233
12.5 静态库工具 234
第13章 平台实践 238
13.1 链接过程调试 238
13.2 确定二进制文件类型 239
13.3 确定二进制文件入口点 240
13.3.1 获取可执行文件入口点 240
13.3.2 获取动态库入口点 240
13.4 列出符号信息 241
13.5 查看节的信息 242
13.5.1 列出所有节的信息 242
13.5.2 查看节的信息 242
13.6 查看段的信息 243
13.7 反汇编代码 244
13.7.1 反汇编二进制文件 244
13.7.2 反汇编正在运行的进程 244
13.8 判断是否为调试构建 244
13.9 查看加载时依赖项 245
13.10 查看装载器可以找到的库文件 245
13.11 查看运行时动态链接的库文件 245
13.11.1 strace实用程序 245
13.11.2 LD_DEBUG环境变量 246
13.11.3 /proc//maps文件 246
13.11.4 lsof实用程序 247
13.11.5 通过编程方式查看 248
13.12 创建和维护静态库 251
第14章 Windows工具集 252
14.1 库管理器(lib.exe) 252
14.1.1 使用lib.exe处理静态库 253
14.1.2 使用lib.exe处理动态库(导入库生成工具) 257
14.2 dumpbin实用程序 258
14.2.1 确定二进制文件类型 258
14.2.2 查看DLL的导出符号 258
14.2.3 查看节的信息 259
14.2.4 反汇编代码 262
14.2.5 确定是否使用了调试模式构建 263
14.2.6 查看加载时依赖项 265
14.3 Dependency Walker工具 265

教学资源推荐
作者: [美] 丹尼尔·卡斯沃姆(Daniel Kusswurm) 著
作者: [美]贝赫鲁兹·A. 佛罗赞(Behrouz A.Forouzan) 理查德·F. 吉尔伯格(Richard F. Gilberg) 著
作者: 朱鸣华,刘旭,麟杨微,罗晓芳,李慧,孙大为,赵晶
作者: [英]理查德·伯德(Richard Bird) 著
参考读物推荐
作者: 尹宝林 著
作者: 邵京京,白晶茹 等著
作者: [法]克莱门特·埃斯科菲耶(Clement Escoffier),[澳]肯·芬尼根(Ken Finnigan) 著