我们感谢您对我们文档的反馈。让我们了解如何改进它。
通过Jira提交反馈(需要帐户)
RedHatEnterpriseLinux8支持自定义应用程序的开发。要允许开发人员这样做,必须设置带有必要的工具和实用程序的系统。本章列出了开发的最常见用例和要安装的项目。
RedHatEnterpriseLinux的标准安装不会启用调试和资源存储库。这些存储库包含调试系统组件并测量其性能所需的信息。
步骤
有效的版本控制对于所有多开发人员项目非常重要。RedHatEnterpriseLinux附带了Git,一个分布式版本控制系统。
流程
其他资源
RedHatEnterpriseLinux包括用于创建C和C++应用程序的工具。
先决条件
RedHatEnterpriseLinux提供多种调试和检测工具,来分析和故障排除内部应用程序行为。
RedHatEnterpriseLinux包括多个应用程序,可帮助开发人员确定应用程序性能丢失的原因。
了解源代码必须转换为可执行代码的情况。
可能的代码形式
C和C++语言有三种形式的代码:
GCC中代码表单的处理
从源代码生成可执行代码分为两步执行,这需要不同的应用或工具。GCC可用作编译器和链接器的智能驱动程序。这允许您将单个gcc命令用于任何必要的操作(编译和链接)。GCC自动选择操作及其顺序:
可以运行GCC以便它只执行编译、只执行链接或在单个步骤中进行编译和链接。这由输入的类型和请求的输出类型来决定的。
由于较大的项目需要一个通常为每个操作单独运行GCC的构建系统,因此最好始终考虑将编译和链接作为两个不同的操作,即使GCC可以同时执行这两项操作。
要从源代码文件而不是可执行文件立即创建目标代码文件,必须指示GCC仅将目标代码文件创建为其输出。此操作代表了大型项目的构建过程的基本操作。
由于调试信息较大,因此默认情况下,不会包含在可执行文件中。要用它启用C和C++应用程序的调试,您必须明确指示编译器创建它。
要在编译和链接代码时使用GCC启用调试信息的创建,请使用-g选项:
$gcc...-g...其他资源
一个程序可以转换为多个计算机指令序列。如果在编译过程中分配更多资源来分析代码,您可以获得更优的结果。
有了GCC,您可以使用-Olevel选项设置优化级别。这个选项接受一组值来代替level。
0
编译速度的优化-无代码优化(默认)。
1,2,3
优化以加快代码执行速度(数量越多,速度越快)。
s
文件大小的优化。
fast
与级别3设置一样,fast忽略严格的标准合规性,以允许额外的优化。
g
调试体验的优化。
对于版本构建,请使用优化选项-O2。
在开发过程中,-Og选项在某些情况下对于调试程序或库很有用。由于某些bug只在某些优化级别上出现,因此请使用版本优化级别测试程序或库。
GCC提供了大量选项来启用单个优化。如需更多信息,请参阅以下额外资源。
当编译器将源代码转换为目标代码时,它可以添加各种检查来防止经常被利用的情况,并提高安全性。选择正确的编译器选项有助于生成更安全的程序和库,而无需更改源代码。
发行版本选项
对于以RedHatEnterpriseLinux为目标的开发人员,推荐使用以下选项列表:
$gcc...-O2-g-Wall-Wl,-z,now,-z,relro-fstack-protector-strong-fstack-clash-protection-D_FORTIFY_SOURCE=2...开发选项
使用以下选项来检测开发过程中的安全漏洞:使用这些选项与发行版本的选项相结合:
$gcc...-Walloc-zero-Walloca-larger-than-Wextra-Wformat-security-Wvla-larger-than...其他资源
构建C或C++应用程序时,链接是最后一步。链接将所有目标文件和库合并到一个可执行文件中。
此示例演示了构建一个简单示例C程序的确切步骤。
在本例中,编译和链接代码在一个步骤中完成。
在本例中,编译和链接代码是两个独立的步骤。
本例显示了构建最小C++程序的确切步骤。
了解在代码中使用库。
对库使用特殊文件名惯例:名为foo的库应该以文件libfoo.so或libfoo.a的形式存在。通过链接GCC的输入选项(而非输出选项)可自动理解这一惯例:
开发人员在使用完全编译的语言构建应用程序时可以选择使用静态或动态链接。务必要了解静态和动态链接之间的区别,特别是在RedHatEnterpriseLinux上使用C和C++语言的上下文中。总之,红帽不建议对RedHatEnterpriseLinux的应用程序使用静态链接。
静态和动态链接的比较
静态链接使库成为生成的可执行文件的一部分。动态链接将这些库保留为单独的文件。
可以通过多种方式比较动态和静态链接:
静态链接会导致更大的可执行文件,其中包含更多代码。这些额外的代码来自不能在系统上的多个程序之间共享的库,这会增加运行时文件系统的使用率和内存的使用率。运行同一静态链接的程序的多个进程仍将共享代码。
静态链接似乎提供独立于操作系统提供的库版本的可执行文件。但是,大多数库依赖于其他库。有了静态链接,此依赖变得不灵活,因此会丢失向前和向后兼容性。静态链接可保证仅在构建可执行文件的系统上工作。
静态链接GNUC库的应用程序(glibc)仍然需要glibc作为动态库存在于系统中。此外,在应用程序的运行时可用的glibc的动态库变体在连接应用程序时必须与当前版本按位相同。因此,静态链接保证仅在构建可执行文件的系统上工作。
某些库,特别是GNUC库(glibc),在静态链接时提供减少的功能。
例如,当静态链接时,glibc不支持线程和在同一程序中对dlopen()函数的任何形式的调用。
由于所列出的缺点,应该不惜一切代价避免静态链接,特别是对于整个应用程序以及glibc和libstdc++库。
静态链接的情况
在某些情况下静态链接可能是一种合理的选择,例如:
库是可在您的程序中重复使用的代码软件包。C或C++库由两个部分组成:
使用库编译代码
头文件描述库的接口:库中的函数和变量。编译代码需要头文件中的信息。
通常,库的头文件将被放置在与您的应用代码不同的目录中。要告诉GCC头文件的位置,请使用-I选项:
$gcc...-Iinclude_path...使用头文件目录的实际路径替换include_path。
-I选项可多次使用,以添加包含头文件的多个目录。查找头文件时,会按照它们在-I选项中出现的顺序搜索这些目录。
链接使用库的代码
链接可执行文件时,应用程序的目标代码和库的二进制代码都必须提供。静态和动态库的代码以不同的格式存在:
要告诉GCC库的存档或共享目标文件的位置,请使用-L选项:
$gcc...-Llibrary_path-lfoo...使用库目录的实际路径替换library_path。
-L选项可多次使用,以添加多个目录。查找库时,系统将按照其-L选项的顺序搜索这些目录。
选项的顺序很重要:GCC不能链接库foo,除非其知道此库的目录。因此,在使用-l选项链接库之前,请使用-L选项来指定库目录。
在一个步骤中编译和链接使用库的代码
当允许在一个gcc命令中编译并链接代码时,请同时对上述两种情况使用选项。
静态库作为包含目标文件的存档提供。链接后,它们成为生成的可执行文件的一部分。
要从源和目标文件链接程序,请添加静态链接库foo,该库可作为libfoo.a文件找到:
动态库作为独立的可执行文件提供,在链接时和运行时需要。它们独立于您应用程序的可执行文件。
将程序与动态库链接
要将程序与动态库foo链接:
$gcc...-Llibrary_path-lfoo...当程序链接了动态库时,生成的程序必须总是在运行时加载库。定位库有两个选项:
使用存储在可执行文件中的rpath值
在其被链接时,rpath是一个作为可执行文件的一部分保存的特殊值。之后,从可执行文件加载程序时,运行时链接器将使用rpath值来定位库文件。
与GCC链接时,要将路径library_path存储为rpath:
$gcc...-Llibrary_path-lfoo-Wl,-rpath=library_path...路径library_path必须指向包含文件libfoo.so的目录。
不要在-Wl,-rpath=选项中的逗号后面添加空格。
要稍后运行程序:
$./program使用LD_LIBRARY_PATH环境变量
如果在程序的可执行文件中没有找到rpath,则运行时链接器将使用LD_LIBRARY_PATH环境变量。必须为每个程序更改此变量的值。这个值应该代表共享库目标所在的路径。
要运行没有rpath设置的程序,库要存在于路径library_path中:
$exportLD_LIBRARY_PATH=library_path:$LD_LIBRARY_PATH$./program省略rpath值提供了灵活性,但每次程序运行时,都需要设置LD_LIBRARY_PATH变量。
将库放入默认目录
运行时链接器配置指定多个目录来作为动态库文件的默认位置。要使用此默认行为,请将库复制到合适的目录中。
对动态链接器行为的完整描述超出了本文档的范围。如需更多信息,请参阅以下资源:
有时需要静态链接一些库,有时需要动态链接一些库。这种情况带来了一些挑战。
简介
gcc识别动态和静态库。遇到-lfoo选项时,gcc将首先尝试查找包含foo库的动态链接版本的共享目标(一个.so文件),然后查找包含库的静态版本的存档文件(.a)。因此,这个搜索可能会导致以下情况:
由于这些规则,选择用于链接的库的静态或动态版本的最佳方法是让gcc只找到该版本。在指定-Lpath选项时,可以使用或省略包含库版本的目录,来在某种程度上控制它。
此外,由于动态链接是默认的,因此链接被明确指定的唯一情形是存在两个版本的库都应被静态链接时。有两种可能的解决方案:
通过文件指定静态库
通常,使用-lfoo选项指示gcc链接到foo库。但是,可以指定包含库的libfoo.a文件的全路径:
$gcc...path/to/libfoo.a...从文件扩展名.a,gcc将理解为这是一个与程序链接的库。但是,指定库文件的全整路径是一个不太灵活的方法。
使用-Wl选项
gcc选项-Wl是一个将选项传给底层链接器的特殊选项。此选项的语法与其他gcc选项不同。Wl选项后跟一个以逗号分隔的链接选项列表,而其他gcc选项则需要以空格分隔的选项列表。
gcc使用的ld链接器提供选项-Bstatic和-Bdynamic,来指定此选项后面的库是否应分别被静态链接或动态链接。在将-Bstatic和库传给链路器后,必须为以下使用-Bdynamic选项动态链接的库手动恢复默认的动态链接行为:
要链接程序,请静态链接库first(libfirst.a),动态链接库second(libsecond.so):
$gcc...-Wl,-Bstatic-lfirst-Wl,-Bdynamic-lsecond...注意GCC可以配置为使用默认ld以外的链接器。
了解创建库以及Linux操作系统用于库的必要概念的步骤。
动态加载的库(共享对象)使用一个名为soname的机制来管理库的多个兼容版本。
问题简介
动态加载的库(共享目标)作为一个独立的可执行文件存在。这使得可以在不更新依赖于它的应用程序的情况下更新库。但是,这个概念会出现以下问题:
soname机制
为了解决这个问题,Linux使用一种称为soname的机制。
foo库版本X.Y与版本号为X的其他版本ABI兼容。保持兼容性的次更改会增加数字Y。破坏兼容性的主更改会增加数字X。
实际的foo库版本X.Y作为文件libfoo.so.x.y存在。在库文件中,soname是使用值libfoo.so.x记录的,以表示兼容性。
当运行时动态链接器在运行前链接应用程序时,它会从应用的可执行文件中读取soname。该soname是libfoo.so.x。具有此名称的符号链接必须存在,指向实际的库文件。这允许加载库,而不考虑版本的Y组件,因为soname不会改变。
版本号Y组件号不仅限于一个数字。此外,一些库将其版本编码到其名称中。
从文件中读取soname
要显示库文件somelibrary的soname:
$objdump-psomelibrary|grepSONAME使用您要检查的库的实际文件名替换somelibrary。
动态链接的库(共享目标)允许:
按照以下步骤从源构建和安装动态库。
通过将目标文件转换为特殊类型的存档文件,可以创建用于静态链接的库。
GNUmake程序(通常缩写为make)是一个控制从源文件生成可执行文件的工具。make自动确定复杂程序的哪个部分已更改,需要重新编译。make使用名为Makefile的配置文件来控制构建程序的方式。
要从特定项目的源文件创建一个可用的表单(通常是可执行文件),请执行几个必要的步骤。记录操作及其顺序,以便稍后可重复这些操作。
RedHatEnterpriseLinux包含GNUmake,这是专为此目的设计的构建系统。
GNUmake
GNUmake读取Makefile,其中包含描述构建过程的说明。Makefile包含多个规则,它们描述了满足带有特定操作(recipe)的某一条件(target)的方法。规则可以在层次上依赖于另一条规则。
运行不带任何选项的make可使其在当前的目录中查找Makefile,并尝试到达默认目标。实际的Makefile文件名可以是Makefile、makefile和GNUmakefile中的一个。默认目标由Makefile内容决定。
Makefile详情
makefile使用相对简单的语法来定义变量和规则,这些变量和规则由一个target和一个recipe组成。目标指定执行规则后的输出是什么。带有recipe的行必须以TAB字符开头。
通常,Makefile包含用于编译源文件的规则、用于链接生成的目标文件的规则,以及充当层次结构顶部的入口点的目标。
请考虑以下用来构建由单个文件hello.c组成的C程序的Makefile。
all:hellohello:hello.ogcchello.o-ohellohello.o:hello.cgcc-chello.c-ohello.o本例演示了要到达目标all,需要文件hello。要获得hello,您需要hello.o(由gcc链接),后者是从hello.c创建的(由gcc编译)。
目标all是默认目标,因为它是不是以句点(.)开头的第一个目标。当当前目录包含这个Makefile时,运行不带任何参数的make与运行makeall一样。
典型的makefile
更为典型的Makefile使用变量来概括步骤,并添加一个目标"clean"-删除除源文件以外的任何内容。
CC=gccCFLAGS=-c-WallSOURCE=hello.cOBJ=$(SOURCE:.c=.o)EXE=helloall:$(SOURCE)$(EXE)$(EXE):$(OBJ)$(CC)$(OBJ)-o$@%.o:%.c$(CC)$(CFLAGS)$<-o$@clean:rm-rf$(OBJ)$(EXE)向此类Makefile添加更多源文件只需要将它们添加到定义了SOURCE变量的行中。
按照本示例中的步骤,使用Makefile构建一个示例C程序。
有关make的更多信息,请参阅以下列出的资源。
安装的文档
在线文档
在RedHatEnterpriseLinux8中,GCC工具链基于GCC8.2发行系列。从RedHatEnterpriseLinux7开始的显著变化包括:
Security
GCC已被扩展,提供一些工具以确保增加生成的代码的强化。
构架和处理器支持
架构和处理器支持的改进包括:
语言和标准
与语言和标准有关的显著变化包括:
其它资源
新警告
添加了这些警告选项:
-Wstringop-truncation
调用有界字符串操作函数,如strncat、strncpy和stpncpy,它们可能会截断复制的字符串或使目的地保持不变。
-Wclass-memaccess
原始功能(如memcpy或realloc)可能会以不安全的方式处理类型为非trivial类的对象。
警告有助于检测绕过用户定义的构造器或复制-赋值运算符、损坏虚拟表指针、常量限定类型或引用的数据成员或成员指针的调用。该警告还会检测到可绕过数据成员的访问控制的调用。
-Wmisleading-indentation
代码缩进对于阅读代码的人可能会造成对代码块结构的误导。
-Walloc-size-larger-than=size
调用内存分配超过size的内存分配功能。也适用于通过将两个参数相乘来指定分配的函数,也适用于使用属性alloc_size修饰的任何函数。
-Walloc-zero
调用内存分配功能,试图分配零内存。也适用于通过将两个参数相乘来指定分配的函数,也适用于使用属性alloc_size修饰的任何函数。
-Walloca
所有对alloca功能的调。
-Walloca-larger-than=size
请求内存大于size时调用alloca功能。
-Wvla-larger-than=size
可超过指定大小或者其绑定未知约束的VariableLengthArrays(VLA)定义。
-Wformat-overflow=level
对格式化输出函数的sprintf系列调用中的一定和可能的缓冲区溢出。有关level值的详情和说明,请参阅gcc(1)手册页。
-Wformat-truncation=level
对格式化输出函数的snprintf系列调用中的一定和可能的输出截断。有关level值的详情和说明,请参阅gcc(1)手册页。
-Wstringop-overflow=type
对字符串处理功能,如memcpy和strcpy的调用中的缓冲区溢出。有关level值的详情和说明,请参阅gcc(1)手册页。
警告改进
改进了以下GCC警告:
新的UndefinedBehaviorSanitizer
添加了一个新的用于检测未定义行为的运行时清理程序,称为UndefinedBehaviorSanitizer。以下选项需要加以注意:
-fsanitize=float-divide-by-zero
检查浮点被被零除。
-fsanitize=float-cast-overflow
检查浮点类型到整数转换的结果是否溢出。
-fsanitize=bounds
启用阵列绑定控制并检测对边界外的访问。
-fsanitize=alignment
启用协调检查并检测各种没有对齐的对象。
-fsanitize=object-size
启用对象大小检查并检测到各种对边界外的访问。
-fsanitize=vptr
启用对C++成员功能调用、成员访问以及指针到基本类别和派生类之间的一些转换。另外,检测引用的对象没有正确的动态类型。
-fsanitize=bounds-strict
启用对阵列绑定的严格的检查。这可启用-fsanitize=bounds,以及灵活的数组成员式数组的检测。
-fsanitize=signed-integer-overflow
即使在使用通用向量的诊断操作中诊断异常溢出。
-fsanitize=builtin
在运行时诊断__builtin_clz或__builtin_ctz前缀内置的无效参数。包括-fsanitize=undefined=undefined的检查。
-fsanitize=pointer-overflow
为指针嵌套执行cheaprun-time测试。包括-fsanitize=undefined=undefined的检查。
AddressSanitizer的新选项
这些选项已经被添加到AddressSanitizer中:
-fsanitize=pointer-compare
指向不同内存对象的指针的警告。
-fsanitize=pointer-subtract
对指向不同内存对象的指针减法的警告。
-fsanitize-address-use-after-scope
清理在定义了变量的作用域之后其地址被占用的变量。
其他清理程序和工具
std::string的应用程序二进制接口(ABI)和libstdc++库中的std::list类在RHEL7(GCC4.8)和RHEL8(GCC8)之间的变化符合C++11标准。libstdc++库同时支持旧的和新的ABI,但些其他一些C++系统库不支持。因此,动态链接这些库的应用程序需要重建。这会影响所有C++标准模式,包括C++98。它还影响了使用RHEL7的RedHatDeveloperToolset编译器构建的应用程序,这些应用程序保留了旧的ABI,以保持与系统库的兼容性。
在Ada(GNAT)、GCCGo和目标C/C++语言中构建代码的能力已从GCC编译器中删除。
要构建Go代码,请使用GoToolset。
调试应用程序是一个非常广泛的话题。本节为开发人员提供了在各种情况下进行调试的最通用的技术。
要调试应用和库,需要调试信息。以下章节描述了如何获取此信息。
在调试任何可执行代码时,两种类型的信息允许程序员通过工具和扩展来理解二进制代码:
此类信息称为调试信息。
RedHatEnterpriseLinux对可执行二进制文件、共享库或debuginfo文件使用ELF格式。在这些ELF文件中,DWARF格式用于保存调试信息。
要显示存储在ELF文件中的DWARF信息,请运行readelf-wfile命令。
STABS是一种较旧、功能较弱的格式,有时与UNIX一起使用。红帽不鼓励使用它。GCC和GDB仅在尽最大努力的基础上提供STABS生产和消费。一些其他工具,如Valgrind和elfutils,不适用于STABS。
debuginfo和debugsource软件包包含程序和库的调试信息和调试源代码。对于安装在RedHatEnterpriseLinux存储库的软件包中的应用程序和库,您可以从其它渠道获得单独的debuginfo和debugsource软件包。
调试信息软件包类型
有两种类型的软件包可用于调试:
与RHEL7的不同
在RedHatEnterpriseLinux7中,debuginfo软件包包含这两种类型的信息。RedHatEnterpriseLinux8将调试信息所需的源代码数据从debuginfo软件包分割为单独的debugsource软件包。
软件包名称
debuginfo或debugsource软件包提只对具有相同名称、版本、发行和架构的二进制软件包供有效的调试信息:
需要调试信息来调试代码。对于从软件包安装的代码,GNUDebugger(GDB)自动识别缺少的调试信息,解析软件包名称并提供有关如何获取软件包的具体建议。
您可以通过定位可执行文件,然后查找安装它的软件包来手动确定您需要安装哪些debuginfo软件包。
因为后续步骤依赖于此,所以您必须解决这种情况或中止这个过程。描述确切的故障排除步骤不在本流程范围内。
要找出应用不能正常工作的原因,请控制其执行并使用调试器检查其内部状态。本节描述了如何对此任务使用GNUDebugger(GDB)。
RedHatEnterpriseLinux包含GNU调试器(GDB),允许您通过命令行用户界面调查程序内部发生了什么情况。
GDB功能
单个GDB会话可以调试以下类型的程序:
调试要求
要调试任何可执行代码,GDB需要该特定代码的调试信息:
为了检查进程,必须将GDB附加到进程。
使用GDB启动程序
当该程序没有作为进程运行时,使用GDB启动它:
$gdbprogram使用程序的文件名或路径替换program。
设置GDB以开始程序的执行。您可以使用run命令在开始执行进程前设置断点和gdb环境。
将GDB附加到已在运行的进程
要将GDB附加到已作为进程运行的程序:
将已在运行的GDB附加到已在运行的进程
要将已在运行的GDB附加到已在运行的程序:
在某些情况下,GDB可能无法找到对应的可执行文件。使用file命令指定路径:
(gdb)filepath/to/program其他资源
GDB调试器附加到程序后,您可以使用一些命令来控制程序的执行。
单步调试代码的GDB命令
从当前状态继续程序的执行。程序的执行将继续,直到以下其中一个条件变为true:
从当前状态继续程序的执行,直到达到当前源文件中的下一行代码。程序的执行将继续,直到以下其中一个条件变为true:
恢复程序的执行,并在执行从函数返回时停止。程序的执行将继续,直到以下其中一个条件变为true:
显示程序内部变量的值对于了解程序正在做什么非常重要。GDB提供了多个您可用来检查内部变量的命令。以下是这些命令中最有用的命令:
显示给定的参数的值。通常,参数是任何复杂程度的变量的名称,从简单的单个值到结构。参数也可以是在当前语言中一个有效的表达式,包括程序变量和库函数的使用,或者在测试的程序中定义的函数。
可以使用pretty-printerPython或Guile脚本来扩展GDB,以便使用print命令来自定义对数据结构(如类、结构)的显示。
显示用于到达当前执行点的函数调用链,或者显示在执行终止之前所使用的函数链。这对于调查原因不明的严重bug(如分段错误)非常有用。
向backtrace命令中添加full选项也会显示本地变量。
可以使用framefilterPython脚本来扩展GDB,以便使用bt和infoframe命令自定义显示的数据。术语frame指的是与单个函数调用关联的数据。
info命令是提供关于各种条目的信息一个通用命令。它使用指定要描述的条目的一个选项。
如需可能的条目列表,请在GDB会话中运行命令helpinfo:
(gdb)helpinfol(list)显示源代码中程序停止的行。此命令仅在程序执行停止时才可用。虽然严格来说不是用来显示内部状态的命令,但list帮助用户了解在程序执行的下一步中内部状态将发生哪些变化。其他资源
通常,仅调查代码的一小部分。断点是标记,告知GDB在代码的特定位置停止程序的执行。断点通常与源代码行关联。在这种情况下,放置断点需要指定源文件和行号。
在很多情况下,让程序执行直到某些数据改变了或被访问是有好处的。以下示例是最常见的用例。
在GDB中使用观察点
些程序使用分叉或线程来实现并行代码执行。调试多个同步执行路径需要特殊考虑。
使用GDB调试程序
分叉是一种程序(父)创建自身(子)的一个独立副本的情况。使用以下设置和命令来影响GDB在发生分叉时执行的操作:
使用GDB调试线程程序
GDB能够调试各个线程,并且能够独立地操作和检查它们。要使GDB仅停止检查的线程,请使用命令设置不停止并在其上设置target-async。您可以将这些命令添加到.gdbinit文件。启用该功能后,GDB已准备好执行线程调试。
GDB使用当前线程的概念。默认情况下,命令仅应用于当前线程。
应用程序的可执行代码与操作系统和共享库的代码交互。记录这些交互的活动日志可在不调试实际应用程序代码的情况下充分洞察应用的行为。另外,分析应用的交互可以帮助确定错误清单的条件。
红帽企业Linux提供用于分析应用程序的交互的多种工具。
Thestrace工具主要支持记录供应用使用的系统调用(内核功能)。
ltrace工具支持将应用的用户空间调用记录到共享对象(动态库)。
在RedHatEnterpriseLinux8中,一个已知问题会阻止ltrace追踪系统可执行文件。此限制不适用于用户构建的可执行文件。
SystemTap是一个检测平台,用于在Linux系统上探测运行中的进程和内核活动。SystemTap使用自己的脚本语言来编程自定义事件处理程序。
Thestrace工具启用监控应用执行的系统(内核)调用。
益处是查看输出并将其保存到文件中。使用tee命令实现这一点:
$strace...|&teeyour_log_file.log其他资源
ltrace工具支持监控应用程序对库中可用功能(共享对象)的调用。
如需更多信息,请参阅ltrace(1)_手册页。
$ltrace...|&teeyour_log_file.log其他资源
SystemTap工具启用为内核事件注册自定义事件处理程序。与strace工具相比,它更难使用,但更有效,并支持更复杂的处理逻辑。SystemTap脚本名为trace.stp,与SystemTap一同安装,并且使用SystemTap提供对strace功能的估测。
GNUDebugger(GDB)可让您在程序执行过程中出现的各种情况下停止执行。要在程序执行系统调用时停止执行,请使用GDB捕获点。
GNUDebugger(GDB)可让您在程序执行过程中的不同情况下停止执行。要在程序收到操作系统信号时停止执行,请使用GDB捕获点。
有时,无法直接调试应用。在这些情况下,您可以在应用程序终止时收集有关应用程序的信息,然后对其进行分析。
在应用程序停止工作时,核心转储是部分应用程序内存的副本,以ELF格式存储。它包含应用的所有内部变量和堆栈,可以检查应用的最终状态。使用相应的可执行文件和调试信息进行增强时,可以使用调试器以类似于分析正在运行的程序的方式分析核心转储文件。
如果启用了此功能,Linux操作系统内核会自动记录内核转储。或者,您可以向任何正在运行的应用发送信号,以生成核心转储,而不考虑其实际状态。
某些限制可能会影响生成内核转储的功能。查看当前的限制:
$ulimit-a3.4.2.使用内核转储记录应用程序崩溃要记录应用程序崩溃,请设置核心转储保存并添加系统信息。
在本例中,重要的详细信息是文件名/usr/bin/sleep和build-id2818b2009547f780a5639c904cded443e564973eonthetext[exe]。使用此信息,您可以识别分析核心转储所需的可执行文件。
systemd的coredumpctl工具可显著简化崩溃机器中使用内核转储的工作。此流程概述了如何捕获未响应进程的内核转储。
内核转储调试的工作流允许分析程序的状态离线。在某些情况下,您可以将此工作流用于仍在运行的程序,例如难以通过进程访问环境。您可以使用gcore命令转储仍在运行的任何进程的内存。
您可以将进程内存标记为不转储。这样可以节省资源并在进程内存包含敏感数据时确保额外的安全性:例如,银行或记帐应用程序或整个虚拟机上。内核内核转储(kdump)和手动内核转储(gcore,GDB)都不会转储以这种方式标记的内存。
在某些情况下,您必须转储进程内存的所有内容,无论这些保护如何。此流程演示了如何使用GDB调试器执行此操作。
RedHatEnterpriseLinux8中提供的GDB版本包含许多改变,这些更改会破坏兼容性,特别是在直接从终端读取GDB输出的情况下。以下小节详细介绍了这些更改。
不建议解析GDB的输出。使用PythonGDBAPI或GDB机器接口(MI)的首选脚本。
为了在underferior命令行参数中启用扩展和变量替换,GDBserver现在在shell中启动与GDB相同的扩展和变量替换。
使用shell禁用:
例3.1.远程GDB底层中shell扩展的示例
这个示例演示了在RedHatEnterpriseLinux版本7和8中通过GDBserver运行/bin/echo/*命令的不同:
删除了对调试使用GNUCompilerforJava(gcj)编译的Java程序的支持。
符号转储维护命令语法现在包含文件名前的选项。因此,在RHEL7中使用GDB的命令无法在RHEL8中工作。
例如,以下命令不再将符号存储在文件中,而是生成错误消息:
(gdb)maintenanceprintsymbols/tmp/outmain.c转储维护命令的符号的新语法为:
maintprintsymbols[-pcaddress][--][filename]maintprintsymbols[-objfileobjfile][-sourcesource][--][filename]maintprintpsymbols[-objfileobjfile][-pcaddress][--][filename]maintprintpsymbols[-objfileobjfile][-sourcesource][--][filename]maintprintmsymbols[-objfileobjfile][--][filename]线程号不再是全局的在以前的版本中,GDB只使用全局线程编号。数字已扩展为以inferior_num.thread_num形式显示,如2.1。因此,$_threadconvenience变量和InferiorThread.numPython属性中的线程数字在inferiors之间不再是唯一的。
GDB现在为每个线程存储第二个线程ID,称为全局线程ID,这是上一个发行版中线程编号的新数量。要访问全局线程号,请使用$_gthreadconvenience变量和InferiorThread.global_numPython属性。
为了向后兼容,MachineInterface(MI)线程ID始终包含全局ID。
例3.2.GDB线程数更改示例
在RedHatEnterpriseLinux7上:
#debuginfo-installcoreutils$gdb-batch-ex'fileecho'-exstart-ex'add-inferior'-ex'inferior2'-ex'fileecho'-exstart-ex'infothreads'-ex'pring$_thread'-ex'inferior1'-ex'pring$_thread'(...)IdTargetIdFrame*2process203923"echo"main(argc=1,argv=0x7fffffffdb88)atsrc/echo.c:1091process203914"echo"main(argc=1,argv=0x7fffffffdb88)atsrc/echo.c:109$1=2(...)$2=1在RedHatEnterpriseLinux8中:
#dnfdebuginfo-installcoreutils$gdb-batch-ex'fileecho'-exstart-ex'add-inferior'-ex'inferior2'-ex'fileecho'-exstart-ex'infothreads'-ex'pring$_thread'-ex'inferior1'-ex'pring$_thread'(...)IdTargetIdFrame1.1process4106488"echo"main(argc=1,argv=0x7fffffffce58)at../src/echo.c:109*2.1process4106494"echo"main(argc=1,argv=0x7fffffffce58)at../src/echo.c:109$1=1(...)$2=1值内容的内存可能会受限制在以前的版本中,GDB不会限制为值内容分配的内存量。因此,调试不正确的程序可能会导致GDB分配过多的内存。已添加max-value-size设置来限制分配的内存量。这个限制的默认值为64KiB。因此,RedHatEnterpriseLinux8中的GDB不会显示太大的值,而是会报告这个值太大。
例如,打印一个定义为chars[128*1024];的值会生成不同的结果:
对Sun版本的stabs调试文件格式的支持已删除。GDB仍然支持GCC在RHEL中通过gcc-gstabs选项生成的stabs格式。
当搜索调试所需文件时,使用setsysrootpath命令指定系统根。现在,为这个命令提供的目录名可能会有字符串target:前缀,它使GDB从目标系统中(本地和远程)对共享的库。以前可用的remote:前缀现在被视为目标:此外,默认的系统根值已从空字符串更改为target:用于向后兼容。
当GDB远程启动进程时,或者当它连接到已经运行的进程(本地和远程)时,会预先指定系统root的文件名。这意味着,对于远程进程,默认值为target:GDB始终会尝试从远程系统加载调试信息。要防止这种情况,请在targetremote命令前运行setsysroot命令,这样本地符号文件会在远程符号文件之前被发现。
在以前的版本中,GDB使用HISTSIZE环境变量来确定应保留命令历史记录的时长。GDB已改为使用GDBHISTSIZE环境变量。该变量只适用于GDB。可能的值及其影响有:
现在可以使用setmax-completions命令来限制在完成过程中考虑的最大候选数。若要显示当前限制,请运行showmax-completions命令。默认值为200。这个限制可防止GDB生成太大的完成列表,并且变得无响应。
例如,输入p
HP-UXXDB兼容模式的-xdb选项已从GDB中删除。
在以前的版本中,GDB可以向当前线程发送信号,而不是实际发送信号的线程。这个程序错误已被解决,GDB现在总是在恢复执行时将信号传递给正确的线程。
此外,sign命令现在始终正确地将请求的信号传送到当前线程。如果程序因信号和用户切换线程而停止,GDB将请求确认。
breakpointalways-inserted设置已被更改。已删除auto值和对应行为。默认值现在为off。另外,off值现在会导致GDB不会从目标中删除断点,直到所有线程都停止。
setremotebaud和showremotebaud命令不再被支持。使用设置的serialbaud并改为显示serialbaud命令。
您可以使用为故障排除的不同方面量身定制的各种命令行工具。以下提供类别以及常见的命令行工具。
这不是命令行工具的完整列表。用于调试容器应用的工具选择主要基于容器镜像和您的用例。
例如,systemctl,journalctl,ip,netstat,ping,traceroute,perf,iostat工具可能需要root访问权限,因为它们与系统级别的资源(如网络、systemd服务或硬件性能计数器)进行交互,这些在无根容器中受到限制。
Rootless容器在不需要提升特权的情况下运行,在用户命名空间中运行,以改进与主机系统的安全性和隔离。它们通过降低特权升级漏洞的风险,与主机提供有限的交互,降低攻击面并提高安全性。
rootful容器以提升的特权运行,通常以root用户身份运行,从而授予系统资源和功能的完整访问权限。虽然rootful容器提供更大的灵活性和控制,但它们会带来安全风险,因为他们可能会升级特权升级并暴露主机系统漏洞。
systemd和进程管理工具
网络工具
流程和性能工具
安全和访问控制工具
特定于podman的工具
GCCToolset以AppStream存储库中的软件集合的形式作为ApplicationStream提供。在RedHatEnterpriseLinux订阅级别协议中完全支持GCC工具集,其功能完整,并适用于生产用途。GCCToolset提供的应用程序和库不会替换RedHatEnterpriseLinux系统版本,不会覆盖它们,也不会自动成为默认选择或首选选择。使用名为软件集合的框架,另一组开发人员工具安装到/opt/目录中,用户利用scl实用程序根据需要明确启用。除非对特定工具或功能另有说明,否则GCC工具集适用于红帽企业Linux支持的所有架构。
在系统上安装GCCToolset会安装主要工具和所有必需的依赖项。请注意,工具集的某些部分默认未安装,必须单独安装。
要仅从GCCToolset而不是整个工具集安装某些工具,请列出可用的软件包并使用yum软件包管理工具安装选定的软件包。此流程也适用于默认情况下没有使用工具集安装的软件包。
要从您的系统中删除GCC工具集,请使用yum软件包管理工具卸载它。
要从GCCToolset运行工具,请使用thescl实用程序。
GCCToolset允许运行使用GCC工具集工具版本而不是这些工具的系统版本的shell会话,而无需显式使用scl命令。这在您需要多次以交互方式启动工具时很有用,例如在设置或测试开发设置时。
了解特定于GCCToolset版本9以及这个版本中包含的工具的信息。
GCCToolset9提供了以下工具和版本:
GCC
9.2.1
便携式编译器套件,支持C、C++和Fortran。
GDB
8.3
命令行调试器,适用于使用C、C++和Fortran编写的程序。
Valgrind
3.15.0
检测框架和许多工具来对应用进行性能分析,以检测内存错误、识别内存管理问题并报告系统调用中未使用的参数。
SystemTap
4.1
跟踪和探测工具,可监控整个系统的活动,无需检测、重新编译、安装和重新启动。
Dyninst
10.1.0
执行期间检测和使用用户空间可执行文件的库。
binutils
2.32
一组二进制工具和其他实用程序,用于检查和操作对象文件和二进制文件。
elfutils
0.176
用于检查和操作ELF文件的二进制工具和其他实用程序的集合。
dwz
0.12
用于优化ELF共享库和ELF可执行文件中包含的DWARF调试信息的工具。
make
4.2.1
依赖项跟踪构建自动化工具。
strace
5.1
用于监控程序使用的系统调用并发出信号的调试工具。
ltrace
0.7.91
用于显示对程序所进行的动态库的调用的调试工具。它还可以监控程序执行的系统调用。
annobin
9.08
构建安全检查工具.
此处提供的兼容性信息仅适用于GCCToolset9中的GCC。
GCCToolset中的GCC编译器可以使用以下C++标准:
这是GCCToolset9的默认语言标准设置,其GNU扩展等同于使用选项-std=gnu++14。
当使用GCC版本6或更高版本构建了使用相应标记编译的所有C++对象时,支持使用C++14语言版本。
GCCToolset9中提供此语言标准。
当使用GCC版本5或更高版本构建了使用相应标记编译的所有C++对象时,支持使用C++11语言版本。
所有语言标准均可在符合标准的变体或GNU扩展中找到。
将与GCCToolset构建的对象与通过RHEL工具链构建的对象(particularly.o或.a文件)混合时,应将GCCToolset工具链用于任何链接。这可确保任何仅由GCCToolset提供的更新库功能在链接时得以解决。
库的静态链接
某些较新的库功能已静态链接到使用GCC工具集构建的应用程序中,以支持在多个版本的RedHatEnterpriseLinux中执行。这会产生另外一个小的安全风险,因为标准的RedHatEnterpriseLinux勘误表不会改变这个代码。如果开发人员出于此风险而需要重建其应用,红帽将使用安全勘误对此进行沟通。
由于这种额外的安全风险,开发人员强烈建议不要出于相同的原因将整个应用程序静态链接。
在链接时在对象文件后指定库
在GCCToolset中,库使用链接器脚本链接,这些脚本可能通过静态存档指定一些符号。这需要确保与红帽企业Linux的多个版本兼容。但是,链接器脚本使用对应共享对象文件的名称。因此,链接器使用与预期不同的符号处理规则,在指定对象文件选项前,在指定对象文件选项前不会识别对象文件所需的符号:
$sclenablegcc-toolset-9'gcc-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-9'gccobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的GCC版本时,这个建议也适用。
$sclenablegcc-toolset-9'ld-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-9'ldobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的binutils版本时,这个建议也适用。
了解特定于GCCToolset版本10以及此版本中包含的工具的信息。
GCCToolset10提供以下工具和版本:
10.2.1
9.2
3.16.0
4.4
2.35
0.182
5.7
9.29
此处提供的兼容性信息仅适用于GCCToolset10中的GCC。
这是GCCToolset10的默认语言标准设置,其GNU扩展等同于使用-std=gnu++14。
此语言标准在GCCToolset10中可用。
$sclenablegcc-toolset-10'gcc-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-10'gccobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的GCC版本时,这个建议也适用。
$sclenablegcc-toolset-10'ld-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-10'ldobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的binutils版本时,这个建议也适用。
了解特定于GCCToolset版本11以及此版本中包含的工具的信息。
GCCToolset11提供以下工具和版本:
11.2.1
10.2
3.17.0
4.5
11.0.0
2.36.1
0.185
0.14
4.3
5.13
10.23
此处所提供的兼容性信息仅适用于GCCToolset11中的GCC。
此语言标准在GCCToolset11中提供。
这是GCCToolset11的默认语言标准设置,它使用GNU扩展,相当于使用-std=gnu++17选项明确设置。
当使用GCC版本10或更高版本构建了使用相应标记编译的所有C++对象时,支持使用C++17语言版本。
此语言标准在GCCToolset11中仅作为实验性、不稳定和不受支持的功能提供。此外,还无法保证使用此标准构建的对象、二进制文件和库的兼容性。
要启用C++20支持,请将命令行选项-std=c++20添加到g++命令行。
要启用C++23支持,将命令行选项-std=c++2b添加到g++命令行。
$sclenablegcc-toolset-11'gcc-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-11'gccobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的GCC版本时,这个建议也适用。
$sclenablegcc-toolset-11'ld-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-11'ldobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的binutils版本时,这个建议也适用。
了解特定于GCCToolset版本12以及此版本中包含的工具的信息。
GCCToolset12提供以下工具和版本:
12.2.1
11.2
2.38
11.08
这里给出的兼容性信息只适用于GCCToolset12中的GCC。
这个语言标准包括在GCCToolset12中。
这是GCCToolset12的默认语言标准设置,它相当于使用-std=gnu++17选项进行显式使用。
这个语言标准只在GCCToolset12中作为实验性、不稳定和不受支持的功能提供。此外,还无法保证使用此标准构建的对象、二进制文件和库的兼容性。
要启用C++23支持,请在g++命令行中添加命令行选项-std=c++23。
$sclenablegcc-toolset-12'gcc-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-12'gccobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的GCC版本时,这个建议也适用。
$sclenablegcc-toolset-12'ld-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-12'ldobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的binutils版本时,这个建议也适用。
在某些情况下,由于GCCToolset12中的annobin和gcc之间的同步问题,您的编译可能会失败,并显示类似如下的错误消息:
cc1:fatalerror:inaccessiblepluginfileopt/rh/gcc-toolset-12/root/usr/lib/gcc/architecture-linux-gnu/12/plugin/gcc-annobin.soexpandedfromshortpluginnamegcc-annobin:Nosuchfileordirectory要临时解决这个问题,请从annobin.so文件中创建一个符号链接到gcc-annobin.so文件中:
#cd/opt/rh/gcc-toolset-12/root/usr/lib/gcc/architecture-linux-gnu/12/plugin#ln-sannobin.sogcc-annobin.so使用您系统中使用的构架替换architecture:
了解特定于GCCToolset版本13的信息以及此版本中包含的工具。
GCCToolset13提供以下工具和版本:
13.2.1
12.1
2.40
12.32
此处显示的兼容性信息只适用于GCCToolset13中的GCC。
这个语言标准在GCCToolset13中提供。
这是GCCToolset13的默认语言标准设置,带有GNU扩展,相当于明确使用-std=gnu++17选项。
在GCCToolset13中,这些语言标准仅作为实验性、不稳定和不支持的功能提供。此外,还无法保证使用此标准构建的对象、二进制文件和库的兼容性。
要启用C++20标准,请在g++命令行中添加命令行选项-std=c++20。
要启用C++23标准,请在g++命令行中添加命令行选项-std=c++23。
$sclenablegcc-toolset-13'gcc-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-13'gccobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的GCC版本时,这个建议也适用。
$sclenablegcc-toolset-13'ld-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-13'ldobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的binutils版本时,这个建议也适用。
在某些情况下,由于GCCToolset13中annobin和gcc之间的同步问题,您的编译可能会失败,并显示类似如下的错误消息:
cc1:fatalerror:inaccessiblepluginfileopt/rh/gcc-toolset-13/root/usr/lib/gcc/architecture-linux-gnu/13/plugin/gcc-annobin.soexpandedfromshortpluginnamegcc-annobin:Nosuchfileordirectory要临时解决这个问题,请从annobin.so文件中创建一个符号链接到gcc-annobin.so文件中:
#cd/opt/rh/gcc-toolset-13/root/usr/lib/gcc/architecture-linux-gnu/13/plugin#ln-sannobin.sogcc-annobin.so使用您系统中使用的构架替换architecture:
了解特定于GCCToolset版本14以及此版本中包含的工具的信息。
GCCToolset14提供以下工具和版本:
14.2.1
14.2
2.41
12.70
此处给出的兼容性信息只适用于GCCToolset14中的GCC。
这个语言标准包括在GCCToolset14中。
这是GCCToolset14的默认语言标准设置,它相当于明确使用option-std=gnu++17。
GCCToolset14中仅作为实验性、不稳定和不受支持的功能提供这些语言标准。此外,还无法保证使用此标准构建的对象、二进制文件和库的兼容性。
$sclenablegcc-toolset-14'gcc-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-14'gccobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的GCC版本时,这个建议也适用。
$sclenablegcc-toolset-14'ld-lsomelibobjfile.o'以这种方式使用GCCToolset中的库会导致未定义引用的符号链接器错误消息。要防止这个问题,请遵循标准链接实践,并在指定对象文件的选项后指定添加库的选项:
$sclenablegcc-toolset-14'ldobjfile.o-lsomelib'请注意,在使用基本RedHatEnterpriseLinux的binutils版本时,这个建议也适用。
在某些情况下,由于GCCToolset14中的annobin和gcc之间的同步问题,您的编译可能会失败,并显示类似如下的错误消息:
cc1:fatalerror:inaccessiblepluginfileopt/rh/gcc-toolset-14/root/usr/lib/gcc/architecture-linux-gnu/14/plugin/gcc-annobin.soexpandedfromshortpluginnamegcc-annobin:Nosuchfileordirectory要临时解决这个问题,请从annobin.so文件中创建一个符号链接到gcc-annobin.so文件中:
#cd/opt/rh/gcc-toolset-14/root/usr/lib/gcc/architecture-linux-gnu/14/plugin#ln-sannobin.sogcc-annobin.so使用您系统中使用的构架替换architecture:
仅支持GCCToolset14容器镜像。之前GCCToolset版本的容器镜像已弃用。
GCCToolset14组件在GCCToolset14Toolchain容器镜像中提供。
GCCToolset容器镜像基于rhel8基础镜像,可用于RHEL8支持的所有架构:
GCCToolset14Toolchain内容
rhel8/gcc-toolset-14-toolchain容器镜像由以下组件组成:
gcc
gcc-toolset-14-gcc
g++
gcc-toolset-14-gcc-c++
gfortran
gcc-toolset-14-gcc-gfortran
gdb
gcc-toolset-14-gdb
下面的部分论述了如何访问并运行GCCToolset容器镜像。
本例演示了如何拉取和开始使用GCCToolset14Toolchain容器镜像。
RHEL8提供以下编译器工具集作为ApplicationStreams:
Annobin项目是Watermark规范项目的实施。水印规范项目旨在向可执行文件和可链接格式(ELF)对象添加标记以确定其属性。Annobin项目由annobin插件和annockeck程序组成。
annobin插件扫描GNUCompilerCollection(GCC)命令行、编译状态和编译过程,并生成ELF注释。ELF注释记录了二进制文件的构建方式,并为annocheck程序提供信息,以执行安全强化检查。
安全强化检查器是annocheck程序的一部分,默认启用。它检查二进制文件,以确定是否使用必要的安全强化选项构建程序并正确编译。nocheck能够递归扫描ELF对象文件的目录、存档和RPM软件包。
文件必须采用ELF格式。anocheck不会处理任何其他二进制文件类型。
下面的部分描述了如何:
下面的部分论述了如何通过gcc和clang启用annobin插件。
下面的部分论述了如何通过gcc和clang将选项传递给annobin插件。
下面的部分论述了如何使用annocheck检查:
无检查会以递归方式扫描ELF对象文件的目录、存档和RPM软件包。文件必须采用ELF格式。anocheck不会处理任何其他二进制文件类型。
下面的部分论述了如何使用annocheck检查ELF文件。
文件必须采用ELF格式。anocheck不会处理任何其他二进制文件类型。nocheck进程包含ELF对象文件的静态库。
其他信息
下面的部分论述了如何使用annocheck检查目录中的ELF文件。
annocheck只查找ELF文件。忽略其他文件类型。
下面的部分论述了如何使用annocheck检查RPM软件包中的ELF文件。
annocheck包含用于检查二进制文件的多个工具。您可以通过命令行选项启用这些工具。
下面的部分论述了如何启用:
您可以同时启用多个工具。
默认启用强化检查器。
您可以使用annocheckbuild-by工具查找构建二进制文件的编译器的名称。
您可以使用annocheck备注工具显示由annobin插件创建的二进制文件内存储的注释。
您可以使用annocheck部分-size工具显示指定部分的大小。
默认启用强化检查器。您可以使用--disable-hardened命令行选项禁用强化检查程序。
annocheck程序检查以下选项:
下面的部分论述了如何禁用强化检查器。
使用annobin会增加二进制文件的大小。要减少使用annobin编译的二进制文件的大小,您可以删除冗余annobin备注。要删除冗余的annobin注释,请使用objcopy程序,该程序是binutils软件包的一部分。
在这个版本中,librtkaio库已被删除。此库为某些文件提供了高性能实时异步I/O访问,该文件基于Linux内核异步I/O支持(KAIO)。
删除后:
librtkaio用户有以下选项:
librt和libaio都可以在特定条件下提供可比的功能和性能。
请注意,libaio软件包的红帽兼容性级别为2,而librtkaio和移除的librtkaio级别1。
glibc库不再为新应用程序提供SunRPC和NIS接口。现在,这些接口仅适用于运行传统应用程序。开发人员必须更改其应用程序以使用libtirpc库,而不是SunRPC和libnsl2而不是NIS。应用可从替换库中的IPv6支持中受益。
在以前的版本中,glibci686软件包包含一个替代glibc构建,它避免使用带有负偏移(nosegneg)的线程描述符片段注册。此备选构建仅在没有硬件虚拟化支持的Xen项目系统管理程序的32位版本中使用,作为降低完全半虚拟化成本的优化。这些替代构建不再使用,它们已被删除。
有关运算符和函数之间的更多详细信息和差异,请参阅GNUmakemanual。
由valgrind-openmpi软件包提供的Valgrind的libmpiwrap.so包装器库已被删除。这个库启用了Valgrind使用MessagePassingInterface(MPI)调试程序。这个库专用于之前版本的RedHatEnterpriseLinux中的OpenMPI实施版本。
建议libmpiwrap.so用户从特定于其MPI实施和版本的上游源构建自己的版本。利用LD_PRELOAD技术,将这些自定义的库提供给Valgrind。
在以前的版本中,valgrind-devel子软件包用于包含用于开发自定义valgrind工具的开发文件。在这个版本中会删除这些文件,因为它们没有保证的API,所以必须静态链接,且不受支持。valgrind-devel软件包仍包含用于valgrind-aware程序和标头文件的开发文件,如valgrind.h、callgrind.h、drd.h、helgrind.h和memcheck.h,它们稳定且受到良好支持。
要在RedHatEnterpriseLinux8上运行RedHatEnterpriseLinux6或7应用程序,可以使用一系列选项。系统管理员需要应用开发人员提供的详细指导。以下列表概述了红帽提供的选项、注意事项和资源。
这个选项提供最低的资源成本,但也有最严格的要求。应用程序开发人员必须确定RHEL8系统的正确配置。以下资源可帮助开发人员完成此任务: