Developing C and C++ applications in RHEL 10
大约 52 分钟
Developing C and C++ applications in RHEL 10
来源:官方文档 原始多页入口:Developing C and C++ applications in RHEL 10 内容规模:约 129,572 字符,99 个章节标题,233 个命令/代码块,34 条提示框
阅读提要
- 副标题:Configuring a developer workstation, and developing and debugging C and C++ applications in Red Hat Enterprise Linux 10
- 摘要:Use the different features and utilities available in Red Hat Enterprise Linux 10 to develop and debug C and C++ applications.
- 主要章节:Configuring a developer workstation, and developing and debugging C and C++ applications in Red Hat Enterprise Linux 10;第 1 章 Preparing a development workstation;第 2 章 Creating C or C++ Applications;第 3 章 Debugging Applications;第 4 章 Using the gcc-toolset-15 container image;第 5 章 Additional toolsets for development;第 6 章 Notable changes in RHEL 10
- 推荐阅读顺序:先看“阅读提要”和目录,再按章节查看“关键点/命令/注意”;需要原文细节时点击来源链接。
章节笔记
概览
- 该章节主要为下一级主题的入口。
Configuring a developer workstation, and developing and debugging C and C++ applications in Red Hat Enterprise Linux 10
- 要点:摘要
第 1 章 Preparing a development workstation
- 要点:Red Hat Enterprise Linux 10 supports development of custom applications. Learn about common development use cases and the required tools. You must ensure that the RHEL system, including a graphical environment, is installed and subscribed.
1.1. Enabling debug and source repositories
- 要点:To debug system components and measure their performance, enable the debug and source repositories. These repositories contain the required information for debugging and profiling but are disabled by default in a standard Red Hat Enterprise Linux installation.
- 要点:Procedure
- 列表:Enable the BaseOS debug information package channel: # subscription-manager repos --enable rhel-10-for-$(uname -i)-baseos-debug-rpms
- 列表:Enable the BaseOS source package channel: # subscription-manager repos --enable rhel-10-for-$(uname -i)-baseos-source-rpms
- 列表:Enable the AppStream debug information package channel: # subscription-manager repos --enable rhel-10-for-$(uname -i)-appstream-debug-rpms
- 列表:Enable the AppStream source package channel: # subscription-manager repos --enable rhel-10-for-$(uname -i)-appstream-source-rpms The $(uname -i) part is automatically replaced with a matching value for architecture of your system: Expand 表 1.1. Values produced by $(uname -i) for each architecture Architecture name Val…
- 命令/配置摘录:
# subscription-manager repos --enable rhel-10-for-$(uname -i)-baseos-debug-rpms
# subscription-manager repos --enable rhel-10-for-$(uname -i)-baseos-source-rpms- 表格样本(共 5 行):
- Architecture name | Value
- 64-bit Intel and AMD | x86_64
- 64-bit ARM | aarch64
- IBM POWER | ppc64le
1.2. Installing Git for managing application versions
- 要点:To manage application versions in multi-developer projects, use Git, a distributed version control system included in Red Hat Enterprise Linux.
- 要点:Procedure
- 列表:Install the git package: # dnf install git
- 列表:Optional: Set the full name associated with your Git commits: $ git config --global user.name "Full_Name"
- 列表:Optional: Set the email address associated with your Git commits: $ git config --global user.email "email@example.com" Replace Full Name and email@example.com with your name and email address.
- 列表:Optional: To change the default text editor started by Git, set the value of the core.editor configuration option: $ git config --global core.editor command Replace command with the command to be used to start the selected text editor.
- 列表:Pro Git
- 列表:Reference
- 命令/配置摘录:
# dnf install git
$ git config --global user.name "Full_Name"1.3. Installing development tools for C and C++
- 要点:To develop applications using C and C++, install the necessary development tools and compilers provided by Red Hat Enterprise Linux. This procedure describes how to install the standard development tools, including the GNU Compiler Collection (GCC), GNU Debugger (GDB), and the LLVM toolset.
- 要点:Prerequisites
- 列表:The debug and source repositories must be enabled.
- 列表:Install the Development Tools package group including GNU Compiler Collection (GCC), GNU Debugger (GDB), and other development tools: # dnf group install "Development Tools"
- 列表:Install the LLVM-based toolchain including the clang compiler and the lld linker: # dnf install llvm-toolset
- 列表:Optional: For Fortran dependencies, install the GNU Fortran compiler: # dnf install gcc-gfortran
- 命令/配置摘录:
# dnf group install "Development Tools"
# dnf install llvm-toolset1.4. Installing tools for debugging applications
- 要点:To analyze and troubleshoot internal application behavior, {ProductName} offers multiple debugging and instrumentation tools.
- 要点:Prerequisites
- 列表:The debug and source repositories is enabled.
- 列表:Install the tools for debugging: # dnf install gdb valgrind systemtap ltrace strace
- 列表:Install the dnf-utils package to use the debuginfo-install tool: # dnf install dnf-utils
- 列表:Run a SystemTap helper script to prepare the environment: # stap-prep Note that stap-prep installs packages relevant to the currently running kernel, which might not be the same as the installed kernel. To ensure stap-prep installs the correct kernel-debuginfo and kernel-headers packages, double-check the current kern…
- 列表:Enabling debugging with debugging information
- 命令/配置摘录:
# dnf install gdb valgrind systemtap ltrace strace
# dnf install dnf-utils1.5. Installing tools for measuring application performance
- 要点:To identify the causes of application performance loss, use the performance measurement tools included in Red Hat Enterprise Linux, such as perf, papi, valgrind, and SystemTap.
- 要点:Prerequisites
- 列表:The debug and source repositories are enabled.
- 列表:Install the tools for performance measurement: # dnf install perf papi pcp-zeroconf valgrind strace sysstat systemtap
- 列表:Run a SystemTap helper script to prepare the environment. # stap-prep Note that stap-prep installs packages relevant to the currently running kernel, which might not be the same as the installed kernel. To ensure stap-prep installs the correct kernel-debuginfo and kernel-headers packages, double-check the current kern…
- 列表:Enable and start the Performance Co-Pilot (PCP) collector service: # systemctl enable pmcd && systemctl start pmcd
- 命令/配置摘录:
# dnf install perf papi pcp-zeroconf valgrind strace sysstat systemtap
# stap-prep第 2 章 Creating C or C++ Applications
- 要点:Red Hat offers multiple tools for creating applications by using the C and C++ languages. Learn about some of the most common development tasks.
2.1. GCC in RHEL 10
- 要点:Red Hat Enterprise Linux 10 is distributed with the GNU Compiler Collection (GCC) 14 as the standard compiler.
- 要点:The default language standard setting for GCC 14 is C++17. This is equivalent to explicitly using the command-line option -std=gnu++17.
- 列表:Porting to GCC 12
- 列表:Porting to GCC 13
- 列表:Porting to GCC 14
2.2. Building code with GCC
- 要点:Transform source code into executable code. Compile source files, link object code, and understand the relationship between different code forms. Optimize, harden, and debug your applications by using GCC.
2.2.1. Relationship between code forms
- 要点:The C and C++ languages have three forms of code that are created through different stages of the build process. Understanding these relationships helps you work effectively with the GNU Compiler Collection (GCC).
- 要点:The code forms of C and C++ languages:
- 列表:Source code written in the C or C++ language, present as plain text files. The files typically use extensions such as .c, .cc, .cpp, .h, .hpp, .i, .inc. For a complete list of supported extensions and their interpretation, see the gcc manual pages: $ man gcc
- 列表:Object code, created by compiling the source code with a compiler. This is an intermediate form. The object code files use the .o extension.
- 列表:Executable code, created by linking object code with a linker. Linux application executable files do not use any file name extension. Shared object (library) executable files use the .so file name extension.
- 列表:Source files are compiled to object files.
- 列表:Object files and libraries are linked (including the previously compiled sources).
- 列表:Static and dynamic linking
- 命令/配置摘录:
$ man gcc- 注意:注意 Library archive files for static linking also exist. This is a variant of object code that uses the .a file name extension. Do not use static linking.
2.2.2. Compiling source files to object code
- 要点:To create object code files from source files without creating an executable file immediately, instruct GCC to create only object code files as its output. This is a basic operation of the build process for larger projects.
- 要点:Prerequisites
- 列表:C or C++ source code file(s)
- 列表:GCC installed on the system
- 列表:At the command line, change to the directory containing the source code file(s).
- 列表:Run gcc with the -c option: $ gcc -c source.c another_source.c Object files are created, with their file names reflecting the original source code files: source.c results in source.o. 注意 With C++ source code, replace the gcc command with g++ for convenient handling of C++ Standard Library dependencies.
- 列表:Options for hardening code with GCC
- 列表:Code optimization with GCC
- 命令/配置摘录:
$ gcc -c source.c another_source.c- 注意:注意 With C++ source code, replace the gcc command with g++ for convenient handling of C++ Standard Library dependencies.
2.2.3. Enabling debugging of C and C++ applications with the GCC
- 要点:To debug C and C++ applications effectively, generate debugging information during compilation. Use GCC’s -g option to create this data. Debuggers use this data to map executable code to source lines for inspecting variables and logic.
- 要点:Prerequisites
- 列表:You have the gcc package installed.
- 列表:Compile and link your code with the -g option to generate debugging information: $ gcc ... -g ...
- 列表:Optional: Set the optimization level to -Og: $ gcc ... -g -Og ... Compiler optimizations can make executable code hard to relate to the source code. The -Og option optimizes the code without interfering with debugging. However, be aware that changing optimization levels can alter the program’s behavior.
- 列表:Optional: Use -g for moderate debugging information, or -g3 to include macro definitions: $ gcc ... -g3 ...
- 列表:Test the code by using the -fcompare-debug GCC option: $ gcc -fcompare-debug ... This option tests code compiled with and without debug information. If the resulting binaries are identical, the executable code is not affected by debugging options. By using the -fcompare-debug option significantly increases compilation…
- 列表:Enabling debugging with debugging information
- 命令/配置摘录:
$ gcc ... -g ...
$ gcc ... -g -Og ...2.2.4. Code optimization with the GCC
- 要点:Compiler optimization transforms your code for efficiency. Use GCC options to balance compilation time with execution speed or binary size suitable for your deployment. Selecting the appropriate optimization level helps you achieve faster execution or smaller binaries for your application.
- 要点:With GCC, you can set the optimization level by using the -Olevel option. This option accepts a set of values in place of the level.
- 列表:Options That Control Optimization
- 表格样本(共 6 行):
- Level | Description
- 0 | Optimize for compilation speed - no code optimization (default).
- 1, 2, 3 | Optimize to increase code execution speed (the larger the number, the greater the speed).
- s | Optimize for file size.
2.2.5. Options for hardening code with the GCC
- 要点:To add security checks during code compilation, you can use GNU Compiler Collection (GCC) compiler options. This helps produce more secure programs and libraries without changing source code.
- 要点:The following list of options is the recommended minimum for developers targeting Red Hat Enterprise Linux:
- 列表:For programs, add the -fPIE and -pie Position Independent Executable options.
- 列表:For dynamically linked libraries, the mandatory -fPIC (Position Independent Code) option indirectly increases security.
- 列表:Defensive Coding Guide
- 列表:Compiler Options Hardening Guide for C and C++
- 列表:Memory Error Detection Using GCC
- 命令/配置摘录:
$ gcc ... -O2 -g -Wall -Wl,-z,now,-z,relro -fstack-protector-strong -fstack-clash-protection -D_FORTIFY_SOURCE=3 ...
$ gcc ... -Walloc-zero -Walloca-larger-than -Wextra -Wformat-security -Wvla-larger-than ...2.2.6. Linking code to create executable files
- 要点:To create an executable file, linking combines all object files and libraries. This is the final step when building a C or C++ application.
- 要点:Prerequisites
- 列表:One or more object file(s)
- 列表:GCC must be installed on the system
- 列表:Change to the directory containing the object code file(s).
- 列表:Run gcc: $ gcc ... objfile.o another_object.o ... -o executable-file An executable file named executable-file is created from the supplied object files and libraries. To link additional libraries, add the required options after the list of object files. For more information, see Using libraries with GCC. 注意 With C++ s…
- 列表:Building code with GCC
- 列表:Static and dynamic linking
- 命令/配置摘录:
$ gcc ... objfile.o another_object.o ... -o executable-file- 注意:注意 With C++ source code, replace the gcc command with g++ for convenient handling of C++ Standard Library dependencies.
2.2.7. Example: Building a C program with the GCC (compiling and linking in one step)
- 要点:To build a basic C program, use GCC to compile source code directly into an executable. This single-step compilation command creates a foundation for developing simple applications on Red Hat Enterprise Linux.
- 要点:Procedure
- 列表:Create a directory hello-c: $ mkdir hello-c
- 列表:Change to the created directory: $ cd hello-c
- 列表:Create file hello.c with the following contents: #include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
- 列表:Compile and link the code with GCC: $ gcc hello.c -o helloworld This compiles the code, creates the object file hello.o, and links the executable file helloworld from the object file.
- 列表:Run the resulting executable file: $ ./helloworld Hello, World!
- 列表:Example: Building a C program using a Makefile
- 命令/配置摘录:
$ mkdir hello-c
$ cd hello-c2.2.8. Example: Building a C program with the GCC (compiling and linking in two steps)
- 要点:To build a simple C program, compile a source file into an object file and then link it to create an executable. This two-step process demonstrates the fundamentals of how to use the GNU Compiler Collection (GCC) compiler workflow for C development.
- 要点:Procedure
- 列表:Create a directory hello-c: $ mkdir hello-c
- 列表:Change to the created directory: $ cd hello-c
- 列表:Create file hello.c with the following contents: #include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
- 列表:Compile the code with GCC: $ gcc -c hello.c The object file hello.o is created.
- 列表:Link an executable file helloworld from the object file: $ gcc hello.o -o helloworld
- 列表:Run the resulting executable file: $ ./helloworld Hello, World!
- 命令/配置摘录:
$ mkdir hello-c
$ cd hello-c2.2.9. Example: Building a C++ program with the GCC (compiling and linking in one step)
- 要点:To build a minimal C++ program, use the following steps.
- 要点:In this example, compiling and linking the code is done in one step.
- 列表:Create a directory hello-cpp: $ mkdir hello-cpp
- 列表:Change to the created directory: $ cd hello-cpp
- 列表:Create file hello.cpp with the following contents: #include <iostream> int main() { std::cout << "Hello, World!\n"; return 0; }
- 列表:Compile and link the code with g++: $ g++ hello.cpp -o helloworld This compiles the code, creates the object file hello.o, and links the executable file helloworld from the object file.
- 列表:Run the resulting executable file: $ ./helloworld Hello, World!
- 列表:Optional: Change back to the parent directory: $ cd ..
- 命令/配置摘录:
$ mkdir hello-cpp
$ cd hello-cpp2.2.10. Example: Building a C++ program with the GCC (compiling and linking in two steps)
- 要点:To build a minimal C++ program by using a two-step process, first compile the source into an object file, and then link it to create the executable. This approach demonstrates modular building with the GNU Compiler Collection (GCC) compiler.
- 要点:Procedure
- 列表:Create a directory hello-cpp: $ mkdir hello-cpp
- 列表:Change to the created directory: $ cd hello-cpp
- 列表:Create file hello.cpp with the following contents: #include <iostream> int main() { std::cout << "Hello, World!\n"; return 0; }
- 列表:Compile the code with g++: $ g++ -c hello.cpp The object file hello.o is created.
- 列表:Link an executable file helloworld from the object file: $ g++ hello.o -o helloworld
- 列表:Run the resulting executable file: $ ./helloworld Hello, World!
- 命令/配置摘录:
$ mkdir hello-cpp
$ cd hello-cpp2.3. Creating libraries with GCC
- 要点:Learn about the steps to create libraries and the concepts the Linux operating system uses for libraries, including sonames, symbolic links, and library file naming conventions.
2.3.1. The soname mechanism
- 要点:To manage multiple compatible versions of a library, dynamically loaded libraries (shared objects) use the soname mechanism.
- 要点:You must understand symbolic links.
- 列表:You must understand dynamic linking and libraries.
- 列表:You must understand the concept of ABI compatibility.
- 列表:You must understand library naming conventions.
- 列表:You must understand symbolic links. Problem introduction A dynamically loaded library (shared object) exists as an independent executable file. This makes it possible to update the library without updating the applications that depend on it. However, the following problems arise with this concept:
- 列表:Identification of the actual version of the library
- 列表:Need for multiple versions of the same library present
- 命令/配置摘录:
$ objdump -p somelibrary | grep SONAME- 注意:注意 The Y component of the version number is not limited to just a single number. Additionally, some libraries encode their version in their name.
2.3.2. Creating dynamic libraries with the GCC
- 要点:To build and install a dynamic library from the source code, you can use the GNU Compiler Collection (GCC). Dynamically linked libraries, also known as shared objects, help you conserve resources by reusing code and increase security by making library updates easier.
- 要点:Prerequisites
- 列表:You must understand the soname mechanism.
- 列表:GCC must be installed on the system.
- 列表:You must have source code for a library.
- 列表:Change to the directory with library sources.
- 列表:Compile each source file to an object file with the Position independent code option -fPIC: $ gcc ... -c -fPIC some_file.c ... The object files have the same file names as the original source code files, but their extension is .o.
- 列表:Link the shared library from the object files: $ gcc -shared -o libfoo.so.x.y -Wl,-soname,libfoo.so.x some_file.o ... The used major version number is X and minor version number Y.
- 命令/配置摘录:
$ gcc ... -c -fPIC some_file.c ...
$ gcc -shared -o libfoo.so.x.y -Wl,-soname,libfoo.so.x some_file.o ...2.3.3. Creating static libraries with the GCC and ar
- 要点:To create static libraries, bundle object files into an archive by using the ar utility. Use the resulting .a file for static linking and for distributing self-contained libraries without external dependencies.
- 要点:Prerequisites
- 列表:GCC and binutils must be installed on the system.
- 列表:You must understand static and dynamic linking.
- 列表:Source file(s) with functions to be shared as a library are available.
- 列表:Create intermediate object files with GCC. $ gcc -c source_file.c ... Append more source files if required. The resulting object files share the file name but use the .o file name extension.
- 列表:Turn the object files into a static library (archive) using the ar tool from the binutils package. $ ar rcs libfoo.a source_file.o ... File libfoo.a is created.
- 列表:Use the nm command to inspect the resulting archive: $ nm libfoo.a
- 命令/配置摘录:
$ gcc -c source_file.c ...
$ ar rcs libfoo.a source_file.o ...- 注意:注意 Red Hat discourages the use of static linking for security reasons. Use static linking only when necessary, especially against libraries provided by Red Hat. See Static and dynamic linking for more details.
2.4. Using Libraries with the GCC
- 要点:Libraries are collections of reusable code, which can make coding easier and more effective. Understand library naming conventions and the distinction between static and dynamic linking. Link applications with static or dynamic libraries with GCC, and optimize with Link Time Optimization (LTO).
2.4.1. Library naming conventions
- 要点:System libraries require consistent naming. A library known as foo is expected to exist as file libfoo.so or libfoo.a. This convention is automatically understood by the linking input options of the GNU Compiler Collection (GCC), but not by the output options:
- 要点:When linking against the library, the library can be specified only by its name foo with the -l option as -lfoo:
- 列表:When linking against the library, the library can be specified only by its name foo with the -l option as -lfoo: $ gcc ... -lfoo ...
- 列表:When creating the library, the full file name libfoo.so or libfoo.a must be specified.
- 列表:The soname mechanism
- 命令/配置摘录:
$ gcc ... -lfoo ...2.4.2. Static and dynamic linking
- 要点:When building C or C++ applications, you must use dynamic linking. Static linking reduces compatibility and prevents timely library security updates.
- 要点:Static linking has numerous disadvantages and should be avoided, particularly for whole applications and the glibc and libstdc++ libraries:
- 列表:When using a library that is not enabled for dynamic linking.
- 列表:When fully static linking is required for running code in an empty chroot environment or container. However, static linking by using the glibc-static package is not supported by Red Hat.
- 列表:The CodeReady Linux Builder repository
- 注意:警告 Applications that statically link against the GNU C library (glibc) still need glibc present on the system as a dynamic library. Furthermore, the glibc dynamic library at run time must exactly match the version present at link time. As a result, static linking works only on the system where you built the executable file.
2.4.3. Link time optimization
- 要点:Link time optimization (LTO) optimizes code across all translation units by using intermediate representation at link time. This results in smaller, faster executable files and libraries. LTO also analyzes source at compile time more thoroughly, improving GCC diagnostics for coding errors.
- 要点:LTO has the following known issues:
- 列表:Violating the One Definition Rule (ODR) produces a -Wodr warning Violations of the ODR resulting in undefined behavior produce a -Wodr warning. This usually points to a bug in your program. The -Wodr warning is enabled by default.
- 列表:LTO causes increased memory consumption The compiler consumes more memory when it processes the translation units the program consists of. On systems with limited memory, disable LTO or lower the parallelism level when building your program.
- 列表:GCC removes seemingly unused functions GCC might remove functions it considers unused because the compiler is unable to recognize which symbols an asm() statement references. A compilation error might occur as a result. To prevent this, add attribute((used)) to the symbols you use in your program.
- 列表:Compiling with the -fPIC option causes errors Because GCC does not parse the contents of asm() statements, compiling your code with the -fPIC command-line option can cause errors. To prevent this, use the -fno-lto option when compiling your translation unit. More information is available at LTO FAQ {mdash}; Symbol usa…
- 列表:GCC Manual {mdash}; Function Attributes
- 列表:GCC Wiki {mdash}; Link Time Optimization
2.4.4. Library use with GCC
- 要点:A library is a reusable package of code. A C or C++ library consists of the library code and header files.
- 要点:Typically, header files of a library will be placed in a different directory than your application’s code. To tell GCC where the header files are, use the -I option:
- 列表:Static libraries are available as archive files. They contain a group of object files. The archive file has a file name extension .a.
- 列表:Dynamic libraries are available as shared objects. They are a form of an executable file. A shared object has a file name extension .so.
- 列表:Options for Directory Search
- 列表:Options for Linking
- 命令/配置摘录:
$ gcc ... -Iinclude_path ...
$ gcc ... -Isome/interesting/directory ...2.4.5. Linking static libraries with the GCC
- 要点:To link static libraries, bundle them as archives that contain object files. After linking, they become part of the resulting executable file. Static linking overrides the default dynamic linking behavior.
- 要点:Prerequisites
- 列表:GCC must be installed on your system.
- 列表:You must understand static and dynamic linking.
- 列表:You have a set of source or object files forming a valid program, requiring some static library foo and no other libraries.
- 列表:The foo library is available as a file libfoo.a, and no file libfoo.so is provided for dynamic linking.
- 列表:To link a program from source and object files, adding a statically linked library foo, which is to be found as a file libfoo.a. Change to the directory containing your code. Compile the program source files with headers of the foo library: $ gcc ... -Iheader_path -c ... Replace header_path with a path to a directory …
- 列表:Change to the directory containing your code.
- 命令/配置摘录:
$ gcc ... -Iheader_path -c ...
$ gcc ... -Llibrary_path -lfoo ...- 注意:注意 Red Hat discourages use of static linking for security reasons. See Static and dynamic linking. Use static linking only when necessary, especially against libraries provided by Red Hat. Most libraries that are part of Red Hat Enterprise Linux support dynamic linking only. The remaining steps in this procedure apply only to libraries that do not support dynamic linking.
- 注意:警告 The -static GCC option related to static linking forbids all dynamic linking. Instead, use the -Wl,-Bstatic and -Wl,-Bdynamic options to control linker behavior more precisely. See Static and dynamic libraries with GCC.
2.4.6. Using a dynamic library with the GCC
- 要点:Dynamic libraries are available as standalone executable files, required at both linking time and run time. They stay independent of your application’s executable file.
- 要点:Prerequisites
- 列表:GCC must be installed on the system.
- 列表:A set of source or object files forming a valid program, requiring some dynamic library foo and no other libraries.
- 列表:The foo library must be available as a file libfoo.so.
- 列表:To link a program against a dynamic library foo: $ gcc ... -Llibrary_path -lfoo ...
- 列表:To use a run path value stored in the executable file: The run path is a special value saved as a part of an executable file when it is being linked. Later, when the program is loaded from its executable file, the runtime linker uses the run path value to locate the library files. While linking with GCC, store the pat…
- 列表:While linking with GCC, store the path library_path as run path: $ gcc ... -Llibrary_path -lfoo -Wl,-run path=library_path ... The path library_path must point to a directory containing the file libfoo.so. 重要 Do not add a space after the comma in the -Wl,-run path= option.
- 命令/配置摘录:
$ gcc ... -Llibrary_path -lfoo ...
$ gcc ... -Llibrary_path -lfoo -Wl,-run path=library_path ...- 注意:重要 Do not add a space after the comma in the -Wl,-run path= option.
2.4.7. Static and dynamic libraries with GCC
- 要点:Combining static and dynamic linking balances portability and efficiency. The GNU Compiler Collection (GCC) automatically selects shared objects over static archives unless you configure it otherwise. That resolution order determines which library versions to link and which linker options apply.
- 要点:Static libraries are packaged as libname.a archive files. Dynamic libraries are packaged as libname.so shared objects. Together, those are the two shapes gcc must choose between when both linking modes are available for the same library name.
- 列表:Only the shared object is found, and gcc links against it dynamically.
- 列表:Only the archive is found, and gcc links against it statically.
- 列表:Both the shared object and archive are found, and by default, gcc selects dynamic linking against the shared object.
- 列表:Neither shared object nor archive is found, and linking fails.
- 列表:Static and dynamic linking
- 列表:Options for Linking
- 命令/配置摘录:
$ gcc ... path/to/libfoo.a ...
$ gcc ... -Wl,-Bstatic -lfirst -Wl,-Bdynamic -lsecond ...- 注意:注意 gcc can be configured to use linkers other than the default ld.
2.5. Managing More Code with Make
- 要点:The GNU make utility, commonly abbreviated as make, is a tool for controlling the generation of executables from source files. make automatically determines which changed parts of a complex program need recompilation. make uses Makefiles to control how you build programs.
2.5.1. GNU make and Makefile overview
- 要点:To create a usable form (usually executable files) from the source files of a particular project, perform several necessary steps. Record the actions and their sequence to be able to repeat them later.
- 要点:Red Hat Enterprise Linux contains GNU make, a build system designed for this purpose.
- 列表:Use the man utility to view manual pages installed on your system: $ man make
- 列表:Use the info utility to view information pages installed on your system: $ info make
- 列表:An Introduction to Makefiles
- 列表:GNU Make Manual
- 列表:Building code with GCC
- 命令/配置摘录:
$ make target
all: hello hello: hello.o gcc hello.o -o hello hello.o: hello.c gcc -c hello.c -o hello.o2.5.2. Example: Building a C program using a Makefile
- 要点:To build a sample C program by using a Makefile, follow the steps in this example.
- 要点:Prerequisites
- 列表:You must understand the concepts of Makefiles and make.
- 列表:Create a directory hellomake: $ mkdir hellomake
- 列表:Change to the created directory: $ cd hellomake
- 列表:Create a file hello.c with the following contents: #include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, World!\n"); return 0; }
- 列表:Create a file Makefile with the following contents: CC=gcc CFLAGS=-c -Wall SOURCE=hello.c OBJ=$(SOURCE:.c=.o) EXE=hello all: $(SOURCE) $(EXE) $(EXE): $(OBJ) $(CC) $(OBJ) -o $@ %.o: %.c $(CC) $(CFLAGS) $< -o $@ clean: rm -rf $(OBJ) $(EXE) 重要 The Makefile recipe lines must start with the tab character. When you copy …
- 列表:Run make: $ make gcc -c -Wall hello.c -o hello.o gcc hello.o -o hello This creates an executable file hello.
- 命令/配置摘录:
$ mkdir hellomake
$ cd hellomake- 注意:重要 The Makefile recipe lines must start with the tab character. When you copy this example from the documentation, the cut-and-paste process might paste spaces instead of tabs. If this happens, correct the issue manually.
第 3 章 Debugging Applications
- 要点:You can use common techniques to debug applications in multiple situations.
3.1. Enabling Debugging with Debugging Information
- 要点:To debug applications and libraries, you must obtain debugging information.
3.1.1. Debugging information
- 要点:Debugging information links binary code to source code so you can inspect variables and execution flow. The GNU Compiler Collection (GCC) generates this data in the Debug With Arbitrary Record Format (DWARF) within ELF files, and the GNU Debugger (GDB) uses it to analyze program behavior.
- 要点:Red Hat Enterprise Linux uses the ELF format for executable binaries, shared libraries, or debuginfo files. Within these ELF files, the DWARF format is used to hold the debug information.
- 列表:The DWARF Debugging Standard
- 注意:重要 STABS (Symbol Table format) is an older, less capable debugging format, occasionally used with UNIX. For debugging on RHEL, use the DWARF format instead. GCC and GDB support STABS on a best-effort basis only. Tools such as Valgrind and elfutils do not support STABS.
3.1.2. Enabling debugging of C and C++ applications with the GCC
- 要点:To debug C and C++ applications effectively, generate debugging information during compilation. Use GCC’s -g option to create this data. Debuggers use this data to map executable code to source lines for inspecting variables and logic.
- 要点:Prerequisites
- 列表:You have the gcc package installed.
- 列表:Compile and link your code with the -g option to generate debugging information: $ gcc ... -g ...
- 列表:Optional: Set the optimization level to -Og: $ gcc ... -g -Og ... Compiler optimizations can make executable code hard to relate to the source code. The -Og option optimizes the code without interfering with debugging. However, be aware that changing optimization levels can alter the program’s behavior.
- 列表:Optional: Use -g for moderate debugging information, or -g3 to include macro definitions: $ gcc ... -g3 ...
- 列表:Test the code by using the -fcompare-debug GCC option: $ gcc -fcompare-debug ... This option tests code compiled with and without debug information. If the resulting binaries are identical, the executable code is not affected by debugging options. By using the -fcompare-debug option significantly increases compilation…
- 列表:Enabling debugging with debugging information
- 命令/配置摘录:
$ gcc ... -g ...
$ gcc ... -g -Og ...3.1.3. Debuginfo and debugsource packages
- 要点:The debuginfo and debugsource packages contain debugging information and source code for programs and libraries. To debug Red Hat Enterprise Linux applications, install these packages from additional repositories.
- 要点:Debugsource packages: The debugsource packages contain the source files used for compiling the binary code. With both debuginfo and debugsource packages installed, debuggers such as GDB or LLDB can relate the execution of binary code to the source code. The source code files are installed to the /usr/src/debug directory.
- 列表:Debugging information
- 列表:Enabling debug and source repositories
3.1.4. Getting debuginfo packages for an application or library using GDB
- 要点:To obtain the necessary debuginfo packages for troubleshooting installed applications or libraries, use the GNU Debugger (GDB). It automatically detects missing symbols and identifies the specific packages needed. Follow GDB’s recommendations to install them for full debugging capabilities.
- 要点:Prerequisites
- 列表:The application or library you want to debug must be installed on the system.
- 列表:GDB and the debuginfo-install tool must be installed on the system.
- 列表:Repositories providing debuginfo and debugsource packages must be configured and enabled on the system. For details, see Enabling debug and source repositories.
- 列表:Start GDB attached to the application or library you want to debug. GDB automatically recognizes missing debugging information and suggests a command to run. $ gdb -q /bin/ls Reading symbols from /bin/ls...Reading symbols from .gnu_debugdata for /usr/bin/ls...(no debugging symbols found)...done. (no debugging symbols …
- 列表:Exit GDB: type q and confirm with Enter. (gdb) q
- 列表:Run the command suggested by GDB to install the required debuginfo packages: # dnf debuginfo-install coreutils-9.5-6.el10.x86_64 The dnf package management tool provides a summary of the changes, asks for confirmation and once you confirm, downloads and installs all the necessary files.
- 命令/配置摘录:
$ gdb -q /bin/ls
Reading symbols from /bin/ls...Reading symbols from .gnu_debugdata for /usr/bin/ls...(no debugging symbols found)...done. (no debugging symbols found)...done. Missing separate debuginfos, use: dnf debuginfo-install coreutils-9.5-6.el10.x86_64 (gdb)3.1.5. Getting debuginfo packages for an application or library manually
- 要点:To manually determine which debuginfo packages you need to install, locate the executable file and find the package that installs it.
- 要点:Prefer Use GDB to determine the packages for installation when that is an option.
- 列表:The application or library must be installed on the system.
- 列表:The application or library was installed from a package.
- 列表:The debuginfo-install tool must be available on the system.
- 列表:Channels providing the debuginfo packages must be configured and enabled on the system.
- 列表:If you use the locate command in this procedure, the mlocate package must be installed and its database must be current. As root, run dnf install mlocate if needed, then run updatedb.
- 列表:Find the executable file of the application or library. Use the which command to find the application file. $ which less /usr/bin/less Use the locate command to find the library file. $ locate libz | grep so /usr/lib64/libz.so.1 /usr/lib64/libz.so.1.2.11 If your debugging started from error messages, choose the path w…
- 命令/配置摘录:
$ which less
/usr/bin/less- 注意:重要 If this step does not produce any results, it is not possible to determine which package provided the binary file. There are several possible cases: The file is installed from a package which is not known to package management tools in their current configuration. The file is installed from a locally downloaded and manually installed package. Determining a suitable debuginfo package automatically is impossible in that case. Your package management tools are misconfigured. The file is not ins…
3.2. Inspecting Application Internal State with GDB
- 要点:To identify why an application fails, you can control its execution and examine its internal state with the GNU Debugger (GDB).
3.2.1. GNU debugger (GDB)
- 要点:Use the GNU Debugger (GDB) to inspect program execution and post-crash states. Also, you can analyze internal data and control execution flow when tracking down runtime errors. This command-line tool shows the detailed application state needed to identify and fix bugs in complex applications.
- 要点:A single GDB session can debug the following types of programs:
- 列表:Multithreaded and forking programs
- 列表:Multiple programs at once
- 列表:Programs on remote machines or in containers with the gdbserver utility connected over a TCP/IP network connection
- 列表:For programs developed by you, you can create the debugging information while building the code.
- 列表:For system programs installed from packages, you must install their debuginfo packages.
3.2.2. Attaching GDB to a process
- 要点:To examine a system process, attach the GNU Debugger (GDB) to the process.
- 要点:Prerequisites
- 列表:GDB must be installed on the system
- 列表:Start a program with GDB. Launch a program using GDB: $ gdb program Replace program with a file name or path to the program. GDB is ready to start execution of the program. You can configure breakpoints and the gdb environment before beginning the execution of the process with the run command. For more information on …
- 列表:Launch a program using GDB: $ gdb program Replace program with a file name or path to the program. GDB is ready to start execution of the program. You can configure breakpoints and the gdb environment before beginning the execution of the process with the run command. For more information on setting breakpoints, see U…
- 列表:Attach GDB to an already running process.
- 列表:Find the process ID (pid) with the ps command: $ ps -C program -o pid h pid Replace program with a file name or path to the program.
- 列表:Attach GDB to this process: $ gdb -p pid Replace pid with an actual process ID number from the ps output.
- 命令/配置摘录:
$ gdb program
$ ps -C program -o pid h- 注意:注意 In some cases, GDB might not be able to find the corresponding executable file. Use the file command to specify the path: (gdb) file path/to/program
3.2.3. Program execution control with GDB
- 要点:When the GNU Debugger (GDB) has been attached to a program, you can use several commands to control the execution of the program. These commands parse code, set breakpoints, and control program flow during debugging sessions.
- 要点:To use these GDB commands effectively, you must have debugging information available through these methods:
- 列表:The program is compiled and built with debugging information
- 列表:The relevant debuginfo packages are installed
- 列表:GDB must be attached to the program to be debugged
- 列表:A breakpoint is reached.
- 列表:A specified condition is satisfied.
- 列表:A signal is received by the program.
3.2.4. Showing program internal values with GDB
- 要点:Displaying the values of a program’s internal variables is important for understanding of what the program is doing. The GNU Debugger (GDB) offers multiple commands that you can use to inspect the internal variables. The following list describes the most useful of these commands.
- 要点:Display the value of the argument given. Usually, the argument is the name of a variable of any complexity, from a simple single value to a structure. An argument can also be an expression valid in the current language, including the use of program variables and library functions, or functions defined in the program being tested.
- 列表:The info args command displays options of the function call that is the currently selected frame.
- 列表:The info locals command displays local variables in the currently selected frame.
- 列表:The GDB Python API
- 列表:Pretty Printing
- 命令/配置摘录:
(gdb) help info3.2.5. Using GDB breakpoints to stop execution at defined code locations
- 要点:During a debugging session, you often need to investigate only specific sections of code. Breakpoints are markers that instruct GDB to stop execution at a defined location. Because each breakpoint maps to a source line, you must specify the correct source file and line number when placing them.
- 要点:Procedure
- 列表:To place a breakpoint. Specify the name of the source code file and the line in that file: (gdb) br file:line When file is not present, name of the source file at the current point of execution is used: (gdb) br line Alternatively, use a function name to put the breakpoint on its start: (gdb) br function_name A progra…
- 列表:Specify the name of the source code file and the line in that file: (gdb) br file:line
- 列表:When file is not present, name of the source file at the current point of execution is used: (gdb) br line
- 列表:Alternatively, use a function name to put the breakpoint on its start: (gdb) br function_name
- 列表:A program might encounter an error after a certain number of iterations of a task. To specify an additional condition to halt execution: (gdb) br file:line if condition Replace condition with a condition in the C or C++ language. The placeholders file and line match the syntax shown in the first breakpoint step in thi…
- 列表:To inspect the status of all breakpoints and watchpoints: (gdb) info br
- 命令/配置摘录:
(gdb) br file:line
(gdb) br line3.2.6. Using GDB watchpoints to stop execution on data access and changes
- 要点:GDB watchpoints pause execution when data changes or is accessed. Use them to debug unexpected variable corruption when the cause is unknown. Setting a watchpoint stops the program at the exact moment of access to inspect the state and find the root cause.
- 要点:Procedure
- 列表:To place a watchpoint for data change (write): (gdb) watch expression Replace expression with an expression that describes what you want to watch. For variables, expression is equal to the name of the variable.
- 列表:To place a watchpoint for data access (read): (gdb) rwatch expression
- 列表:To place a watchpoint for any data access (both read and write): (gdb) awatch expression
- 列表:To inspect the status of all watchpoints and breakpoints: (gdb) info br
- 列表:To remove a watchpoint: (gdb) delete num Replace the num option with the number reported by the info br command.
- 列表:Setting Watchpoints
- 命令/配置摘录:
(gdb) watch expression
(gdb) rwatch expression3.2.7. Debugging forking or threaded programs with GDB
- 要点:Some programs use forking or threads to achieve parallel code execution. To debug multiple simultaneous execution paths, you can use a variety of commands based on your use case.
- 要点:Forking is a situation when a program (parent) creates an independent copy of itself (child). Use the following settings and commands to affect what GDB does when a fork occurs:
- 列表:The follow-fork-mode setting controls whether GDB follows the parent or the child after the fork. set follow-fork-mode parent After a fork, debug the parent process. This is the default. set follow-fork-mode child After a fork, debug the child process. show follow-fork-mode Display the current setting of follow-fork-m…
- 列表:The set detach-on-fork setting controls whether the GDB keeps control of the other (not followed) process or leaves it to run. set detach-on-fork on The process which is not followed (depending on the value of follow-fork-mode) is detached and runs independently. This is the default. set detach-on-fork off GDB keeps c…
- 列表:Debugging Programs with Multiple Threads
- 列表:Debugging Forks
3.3. Recording Application Interactions
- 要点:The executable code of applications interacts with the operating system and shared libraries. Recording an activity log of these interactions can provide enough insight into application behavior without debugging the actual application code, or help pinpoint conditions where a bug manifests.
3.3.1. Tools for recording application interactions
- 要点:To record application interactions, you can use several tools are available in RHEL. For system calls use strace, for library calls use ltrace, and for advanced probing SystemTap. Select the appropriate tool to log specific runtime behaviors and diagnose integration issues.
- 要点:The strace tool primarily enables logging of system calls (kernel functions) used by an application.
- 列表:The strace tool can provide a detailed output about calls, because strace interprets parameters and results with knowledge of the underlying kernel code. Numbers are turned into the corresponding constant names, bitwise combined flags expanded to flag list, pointers to character arrays dereferenced to provide the actu…
- 列表:To reduce the amount of captured data, filter the traced calls.
- 列表:The use of strace does not require any particular configuration except for configuring the log filter.
- 列表:Tracing the application code with strace results in significant slowdown of the application’s execution. As a result, strace is not suitable for many production deployments. As an alternative, consider using ltrace or SystemTap.
- 列表:The version of strace available in Red Hat Developer Toolset can also perform system call tampering. This capability is useful for debugging.
- 列表:The ltrace tool enables tracing calls to any library.
- 注意:注意 In Red Hat Enterprise Linux 10, a known issue prevents ltrace from tracing system executable files. This limitation does not apply to executable files built by users.
3.3.2. Monitoring an application’s system calls with strace
- 要点:To monitor the system (kernel) calls performed by an application, use the strace tool.
- 要点:Prerequisites
- 列表:You must have strace installed on the system.
- 列表:Identify the system calls to monitor. Start strace and attach it to the program. If the program you want to monitor is not running, start strace and specify the program: $ strace -fvttTyy -s 256 -e trace=call program If the program is already running, find its process id (pid): $ ps -C program Attach strace to the pro…
- 列表:Start strace and attach it to the program. If the program you want to monitor is not running, start strace and specify the program: $ strace -fvttTyy -s 256 -e trace=call program If the program is already running, find its process id (pid): $ ps -C program Attach strace to the process: $ strace -fvttTyy -s 256 -e trac…
- 列表:If the program you want to monitor is not running, start strace and specify the program: $ strace -fvttTyy -s 256 -e trace=call program
- 列表:If the program is already running, find its process id (pid): $ ps -C program
- 列表:Attach strace to the process: $ strace -fvttTyy -s 256 -e trace=call -ppid
- 命令/配置摘录:
$ strace -fvttTyy -s 256 -e trace=call program
$ ps -C program- 注意:注意 It is advantageous to both see the output and save it to a file. Use the tee command to achieve this: $ strace ... |& tee your_log_file.log
3.3.3. Monitoring application’s library function calls with ltrace
- 要点:To monitor an application’s calls to functions available in libraries (shared objects), use the ltrace tool.
- 要点:Prerequisites
- 列表:You must have ltrace installed on the system.
- 列表:Identify the libraries and functions of interest, if possible.
- 列表:Start ltrace and attach it to the program. 注意 In Red Hat Enterprise Linux 10, a known issue prevents ltrace from tracing system executable files. This limitation does not apply to executable files built by users. If the program you want to monitor is not running, start ltrace and specify program: $ ltrace -f -l librar…
- 列表:If the program you want to monitor is not running, start ltrace and specify program: $ ltrace -f -l library -e function program
- 列表:If the program is already running, find its process id (pid): $ ps -C program
- 列表:Attach ltrace to the process: $ ltrace -f -l library -e function -ppid program
- 命令/配置摘录:
$ ltrace -f -l library -e function program
$ ps -C program- 注意:注意 In Red Hat Enterprise Linux 10, a known issue prevents ltrace from tracing system executable files. This limitation does not apply to executable files built by users.
- 注意:注意 It is advantageous to both see the output and save it to a file. Use the tee command to achieve this: $ ltrace ... |& tee your_log_file.log
3.3.4. Monitoring application’s system calls with SystemTap
- 要点:To register custom event handlers for kernel events, use the SystemTap tool. SystemTap is more efficient than the strace tool, but requires more setup. Installing SystemTap also installs the strace.stp script, which provides strace-like functionality when using SystemTap on your system.
- 要点:Prerequisites
- 列表:SystemTap and the corresponding kernel packages must be installed on the system.
- 列表:Find the process ID (pid) of the process you want to monitor: $ ps -aux
- 列表:Run SystemTap with the strace.stp script: # stap /usr/share/systemtap/examples/process/strace.stp -x pid The value of pid is the process id. The script is compiled to a kernel module, which is then loaded. This introduces a slight delay between entering the command and getting the output.
- 列表:When the process performs a system call, the call name and its parameters are printed on the command line.
- 列表:The script exits when the process terminates, or when you press Ctrl+C.
- 命令/配置摘录:
$ ps -aux
# stap /usr/share/systemtap/examples/process/strace.stp -x pid3.3.5. Using GDB to intercept application system calls
- 要点:To stop program execution when the program performs specific system calls, use GNU Debugger (GDB) catchpoints, then inspect the program state and system call parameters at those points.
- 要点:Prerequisites
- 列表:You must understand the usage of GDB breakpoints.
- 列表:GDB must be attached to the program.
- 列表:Set the catchpoint: (gdb) catch syscall syscall-name The command catch syscall sets a special type of breakpoint that halts execution when the program performs a system call. The syscall-name option specifies the name of the call. You can specify multiple catchpoints for various system calls. Leaving out the syscall-n…
- 列表:Start execution of the program. If the program has not started execution, start it: (gdb) r If the program execution is halted, resume it: (gdb) c
- 列表:If the program has not started execution, start it: (gdb) r
- 列表:If the program execution is halted, resume it: (gdb) c
- 命令/配置摘录:
(gdb) catch syscall syscall-name
(gdb) r3.3.6. Using GDB to intercept handling of signals by applications
- 要点:To stop the execution of a program under specific circumstances, you can use the GNU Debugger (GDB). To stop the execution when the program receives a signal from the operating system, use a GDB catchpoint.
- 要点:Prerequisites
- 列表:You must understand the usage of GDB breakpoints.
- 列表:GDB must be attached to the program.
- 列表:Set the catchpoint: (gdb) catch signal signal-type The command catch signal sets a special type of a breakpoint that halts execution when a signal is received by the program. The signal-type option specifies the type of the signal. Use the special value 'all' to catch all signals.
- 列表:Let the program run. If the program has not started execution, start it: (gdb) r If the program execution is halted, resume it: (gdb) c
- 列表:If the program has not started execution, start it: (gdb) r
- 列表:If the program execution is halted, resume it: (gdb) c
- 命令/配置摘录:
(gdb) catch signal signal-type
(gdb) r3.4. Debugging a Crashed Application
- 要点:Sometimes, it is not possible to debug an application directly. In these situations, you can collect information about the application at the moment of its termination and analyze it afterwards.
3.4.1. Core dumps: what they are and how to use them
- 要点:A core dump records parts of an application’s memory when the application stops. After an application fails, you can analyze the core dump, along with the executable and debuginfo, by using a debugger.
- 要点:The Linux operating system kernel can record core dumps automatically, if this functionality is enabled. Alternatively, send a signal to any running application to generate a core dump regardless of its actual state.
- 命令/配置摘录:
$ ulimit -a- 注意:警告 Some limits might affect the ability to generate a core dump. To see the current limits: $ ulimit -a
3.4.2. Recording application crashes with core dumps
- 要点:To record application crashes, configure core dump saving and add information about the system.
- 要点:Procedure
- 列表:To enable core dumps, ensure that the /etc/systemd/system.conf file contains the following lines: DumpCore=yes DefaultLimitCORE=infinity You can also add comments describing if these settings were previously present, and what the previous values were. This will enable you to reverse these changes later, if needed. Com…
- 列表:Apply the new configuration: # systemctl daemon-reexec
- 列表:Remove the limits for core dump sizes: # ulimit -c unlimited To reverse this change, run the command with value 0 instead of unlimited.
- 列表:Install the sos package which provides the sosreport utility for collecting system information: # dnf install sos
- 列表:When an application crashes, a core dump is generated and handled by systemd-coredump.
- 列表:Create an SOS report to provide additional information about the system: # sosreport This creates a .tar archive containing information about your system, such as copies of configuration files.
- 命令/配置摘录:
DumpCore=yes DefaultLimitCORE=infinity
# systemctl daemon-reexec- 注意:重要 When the executable file is not known, subsequent analysis of the core file identifies it.
3.4.3. Inspecting application crash states with core dumps
- 要点:To inspect the state of an application at the moment it terminated unexpectely, use core dumps.
- 要点:Prerequisites
- 列表:You must have a core dump file and sosreport from the system where the crash occurred.
- 列表:GDB and elfutils must be installed on your system.
- 列表:To identify the executable file where the crash occurred, run the eu-unstrip command with the core dump file: $ eu-unstrip -n --core=./core.9814 0x400000+0x207000 2818b2009547f780a5639c904cded443e564973e@0x400284 /usr/bin/sleep /usr/lib/debug/bin/sleep.debug [exe] 0x7fff26fff000+0x1000 1e2a683b7d877576970e4275d41a6aae…
- 列表:The memory address where the module was mapped
- 列表:The build-id of the module and where in the memory it was found
- 列表:The module’s executable file name, displayed as - when unknown, or as . when the module has not been loaded from a file
- 命令/配置摘录:
$ eu-unstrip -n --core=./core.9814
0x400000+0x207000 2818b2009547f780a5639c904cded443e564973e@0x400284 /usr/bin/sleep /usr/lib/debug/bin/sleep.debug [exe] 0x7fff26fff000+0x1000 1e2a683b7d877576970e4275d41a6aaec280795e@0x7fff26fff340 . - linux-vdso.so.1 0x35e7e00000+0x3b6000 374add1ead31ccb449779bc7ee7877de3377e5ad@0x35e7e00280 /usr/lib64/libc-2.14.90.so /usr/lib/debug/lib64/libc-2.14.90.so.debug libc.so.6 0x35e7a00000+0x224000 3ed9e61c2b7e707ce244816335776afa2ad0307d@0x35e7a001d8 /usr/lib64/ld-2.14.90.so /usr/lib/debug/lib64/ld-2.14.90.so.debug ld-linux-x86-64.so.2- 注意:注意 It might not be necessary to install the debugging information for all executable files contained in the core dump. Most of these executable files are libraries used by the application code. These libraries might not directly contribute to the problem you are analyzing, and you do not need to include debugging information for them.
- 注意:注意 When analyzing a core file, GDB is not attached to a running process. Commands for controlling execution have no effect.
3.4.4. Creating and accessing a core dump with coredumpctl
- 要点:To manage and analyze core dumps directly on the affected system, use coredumpctl. This tool simplifies finding, capturing, and inspecting crash data. Identify an unresponsive process, force a core dump, and verify its successful capture to diagnose application failures.
- 要点:Prerequisites
- 列表:The system must be configured to use systemd-coredump for core dump handling. To verify this is true: $ sysctl kernel.core_pattern The configuration is correct if the output starts with the following: kernel.core_pattern = |/usr/lib/systemd/systemd-coredump
- 列表:Find the PID of the hung process, based on a known part of the executable file name: $ pgrep -a executable-name-fragment This command will output a line in the form PID command-line Use the command-line value to verify that the PID belongs to the intended process. For example: $ pgrep -a bc 5459 bc
- 列表:Send an abort signal to the process: # kill -ABRT PID
- 列表:Verify that the core has been captured by coredumpctl: $ coredumpctl list PID For example: $ coredumpctl list 5459 TIME PID UID GID SIG COREFILE EXE Thu 2019-11-07 15:14:46 CET 5459 1000 1000 6 present /usr/bin/bc
- 列表:Further examine or use the core file as needed. You can specify the core dump by PID and other values. See the coredumpctl(1) manual page for further details. Next steps To show details of the core file, run: $ coredumpctl info PID To load the core file in the GDB debugger, run: $ coredumpctl debug PID Depending on th…
- 列表:To show details of the core file, run: $ coredumpctl info PID
- 命令/配置摘录:
$ sysctl kernel.core_pattern
kernel.core_pattern = |/usr/lib/systemd/systemd-coredump3.4.5. Dumping process memory with gcore
- 要点:To capture the memory state of a running process without terminating it, use the gcore utility. This creates a core dump file for offline analysis. The result is a snapshot of the application’s memory that helps you investigate issues while the service remains available.
- 要点:Prerequisites
- 列表:You must understand what core dumps are and how they are created.
- 列表:GDB must be installed on the system.
- 列表:Identify the process id (pid). Use tools such as ps, pgrep, and top: $ ps -C some-program
- 列表:Dump the memory of this process: $ gcore -o filename pid This creates a file filename and dumps the process memory in it. While the memory is being dumped, the execution of the process is halted.
- 列表:After the core dump is finished, the process resumes normal execution.
- 列表:Create an SOS report to provide additional information about the system: # sosreport This creates a tar archive containing information about your system, such as copies of configuration files.
- 命令/配置摘录:
$ ps -C some-program
$ gcore -o filename pid3.4.6. Dumping protected process memory with GDB
- 要点:To dump protected process memory, configure GNU Debugger (GDB) to ignore core dump filters. Capture memory regions flagged as non-dumpable, such as those conserving resources or holding sensitive data. Use the gcore command within GDB to generate the complete core file.
- 要点:Prerequisites
- 列表:You must understand what core dumps are.
- 列表:GDB must be installed on the system.
- 列表:GDB must be already attached to the process with protected memory.
- 列表:Set GDB to ignore the settings in the /proc/PID/coredump_filter file: (gdb) set use-coredump-filter off
- 列表:Set GDB to ignore the memory page flag VM_DONTDUMP: (gdb) set dump-excluded-mappings on
- 列表:Dump the memory: (gdb) gcore core-file Replace core-file with name of file where you want to dump the memory.
- 命令/配置摘录:
(gdb) set use-coredump-filter off
(gdb) set dump-excluded-mappings on3.5. Debugging applications in containers
- 要点:To troubleshoot container applications, you can use various command-line tools.
- 要点:Rootless containers operate without elevated privileges. They run as non-root users in user namespaces. That design improves isolation from the host, limits host interaction, and reduces the attack surface.
- 列表:Debugging applications within Red Hat OpenShift containers
- 列表:Debugging a Crashed Application
- 列表:Troubleshooting Kubernetes
- 列表:Tips and Tricks for containerizing services
- 注意:注意 This is not a complete list of command-line tools. Your choice of tool depends on the container image and your use case. Several tools, including systemctl, journalctl, ip, netstat, ping, traceroute, perf, and iostat, might need root access. They interact with system-level resources such as networking, systemd services, or hardware performance counters. Rootless containers restrict those resources for security reasons.
第 4 章 Using the gcc-toolset-15 container image
- 要点:The gcc-toolset-15 container image provides a complete toolchain for building, testing, and troubleshooting C and C++ applications in a containerized environment.
4.1. Introduction to the gcc-toolset-15 container image
- 要点:The gcc-toolset-15 container image provides a GCC Toolset 15 toolchain for building, testing, and troubleshooting C and C++ applications on Red Hat Enterprise Linux (RHEL). By using this image, you can mantain a reproducible environment without installing packages directly on the host.
- 要点:The image is part of the RHEL container collection. All included RPM packages originate from official RHEL repositories, ensuring the image follows standard RHEL lifecycle and support policies. This provides a portable, containerized alternative to traditional RPM-based delivery.
- 列表:Interactive development on a RHEL host by running an interactive container that mounts source code from the host.
- 列表:Noninteractive builds in CI pipelines or scheduled jobs, with build scripts running inside the container and writing artifacts to host-mounted directories.
- 列表:Evaluation and troubleshooting of GCC Toolset 15 behavior in an isolated environment without installing the toolchain on the host.
4.2. Supported platforms and architectures for the gcc-toolset-15 container image
- 要点:The gcc-toolset-15 image targets the same architectures provided by Red Hat Enterprise Linux (RHEL), including AMD64 and Intel 64 (x86_64), 64-bit ARM (aarch64), IBM Power, little endian (ppc64le), and 64-bit IBM Z (s390x).
- 要点:For image-specific metadata, supported architectures, and tags, see the Red Hat container catalog entry for the gcc-toolset-15 container image.
- 列表:<REGISTRY> for the registry hostname.
- 列表:<NAMESPACE> for the registry namespace that contains the gcc-toolset-15 image.
- 列表:<TAG> for the image tag that corresponds to the GCC Toolset 15 level that you require.
4.3. Preparing a RHEL host for the gcc-toolset-15 container image
- 要点:To configure hosts to use the gcc-toolset-15 image, verify system requirements and install necessary container tools. For comprehensive guidelines, see Building, running, and managing containers.
- 要点:Prerequisites
- 列表:Administrator access to the RHEL host.
- 列表:The host is registered and has access to required Red Hat Enterprise Linux repositories.
- 列表:The host runs a supported Red Hat Enterprise Linux variant and architecture.
- 列表:Ensure that the host has adequated resources for CPU, memory, and storage for build workloads.
- 列表:The host has network access to the container registry or to an internal mirror.
- 列表:Install the container management tools: $ sudo dnf install -y container-tools
- 命令/配置摘录:
$ sudo dnf install -y container-tools
$ podman --version4.4. Authenticating to the container registry
- 要点:To pull the gcc-toolset-15 image, you must log in to the container registry.
- 要点:Prerequisites
- 列表:container-tools are installed on the RHEL host.
- 列表:You have the registry hostname and valid credentials.
- 列表:Log in to the registry using podman: $ podman login <REGISTRY> Replace <REGISTRY> with your registry hostname.
- 列表:When prompted, enter your user name and password, or use the authentication mechanism that your organization provides.
- 列表:Verify that the login and registry access were successful by searching for the gcc-toolset-15 image: $ podman search <REGISTRY>/<NAMESPACE>/gcc-toolset-15**
- 命令/配置摘录:
$ podman login <REGISTRY>
$ podman search <REGISTRY>/<NAMESPACE>/gcc-toolset-15**4.5. Pulling the gcc-toolset-15 container image
- 要点:To use the gcc-toolset-15 image, pull it to your local system after authenticating to the registry.
- 要点:Prerequisites
- 列表:You have authenticated to the container registry.
- 列表:You know the <REGISTRY>, <NAMESPACE>, and <TAG> values for the image. You can determine these details from the Red Hat Container Catalog or your internal image catalog.
- 列表:Pull the image: $ podman pull <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<TAG> Replace <REGISTRY>, <NAMESPACE>, and <TAG> with the values you determined earlier.
- 列表:Verify that the image is available locally: $ podman images <REGISTRY>/<NAMESPACE>/gcc-toolset-15 The output should display a table row containing the repository, tag, image ID, and size. For example: REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/.../gcc-toolset-15 latest a1b2c3d4e5f6 2 days ago 540MB
- 命令/配置摘录:
$ podman pull <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<TAG>
$ podman images <REGISTRY>/<NAMESPACE>/gcc-toolset-154.6. Using the gcc-toolset-15 to run interactive development containers
- 要点:To use the gcc-toolset-15 image for interactive development, run an interactive container that mounts source code from the host.
- 要点:Prerequisites
- 列表:The gcc-toolset-15 image is available locally.
- 列表:You have a host directory containing the application source code, for example, /home/devuser/src.
- 列表:You have read and write permissions for the host directory.
- 列表:Start an interactive container that mounts the source directory and uses it as the working directory: $ podman run --rm -it -v /home/devuser/src:/src -w /src <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<TAG> /bin/bash Replace <REGISTRY>, <NAMESPACE>, and <TAG> with your specific values.
- 列表:Inside the container, verify that the source code is available: # ls /src
- 列表:Build an application using GCC Toolset 15: # gcc -o myapp main.c Build artifacts created in /src are stored on the host in /home/devuser/src.
- 命令/配置摘录:
$ podman run --rm -it -v /home/devuser/src:/src -w /src <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<TAG> /bin/bash
# ls /src4.7. Running noninteractive builds with gcc-toolset-15
- 要点:To perform noninteractive builds, run the gcc-toolset-15 image with a predefined build script that exits upon completion.
- 要点:In CI systems, you can integrate this pattern by running podman run as part of a pipeline step. Use pipeline variables or configuration files to provide the values for <REGISTRY>, <NAMESPACE>, <TAG>, and host paths.
- 列表:The gcc-toolset-15 image is available locally.
- 列表:A host directory for source and build scripts, for example, /srv/src.
- 列表:A host directory for build output, for example, /srv/build-output.
- 列表:A build script, for example, build.sh, that runs GCC Toolset 15 commands.
- 列表:Prepare your build workflow. Ensure both the source and output directories on the host have appropriate permissions.
- 列表:Run the container in noninteractive mode: $ podman run --rm -v /srv/src:/src -v /srv/build-output:/build-output -w /src <REGISTRY> / <NAMESPACE> /gcc-toolset-15: <TAG> /src/build.sh In this example: /src/build.sh is a script inside the container that performs the build. Build artifacts and logs are written to /build-o…
- 命令/配置摘录:
$ podman run --rm -v /srv/src:/src -v /srv/build-output:/build-output -w /src <REGISTRY> / <NAMESPACE> /gcc-toolset-15: <TAG> /src/build.sh4.8. Maintaining the gcc-toolset-15 container image
- 要点:To maintain the gcc-toolset-15 image, monitor for updates including security fixes, bug fixes, and dependency changes. Track updates and errata by monitoring RHEL release notes, or internal advisories for new images that contain updated GCC Toolset 15 content.
- 要点:Procedure
- 列表:Update to a new image tag: Consult the Red Hat Ecosystem Catalog or your internal registry to find the new image tag. Determine the <NEW_TAG> that corresponds to the updated gcc-toolset-15 image. Pull the new tag to your environment: $ podman pull <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<NEW_TAG> Update scripts, CI jobs…
- 列表:Determine the <NEW_TAG> that corresponds to the updated gcc-toolset-15 image.
- 列表:Pull the new tag to your environment: $ podman pull <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<NEW_TAG>
- 列表:Update scripts, CI jobs, and documentation to reference <NEW_TAG> as appropriate.
- 列表:Remove outdated image tags after you complete validation and roll out the new tag, according to your retention policy: $ podman rmi <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<OLD_TAG>
- 命令/配置摘录:
$ podman pull <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<NEW_TAG>
$ podman rmi <REGISTRY>/<NAMESPACE>/gcc-toolset-15:<OLD_TAG>- 注意:重要 If you use an internal registry, mirror the updated image into the internal registry or rely on existing synchronization mechanisms. Use internal paths for <REGISTRY> and <NAMESPACE> in all procedures. Coordinate with the team that manages the internal registry to ensure that mirrors are updated inline with your rollout schedule.
4.9. Troubleshooting the gcc-toolset-15 container image
- 要点:Identify and resolve common issues when pulling or running the gcc-toolset-15 container image.
- 要点:If podman pull fails:
- 列表:Check registry login by running podman login <REGISTRY>.
- 列表:Verify network connectivity to the registry.
- 列表:Confirm that <REGISTRY>, <NAMESPACE>, and <TAG> values are correct.
- 列表:If access is denied, verify that your subscription and registry permissions allow access to the gcc-toolset-15 image.
- 列表:Verify that the image is available locally by running podman images <REGISTRY>/<NAMESPACE>/gcc-toolset-15. The output should display a table row containing the repository, tag, image ID, and size. For example: REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/.../gcc-toolset-15 latest a1b2c3d4e5f6 2 days ago 540…
- 列表:Check volume mount paths to ensure that host directories exist and that you have appropriate permissions.
- 命令/配置摘录:
REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/.../gcc-toolset-15 latest a1b2c3d4e5f6 2 days ago 540MB4.10. Operational and security considerations for the gcc-toolset-15 container image
- 要点:Review the following operational and security guidelines when using the gcc-toolset-15 container image in your environment.
- 要点:Because the gcc-toolset-15 image is built from Red Hat Enterprise Linux (RHEL) repositories, it follows RHEL security practices. However, you should still:
- 列表:Limit who can run containers on shared hosts.
- 列表:Periodically review and update image tags to consume security fixes.
- 列表:Use internal registries and scanning tools according to your organization’s policies.
第 5 章 Additional toolsets for development
- 要点:Additional toolsets for C and C++ development provides capabilities for building, analyzing, and optimizing applications. By using these toolsets, you can define development workflows and improve application quality.
5.1. Using the GCC Toolset
- 要点:The GCC Toolset provides updated development tools on Red Hat Enterprise Linux. Install, enable, and manage the toolset to build and debug C and C++ applications.
5.1.1. What is the GCC Toolset
- 要点:Red Hat Enterprise Linux 10 introduces the GCC Toolset, which is an Application Stream that contains updated versions of development and performance analysis tools. The GCC Toolset is similar in role to Red Hat Developer Toolset.
- 要点:GCC Toolset is available as an Application Stream in the form of a Software Collection in the AppStream repository. The GCC Toolset is fully supported under Red Hat Enterprise Linux Subscription Level Agreements, is functionally complete, and is intended for production use. Applications and libraries provided by the GCC Toolset do not replace the Red Hat Enterprise Linux system versions, do not override them, and do not automatically become default or preferred choices. By using a framework called Software Collect…
- 列表:Red Hat Developer Toolset
- 列表:Red Hat Enterprise Linux Application Streams Life Cycle
5.1.2. Installing the GCC Toolset
- 要点:Installing the GCC Toolset on a system installs the main tools and all necessary dependencies. Note that some parts of the toolset are not installed by default and must be installed separately.
- 要点:Procedure
- 列表:To install the GCC Toolset version N: # dnf install gcc-toolset-N
- 命令/配置摘录:
# dnf install gcc-toolset-N5.1.3. Installing individual packages from the GCC Toolset
- 要点:To install only certain tools from the GCC Toolset instead of the whole toolset, list the available packages and install the selected ones with the dnf package management tool. Use selective installation to access packages not installed by default with the full toolset.
- 要点:Procedure
- 列表:List the packages available in the GCC Toolset version N: $ dnf list available gcc-toolset-N-\
- 列表:To install any of these packages: # dnf install package_name Replace package_name with a space-separated list of packages to install. For example, to install the gcc-toolset-15-annobin-annocheck and gcc-toolset-15-binutils-devel packages: # dnf install gcc-toolset-15-annobin-annocheck gcc-toolset-15-binutils-devel
- 命令/配置摘录:
$ dnf list available gcc-toolset-N-\
# dnf install package_name5.1.4. Uninstalling the GCC Toolset
- 要点:Remove the GCC Toolset from your system by uninstalling it using the dnf package management tool.
- 要点:Procedure
- 列表:To uninstall the GCC Toolset version N: # dnf remove gcc-toolset-N \
- 命令/配置摘录:
# dnf remove gcc-toolset-N \5.1.5. Accessing the GCC Toolset
- 要点:To access the GCC Toolset, you can run a specific tool using the scl utility, or start a shell session where the toolset versions override the system versions.
- 要点:Procedure
- 列表:To run a single tool from the GCC Toolset version N: $ gcc-toolset-N-env tool Replace tool with the command provided by the tool you want to run.
- 列表:To run a shell session where tool versions from the GCC Toolset version N override system versions of these tools: $ gcc-toolset-N-env bash 注意 The scl utility is not used for the GCC Toolset in Red Hat Enterprise Linux 10. The scl enable command does not work with the GCC Toolset.
- 命令/配置摘录:
$ gcc-toolset-N-env tool
$ gcc-toolset-N-env bash- 注意:注意 The scl utility is not used for the GCC Toolset in Red Hat Enterprise Linux 10. The scl enable command does not work with the GCC Toolset.
5.1.6. ADDITIONAL RESOURCES
- 列表:Developer Toolset User Guide
5.2. GCC Toolset 15
- 要点:GCC Toolset 15 in Red Hat Enterprise Linux offers updated compilers and debuggers for C, C++, and Fortran. It enables building, testing, and optimizing applications with current features while maintaining system stability and support.
5.2.1. The GCC Toolset 15 tools and versions
- 要点:The GCC Toolset 15 offers updated versions of development tools for building and debugging applications on RHEL.
- 列表:[list of tools]
- 表格样本(共 4 行):
- Name | Version | Description
- GCC | 15.1.0 | A portable compiler suite with support for C, C++, and Fortran.
- binutils | 2.44 | A collection of binary tools and other utilities to inspect and manipulate object files and binaries.
- dwz | 0.16 | A tool to optimize DWARF debugging information contained in ELF shared libraries and ELF executables for size.
5.2.2. C++ compatibility in the GCC Toolset 15
- 要点:GCC Toolset 15 supports a range of C++ language standards. The default standard is C++17, but you can choose C++98, C++11, C++14, or experimental versions including C++20, C++23, and C++26. Select a different standard with the appropriate compiler flag when building your code.
- 要点:The GCC compiler in the GCC Toolset 15 can use the following C++ standards:
- 注意:重要 This compatibility information applies only to GCC from the GCC Toolset 15.
5.2.3. Specifics of GCC in the GCC Toolset 15
- 要点:Certain behaviors and requirements of binutils in the GCC Toolset 15 differ from the base Red Hat Enterprise Linux binutils. These include automatic static linking of certain library features and the requirement to specify libraries after object files during linking.
- 要点:In the GCC Toolset 15, libraries are linked by using linker scripts, which might specify some symbols through static archives. This is required to ensure compatibility with multiple versions of Red Hat Enterprise Linux. However, the linker scripts use the names of the corresponding shared object files. As a consequence, the linker uses different symbol handling rules than expected, and does not recognize symbols required by object files when the option adding the library is specified before options specifying the …
- 命令/配置摘录:
$ gcc-toolset-15-env gcc -lsomelib objfile.o
$ gcc-toolset-15-env gcc objfile.o -lsomelib- 注意:重要 Because of this additional security risk, developers are strongly advised not to statically link their entire application for the same reasons.
5.2.4. Specifics of binutils in the GCC Toolset 15
- 要点:Certain behaviors and requirements of binutils in the GCC Toolset 15 differ from the base Red Hat Enterprise Linux binutils. These include automatic static linking of certain library features and the requirement to specify libraries after object files during linking.
- 要点:In the GCC Toolset 15, libraries are linked by using linker scripts which might specify some symbols through static archives. This is required to ensure compatibility with multiple versions of Red Hat Enterprise Linux. However, the linker scripts use the names of the corresponding shared object files. As a consequence, the linker uses different symbol handling rules than expected, and does not recognize symbols required by object files when the option adding the library is specified before options specifying the o…
- 命令/配置摘录:
$ gcc-toolset-15-env gcc ld -lsomelib objfile.o
$ gcc-toolset-15-env ld objfile.o -lsomelib- 注意:重要 Because of this additional security risk, developers are strongly advised not to statically link their entire application for the same reasons.
5.3. Compiler toolsets
- 要点:RHEL 10 provides several compiler toolsets as Application Streams, including the LLVM Toolset, Rust Toolset, and Go Toolset. These toolsets provides compilers, debuggers, dependency managers, and other related tools and libraries for C, C++, Rust, and Go development.
- 要点:The following compiler toolsets are available:
- 列表:LLVM Toolset provides the LLVM compiler infrastructure framework, the Clang compiler for the C and C++ languages, the LLDB debugger, and related tools for code analysis.
- 列表:Rust Toolset provides the Rust programming language compiler rustc, the cargo build tool and dependency manager, the cargo-vendor plug-in, and required libraries.
- 列表:Go Toolset provides the Go programming language tools and libraries. Go is alternatively known as golang.
5.4. The Annobin project
- 要点:Use the Annobin project to add markers to Executable and Linkable Format (ELF) objects. With the Annobin project, you can track build properties and perform security hardening checks on your binaries by using the annobin plugin and the annocheck programs.
- 要点:The annobin plugin scans the GNU Compiler Collection (GCC) command line, the compilation state, and the compilation process, and generates the ELF notes. The ELF notes record how the binary was built and provide information for the annocheck program to perform security hardening checks.
- 列表:Use the annobin plugin
- 列表:Use the annocheck program
- 列表:Remove redundant annobin notes
- 注意:注意 The files must be in ELF format. annocheck does not handle any other binary file types.
5.4.1. Using the annobin plugin
- 要点:You can use the annobin plugin to annotate binary files. You can enable the annobin plugin and pass options to it.
- 要点:To add build security notes to binaries, enable the annobin plug-in by using command-line options with gcc or clang utilities.
- 列表:To enable the annobin plug-in with gcc, use: $ gcc -fplugin=annobin If gcc does not find the annobin plug-in, use: $ gcc -iplugindir=/path/to/directory/containing/annobin/ Replace /path/to/directory/containing/annobin/ with the absolute path to the directory that contains annobin. To find the directory containing the …
- 列表:If gcc does not find the annobin plug-in, use: $ gcc -iplugindir=/path/to/directory/containing/annobin/ Replace /path/to/directory/containing/annobin/ with the absolute path to the directory that contains annobin.
- 列表:To find the directory containing the annobin plug-in, use: $ gcc --print-file-name=plugin
- 列表:To enable the annobin plug-in with clang, use: $ clang -fplugin=/path/to/directory/containing/annobin/ Replace /path/to/directory/containing/annobin/ with the absolute path to the directory that contains annobin.
- 列表:Optional: To remove the redundant annobin notes, use the objcopy utility: $ objcopy --merge-notes file-name
- 列表:To pass options to the annobin plug-in with gcc, use: $ gcc -fplugin=annobin -fplugin-arg-annobin-option file-name Replace option with the annobin command line arguments and replace file-name with the name of the file. For example, to display additional details about what annobin it is doing, use: $ gcc -fplugin=annob…
- 命令/配置摘录:
$ gcc -fplugin=annobin
$ gcc -iplugindir=/path/to/directory/containing/annobin/5.4.2. Using the annocheck program
- 要点:You can use annocheck to examine files, directories, RPM packages, and extra tools.
- 要点:To verify hardening options and build security notes of ELF files, examine the files by using the annocheck tool.
- 列表:To examine a file, use: $ annocheck file-name Replace file-name with the name of a file. 注意 The files must be in ELF format. annocheck does not handle any other binary file types. annocheck processes static libraries that contain ELF object files.
- 列表:To scan a directory, use: $ annocheck directory-name Replace directory-name with the name of a directory. annocheck automatically examines the contents of the directory, its sub-directories, and any archives and RPM packages within the directory. 注意 annocheck only looks for ELF files. Other file types are ignored.
- 列表:To scan an RPM package, use: $ annocheck rpm-package-name Replace rpm-package-name with the name of an RPM package. annocheck recursively scans all the ELF files inside the RPM package. 注意 annocheck only looks for ELF files. Other file types are ignored.
- 列表:To scan an RPM package with provided debug info RPM, use: $ annocheck rpm-package-name --debug-rpm debuginfo-rpm Replace rpm-package-name with the name of an RPM package, and debuginfo-rpm with the name of a debug info RPM associated with the binary RPM.
- 列表:built-by tool
- 列表:notes tool
- 命令/配置摘录:
$ annocheck file-name
$ annocheck directory-name- 注意:注意 annocheck recursively scans directories, archives, and RPM packages for ELF object files. The files have to be in the ELF format. annocheck does not handle any other binary file types.
- 注意:注意 The files must be in ELF format. annocheck does not handle any other binary file types. annocheck processes static libraries that contain ELF object files.
5.4.3. Removing redundant annobin notes
- 要点:Using annobin increases the size of binaries. To reduce the size of the binaries compiled with annobin, use the objcopy program, which is a part of the binutils package.
- 要点:Procedure
- 列表:To remove the redundant annobin notes, use: $ objcopy --merge-notes file-name Replace file-name with the name of the file.
- 命令/配置摘录:
$ objcopy --merge-notes file-name第 6 章 Notable changes in RHEL 10
- 要点:Red Hat Enterprise Linux 10 introduces important changes that affect C and C++ application development.
6.1. Compatibility breaking changes in C++
- 要点:GNU Compiler Collection (GCC) 12 and later introduce compatibility-breaking changes for C++ code that depends on condition variables not being able to throw exceptions and for code that relies on deprecated standard library class templates.
- 要点:Certain class templates have been deprecated in new versions of C++ and produce warning diagnostics in GCC 12 and later.
- 列表:The following class templates have been deprecated in C++11 and later: std::unary_function std::binary_function
- 列表:std::unary_function
- 列表:std::binary_function
- 列表:The std::iterator class template has been deprecated in C++17 and later.
- 列表:When you do not want to make other changes to the code, silence the warning diagnostics by using GCC’s diagnostic pragmas. For example: #pragma GCC diagnostic push #pragma GCC diagnostic ignored “-Wdeprecated-declarations" class Functor : public std::unary_function<int, int> { /* … */ }; #pragma GCC diagnostic pop
- 列表:When you want your code to be compatible with later versions of C++, replace these class templates in the code with nested typedefs. For example, you can replace a std::unary_function base class with result_type and argument_type typedefs: class Functor { using result_type = int; using argument_type = int; /* … */ …
- 命令/配置摘录:
#pragma GCC diagnostic push #pragma GCC diagnostic ignored “-Wdeprecated-declarations" class Functor : public std::unary_function<int, int> { /* … */ }; #pragma GCC diagnostic pop
class Functor { using result_type = int; using argument_type = int; /* … */ };6.2. Compatibility breaking changes to glibc
- 要点:Updates to the GNU C Library (glibc) include compatibility breaking changes to the dynamic linker search algorithm, which no longer checks certain subdirectories for shared objects. This release also removes the catchsegv script and the libSegFault.so shared object.
- 要点:The following list describes changes to the dynamic linker search algorithm:
- 列表:The dynamic linker no longer loads shared objects from the tls subdirectories on the library search path or the subdirectory that corresponds to the AT_PLATFORM system name.
- 列表:The dynamic linker no longer searches subdirectories named after the legacy AT_HWCAP search mechanism.
6.3. C23 support in glibc
- 要点:The GNU C Library (glibc) in Red Hat Enterprise Linux 10 includes support for C standard library facilities associated with the ISO C23 language standard.
- 要点:Red Hat Enterprise Linux 10 includes GNU Compiler Collection (GCC) 14 as the default C and C++ compiler. To compile C application code as ISO C23 with GCC, use an option such as -std=c23. If you use another GCC release (for example, from a compiler toolset) or a different compiler, use the dialect option and documentation for that toolchain. C23 language support varies by compiler version.
- 列表:The GNU C Library Reference Manual
6.4. RHEL 10 uses IEEE binary128 for long double on POWER
- 要点:On POWER (ppc64le), RHEL 10 changes the default long double representation from IBM double-double to IEEE 754 binary128. Both formats use 16 bytes but differ internally. glibc and libstdc++ support both formats. Recompile applications by using long double on POWER for correct behavior.
完整目录
- Configuring a developer workstation, and developing and debugging C and C++ applications in Red Hat Enterprise Linux 10
- 第 1 章 Preparing a development workstation
- 1.1. Enabling debug and source repositories
- 1.2. Installing Git for managing application versions
- 1.3. Installing development tools for C and C++
- 1.4. Installing tools for debugging applications
- 1.5. Installing tools for measuring application performance
- 第 2 章 Creating C or C++ Applications
- 2.1. GCC in RHEL 10
- 2.2. Building code with GCC
- 2.2.1. Relationship between code forms
- 2.2.2. Compiling source files to object code
- 2.2.3. Enabling debugging of C and C++ applications with the GCC
- 2.2.4. Code optimization with the GCC
- 2.2.5. Options for hardening code with the GCC
- 2.2.6. Linking code to create executable files
- 2.2.7. Example: Building a C program with the GCC (compiling and linking in one step)
- 2.2.8. Example: Building a C program with the GCC (compiling and linking in two steps)
- 2.2.9. Example: Building a C++ program with the GCC (compiling and linking in one step)
- 2.2.10. Example: Building a C++ program with the GCC (compiling and linking in two steps)
- 2.3. Creating libraries with GCC
- 2.3.1. The soname mechanism
- 2.3.2. Creating dynamic libraries with the GCC
- 2.3.3. Creating static libraries with the GCC and ar
- 2.4. Using Libraries with the GCC
- 2.4.1. Library naming conventions
- 2.4.2. Static and dynamic linking
- 2.4.3. Link time optimization
- 2.4.4. Library use with GCC
- 2.4.5. Linking static libraries with the GCC
- 2.4.6. Using a dynamic library with the GCC
- 2.4.7. Static and dynamic libraries with GCC
- 2.5. Managing More Code with Make
- 2.5.1. GNU make and Makefile overview
- 2.5.2. Example: Building a C program using a Makefile
- 第 3 章 Debugging Applications
- 3.1. Enabling Debugging with Debugging Information
- 3.1.1. Debugging information
- 3.1.2. Enabling debugging of C and C++ applications with the GCC
- 3.1.3. Debuginfo and debugsource packages
- 3.1.4. Getting debuginfo packages for an application or library using GDB
- 3.1.5. Getting debuginfo packages for an application or library manually
- 3.2. Inspecting Application Internal State with GDB
- 3.2.1. GNU debugger (GDB)
- 3.2.2. Attaching GDB to a process
- 3.2.3. Program execution control with GDB
- 3.2.4. Showing program internal values with GDB
- 3.2.5. Using GDB breakpoints to stop execution at defined code locations
- 3.2.6. Using GDB watchpoints to stop execution on data access and changes
- 3.2.7. Debugging forking or threaded programs with GDB
- 3.3. Recording Application Interactions
- 3.3.1. Tools for recording application interactions
- 3.3.2. Monitoring an application’s system calls with strace
- 3.3.3. Monitoring application’s library function calls with ltrace
- 3.3.4. Monitoring application’s system calls with SystemTap
- 3.3.5. Using GDB to intercept application system calls
- 3.3.6. Using GDB to intercept handling of signals by applications
- 3.4. Debugging a Crashed Application
- 3.4.1. Core dumps: what they are and how to use them
- 3.4.2. Recording application crashes with core dumps
- 3.4.3. Inspecting application crash states with core dumps
- 3.4.4. Creating and accessing a core dump with coredumpctl
- 3.4.5. Dumping process memory with gcore
- 3.4.6. Dumping protected process memory with GDB
- 3.5. Debugging applications in containers
- 3.1. Enabling Debugging with Debugging Information
- 第 4 章 Using the gcc-toolset-15 container image
- 4.1. Introduction to the gcc-toolset-15 container image
- 4.2. Supported platforms and architectures for the gcc-toolset-15 container image
- 4.3. Preparing a RHEL host for the gcc-toolset-15 container image
- 4.4. Authenticating to the container registry
- 4.5. Pulling the gcc-toolset-15 container image
- 4.6. Using the gcc-toolset-15 to run interactive development containers
- 4.7. Running noninteractive builds with gcc-toolset-15
- 4.8. Maintaining the gcc-toolset-15 container image
- 4.9. Troubleshooting the gcc-toolset-15 container image
- 4.10. Operational and security considerations for the gcc-toolset-15 container image
- 第 5 章 Additional toolsets for development
- 5.1. Using the GCC Toolset
- 5.1.1. What is the GCC Toolset
- 5.1.2. Installing the GCC Toolset
- 5.1.3. Installing individual packages from the GCC Toolset
- 5.1.4. Uninstalling the GCC Toolset
- 5.1.5. Accessing the GCC Toolset
- 5.1.6. ADDITIONAL RESOURCES
- 5.2. GCC Toolset 15
- 5.2.1. The GCC Toolset 15 tools and versions
- 5.2.2. C++ compatibility in the GCC Toolset 15
- 5.2.3. Specifics of GCC in the GCC Toolset 15
- 5.2.4. Specifics of binutils in the GCC Toolset 15
- 5.3. Compiler toolsets
- 5.4. The Annobin project
- 5.4.1. Using the annobin plugin
- 5.4.2. Using the annocheck program
- 5.4.3. Removing redundant annobin notes
- 5.1. Using the GCC Toolset
- 第 6 章 Notable changes in RHEL 10
- 6.1. Compatibility breaking changes in C++
- 6.2. Compatibility breaking changes to glibc
- 6.3. C23 support in glibc
- 6.4. RHEL 10 uses IEEE binary128 for long double on POWER
