1. 项目概述为什么一个“Linux C环境搭建”值得花两小时认真对待在某高校嵌入式实验室带学生做课程设计时我连续三年遇到同一个问题近七成大三学生拿到开发板后卡在第一步——连编译器都装不全。有人用sudo apt install g装完就以为万事大吉结果写个std::thread直接报错有人照着某博客配了CMake却不会改CMakeLists.txt里的标准版本还有人把VS Code的Windows插件原封不动搬进Ubuntu折腾半天连代码补全都出不来。这根本不是“会不会写代码”的问题而是环境本身没被真正理解。Linux C环境不是一堆命令的拼凑它是一套有逻辑、有依赖、有版本边界的协作系统GCC负责把C源码翻译成机器指令glibc提供运行时基础能力CMake协调多文件编译流程而VS Code或Vim只是你和这套系统对话的“话筒”。标题里这个看似简单的“搭建”实际覆盖了工具链选型、ABI兼容性判断、构建系统分层设计、IDE深度集成四个关键层。它适合三类人刚从Windows转Linux的开发者别再用MinGW思维想问题、需要部署服务端C程序的运维/后端工程师你得知道-static-libstdc加在哪一行、以及准备参加ACM/蓝桥杯等竞赛的学生现场环境往往只预装基础工具。我试过用Docker一键拉镜像也试过从源码编译GCC最终发现最稳的方案是“精准控制最小侵入”——只装真正需要的组件每个包都明确它的职责边界每行配置都清楚它在解决什么问题。这不是教你怎么敲命令而是带你重建对Linux下C开发底层逻辑的认知。2. 环境整体设计与思路拆解拒绝“一键脚本”选择可验证的分层架构2.1 为什么不用Docker或虚拟机预装镜像很多人第一反应是拉个ubuntu:22.04镜像apt update apt install build-essential完事。这确实快但埋了三个隐患第一容器内/usr/bin/g和宿主机/usr/bin/g的ABI可能不一致当你在容器里编译出的二进制要拷到物理设备上运行时GLIBCXX_3.4.29这种符号缺失错误会让你凌晨三点还在查strings a.out | grep GLIBCXX第二Docker默认关闭ptrace权限调试gdb时直接报Operation not permitted第三竞赛现场或企业内网环境往往禁用Docker daemon。我带过的某公司后端团队就吃过亏测试环境用Docker跑得好好的服务上线到物理服务器后core dump最后发现是容器里glibc版本比生产机高两级。所以我的方案是裸机原生安装但绝不盲目apt install所有包——只装build-essential核心四件套gcc, g, make, dpkg-dev其他全部按需手动安装这样每个组件的版本、路径、依赖关系都清晰可控。2.2 工具链选型的底层逻辑GCC vs Clang静态链接 vs 动态链接C工具链不是越新越好。比如GCC 13虽然支持C23的std::expected但某国产ARM服务器只预装GCC 9.4强行升级会导致libstdc.so.6版本冲突。我实测过三种组合GCC 11.4 libstdc动态链接适合开发调试编译快GDB调试信息完整但部署时需确认目标机glibc版本Ubuntu 20.04对应glibc 2.3122.04对应2.35Clang 14 libc静态链接生成二进制体积大30%但彻底摆脱glibc依赖某边缘计算设备要求“单文件无依赖部署”这就是唯一解GCC 9.4 -static-libstdc折中方案保留GCC生态兼容性又避免运行时库版本问题ACM现场赛U盘里就存这个配置。选型依据很简单看你的交付物形态。如果交付的是.deb包用动态链接dpkg-shlibdeps自动分析依赖如果交付单个可执行文件必须静态链接如果交付Docker镜像用Clanglibc能减小镜像体积libc比libstdc小15%。这里没有银弹只有匹配场景的最优解。2.3 构建系统分层设计为什么CMake是必选项而Makefile只用于极简场景新手常问“写个hello world还要CMake直接g main.cpp不香吗”——这暴露了对构建系统本质的误解。g main.cpp本质是命令行调用编译器而CMake是描述项目结构的元语言。举个真实案例某传感器数据处理项目有127个.cpp文件分属driver/、algorithm/、network/三个目录其中algorithm/依赖OpenCV 4.5network/依赖Boost 1.78。如果手写Makefile你要维护三套编译规则、五种头文件搜索路径、七处库链接参数而CMake只需三行add_subdirectory(algorithm) add_subdirectory(network) target_link_libraries(sensor_core PRIVATE opencv_core boost_system)CMake会自动生成适配当前系统的Makefile或Ninja文件。更关键的是可移植性同一份CMakeLists.txt在Ubuntu上生成Makefile在Windows上生成Visual Studio工程在Mac上生成Xcode项目。我坚持用CMake的另一个原因是调试信息注入set(CMAKE_CXX_FLAGS_DEBUG -O0 -g3 -fno-omit-frame-pointer)这行配置让GDB能精确到每一行代码而手写Makefile时容易漏掉-g3导致调试时显示??符号。只有两种情况我用手写Makefile一是嵌入式裸机开发无OS无CMake运行环境二是写竞赛模板代码单文件追求极致编译速度。2.4 IDE集成策略VS Code的Remote-SSH模式为何比本地安装更可靠很多教程教你在Ubuntu桌面版装VS Code GUI再装C/C插件。这在个人电脑上可行但在服务器或远程开发场景就是灾难GUI界面卡顿、插件更新失败、调试器连接超时。我全程采用VS Code Remote-SSH模式——本地Windows/Mac装VS Code通过SSH连接到Linux服务器所有编译、调试、文件操作都在远端执行本地只负责显示界面。这样做的三大好处第一环境完全隔离你在服务器上装什么版本GCCVS Code就用什么不存在本地插件和远端工具链不匹配的问题第二资源占用低编译百万行代码时CPU和内存全在服务器笔记本风扇不狂转第三调试体验一致GDB server在远端启动VS Code通过miDebuggerPath指定/usr/bin/gdb断点、变量监视、内存查看和本地调试无差别。实测对比本地VS Code调试10万行项目平均响应延迟2.3秒Remote-SSH模式稳定在0.4秒以内。配置关键点在于settings.json里这三行cmake.configureArgs: [-DCMAKE_BUILD_TYPEDebug], cpp.debuggerPath: /usr/bin/gdb, remote.SSH.showLoginTerminal: false最后一行禁用登录终端避免每次连接都弹出无用的bash窗口。3. 核心细节解析与实操要点从GCC安装到CMake配置的硬核细节3.1 GCC安装的隐藏陷阱如何避开libstdc.so.6版本冲突sudo apt install build-essential看似省事但Ubuntu 22.04默认装GCC 11.3而某些工业软件SDK要求GCC 9.4。如果直接apt install gcc-9 g-9系统会同时存在/usr/bin/gcc-9和/usr/bin/gcc-11但/usr/bin/gcc软链接指向谁update-alternatives --config gcc输出的选项顺序决定默认版本而这个顺序受安装时间影响——后装的版本排前面。我踩过的坑是先装gcc-11再装gcc-9结果gcc --version还是显示11.3因为update-alternatives没自动切换。正确做法分三步查看当前替代方案update-alternatives --list gcc确认gcc-9是否在列表里如果不在手动注册sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 --slave /usr/bin/g g /usr/bin/g-9数字90是优先级必须高于gcc-11的默认优先级通常是100所以这里设90强制切换sudo update-alternatives --config gcc输入gcc-9对应的编号。提示--slave参数是关键它让g随gcc一起切换避免出现gcc -v显示9.4而g -v显示11.3的诡异状态。实测发现当gcc和g版本不一致时std::string的ABI可能错乱导致std::vectorstd::string在函数间传递时崩溃。3.2 CMakeLists.txt的黄金模板为什么project()必须带VERSION和LANGUAGES新手常写的CMakeLists.txt只有两行cmake_minimum_required(VERSION 3.10) project(MyProject)这会导致两个严重问题第一project()不声明语言时CMake默认只启用CC文件会被忽略第二不指定版本号find_package(OpenCV 4.5 REQUIRED)会因版本比较失败而报错。正确模板必须包含cmake_minimum_required(VERSION 3.16) # Ubuntu 20.04自带CMake 3.16向下兼容 project(MyProject VERSION 1.0.0 LANGUAGES CXX) # 显式声明C语言 set(CMAKE_CXX_STANDARD 17) # 强制C17标准 set(CMAKE_CXX_STANDARD_REQUIRED ON) # 拒绝降级到C14这里CMAKE_CXX_STANDARD_REQUIRED ON是安全阀。某次我帮学生调试他代码里用了std::optionalC17特性但忘记在CMake里设标准CMake默认用C14编译GCC报错optional is not a member of std而错误提示指向#include optional那行实际根源是编译标准没生效。另外VERSION字段不只是写个数字它会自动定义MyProject_VERSION_MAJOR等变量方便在代码里用#if MyProject_VERSION_MAJOR 2做条件编译。3.3 GDB调试配置的致命细节.gdbinit文件里必须写的三行VS Code的C/C插件默认用GDB但很多教程漏掉关键配置导致调试时看不到STL容器内容。比如std::vectorint v {1,2,3};在VS Code变量窗口只显示v {size3, capacity3}点不开具体元素。这是因为GDB默认不加载Python脚本扩展。解决方案是在用户目录下创建.gdbinitecho set print pretty on ~/.gdbinit echo set print object on ~/.gdbinit echo source /usr/share/gcc-11/python/libstdcxx/v6/printers.py ~/.gdbinit第三行路径中的gcc-11要替换成你实际安装的GCC版本号ls /usr/share/ | grep gcc可查。这行的作用是加载GCC自带的STL打印器让GDB能解析std::vector内部结构。实测对比未配置时GDB命令行输入p v只显示地址配置后p v直接输出{1, 2, 3}。VS Code里同样生效变量窗口点击v旁的三角箭头就能展开所有元素。注意printers.py路径在不同发行版有差异Debian系在/usr/share/gcc-*/python/CentOS系在/usr/share/gdb/auto-load/usr/lib64/必须根据find /usr -name printers.py 2/dev/null结果确认。3.4 VS Code远程调试的端口穿透如何让GDB server监听所有IPRemote-SSH模式下默认GDB server只监听127.0.0.1:3000这导致VS Code无法连接。必须修改launch.json{ version: 0.2.0, configurations: [ { name: (gdb) Launch, type: cppdbg, request: launch, program: ${workspaceFolder}/build/sensor_core, args: [], stopAtEntry: false, cwd: ${workspaceFolder}, environment: [], externalConsole: false, MIMode: gdb, miDebuggerPath: /usr/bin/gdb, setupCommands: [ { description: Enable pretty-printing for gdb, text: -enable-pretty-printing, ignoreFailures: true } ], customLaunchSetupCommands: [ { description: Allow remote debugging, text: set follow-fork-mode child, ignoreFailures: true } ], pipeTransport: { pipeProgram: ssh, pipeArgs: [-T, userserver], debuggerPath: /usr/bin/gdb }, sourceFileMap: { /home/user/project: ${workspaceFolder} } } ] }关键在pipeTransport部分——它告诉VS Code通过SSH管道启动GDB而不是直连localhost。这样GDB server在远端启动时自动绑定0.0.0.0无需额外开防火墙端口。实测发现如果误用miDebuggerServerAddress字段旧版配置会导致GDB server在本地启动完全失去远程意义。4. 实操过程与核心环节实现从零开始的完整搭建流程4.1 基础环境初始化Ubuntu 22.04下的精准包管理我们以Ubuntu 22.04为基准系统内核5.15glibc 2.35这是目前企业服务器和竞赛环境最主流的版本。第一步不是装编译器而是清理APT缓存并锁定基础工具链# 清理旧缓存避免apt update时下载过期索引 sudo apt clean sudo rm -rf /var/lib/apt/lists/* # 更新源列表使用阿里云镜像加速国内用户必备 sudo sed -i s/archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list sudo sed -i s/security.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list # 执行更新-y参数避免交互确认 sudo apt update -y # 安装基础工具注意build-essential已包含gcc/g/make但不包含gdb sudo apt install -y build-essential gdb git curl wget vim这里build-essential是核心它依赖gcc、g、make、dpkg-dev四个包。dpkg-dev常被忽略但它提供dpkg-buildpackage等打包工具当你需要生成.deb包时必不可少。curl和wget用于后续下载源码git用于克隆项目vim是远程服务器必备编辑器GUI环境不一定装。执行完这步g --version应显示11.3.0make --version显示4.3gdb --version显示12.1。如果版本不符说明系统源被污染需重装系统或手动清理/var/lib/dpkg/status。4.2 GCC多版本共存配置为竞赛和生产环境预留切换能力竞赛现场常要求GCC 9.4ACM-ICPC官方指定而生产环境用GCC 11.3。我们用update-alternatives实现无缝切换# 安装GCC 9.4Ubuntu 22.04默认不提供需添加toolchain PPA sudo apt install -y software-properties-common sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test sudo apt update -y sudo apt install -y gcc-9 g-9 # 注册GCC 9为替代方案优先级设为90低于默认100 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 \ --slave /usr/bin/g g /usr/bin/g-9 \ --slave /usr/bin/gcov gcov /usr/bin/gcov-9 # 注册GCC 11build-essential已安装但需显式注册 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100 \ --slave /usr/bin/g g /usr/bin/g-11 \ --slave /usr/bin/gcov gcov /usr/bin/gcov-11 # 验证注册结果 update-alternatives --list gcc # 应输出 # /usr/bin/gcc-9 # /usr/bin/gcc-11现在可通过sudo update-alternatives --config gcc交互切换或用命令行一键切# 切换到GCC 9 sudo update-alternatives --set gcc /usr/bin/gcc-9 # 切换回GCC 11 sudo update-alternatives --set gcc /usr/bin/gcc-11注意--slave参数必须成对出现g和gcov必须和gcc绑定在同一版本否则编译时会出现g: error trying to exec cc1plus: execvp: No such file or directory。这是GCC内部组件路径错乱导致的cc1plus是C前端编译器路径由gcc二进制文件硬编码版本不匹配时找不到对应模块。4.3 CMake项目骨架搭建从空目录到可编译的Hello World创建标准CMake项目结构这是所有C项目的起点mkdir -p ~/projects/hello-cpp/{src,build} cd ~/projects/hello-cpp # 创建顶层CMakeLists.txt cat CMakeLists.txt EOF cmake_minimum_required(VERSION 3.16) project(HelloCpp VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 添加可执行文件 add_executable(hello src/main.cpp) EOF # 创建源文件 mkdir -p src cat src/main.cpp EOF #include iostream #include string int main() { std::string msg Hello from Linux C!; std::cout msg std::endl; return 0; } EOF现在进入build目录执行编译cd build cmake .. -DCMAKE_BUILD_TYPEDebug make -j$(nproc) ./hello # 输出Hello from Linux C!-j$(nproc)是关键它让make使用所有CPU核心并行编译nproc命令返回CPU逻辑核心数。在16核服务器上编译速度比单线程快5倍以上。CMAKE_BUILD_TYPEDebug启用调试信息生成的二进制包含完整的符号表gdb ./hello可直接调试。4.4 VS Code远程开发配置三步完成从连接到调试在本地Windows电脑上安装VS Code然后第一步安装Remote-SSH插件打开VS Code扩展市场搜索“Remote-SSH”安装Microsoft官方插件图标是蓝色服务器。第二步配置SSH连接按CtrlShiftP打开命令面板输入“Remote-SSH: Connect to Host”选择“Add New SSH Host...”输入ssh -o StrictHostKeyCheckingno useryour-server-ipVS Code会自动生成~/.ssh/config条目Host my-server HostName your-server-ip User user StrictHostKeyChecking no第三步打开远程文件夹并配置调试按CtrlShiftP输入“Remote-SSH: Connect to Host”选择my-server等待连接成功。在远程终端中执行cd ~/projects/hello-cpp mkdir -p build cd build cmake .. -DCMAKE_BUILD_TYPEDebug make然后按CtrlShiftP输入“C/C: Edit Configurations (UI)”在CMake Tools设置里填Build Directory:~/projects/hello-cpp/buildCMake Generator:Unix MakefilesCMake Kit:GCC 11.3.0 x86_64-linux-gnu自动检测最后按F5启动调试VS Code会自动读取CMakeLists.txt生成launch.json并在hello二进制上设置断点。实测发现首次连接时VS Code会在远端自动安装vscode-server耗时约45秒后续连接秒级完成。5. 常见问题与排查技巧实录那些文档里不会写的实战经验5.1 问题速查表高频故障现象与根因定位故障现象可能原因排查命令解决方案g: error: unrecognized command-line option ‘-stdc17’GCC版本过低5.0g --version升级GCC或改用-stdc14undefined reference to std::thread::join()未链接pthread库nm -C build/hellogrep joinVS Code调试时变量显示optimized out编译未关优化readelf -S build/hellogrep debugCMake Error: The source directory does not contain CMakeLists.txt当前目录错误pwd ls -la进入项目根目录再执行cmake ..gdb: error while loading shared libraries: libncurses.so.5: cannot open shared object file缺少ncurses库ldd /usr/bin/gdb | grep ncursessudo apt install libncurses5这张表来自我三年带学生的故障日志统计覆盖92%的初学者问题。特别强调第二行std::thread::join()报错不是代码问题而是链接缺失。GCC默认不链接pthread必须显式声明。CMake里用target_link_libraries(target PRIVATE pthread)命令行则加-lpthread参数。5.2 调试器失效的终极排查从GDB到内核参数某次在客户服务器上GDB完全无法启动报错ptrace: Operation not permitted。常规方案如sudo sysctl kernel.yama.ptrace_scope0无效。深入排查发现先确认ptrace权限cat /proc/sys/kernel/yama/ptrace_scope值为1表示受限尝试临时放开echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope仍报错检查是否启用SELinuxsestatus输出enabled查看SELinux日志sudo ausearch -m avc -ts recent \| grep gdb发现avc: denied { ptrace } for pid1234 commgdb临时允许sudo setsebool -P allow_ptrace 1。实操心得企业级Linux服务器常启用SELinux或AppArmor它们比ptrace_scope更严格。setsebool -P allow_ptrace 1永久开启ptrace权限-P参数确保重启后生效。这是文档极少提及的深层障碍必须纳入环境检查清单。5.3 CMake缓存污染的清除术为什么rm -rf build/*不够CMake的缓存机制很聪明但也很顽固。有时改了CMakeLists.txtcmake ..却不生效因为CMakeCache.txt里存了旧配置。单纯rm -rf build/*可能残留.cmake隐藏目录。正确清理流程# 进入build目录 cd ~/projects/hello-cpp/build # 彻底删除所有CMake生成文件 rm -f CMakeCache.txt rm -f CMakeFiles/ rm -f cmake_install.cmake rm -f Makefile rm -f *.so rm -f *.a # 额外清理CMake可能在项目根目录生成CTestTestfile.cmake cd .. rm -f CTestTestfile.cmake更保险的做法是用CMake自带命令cd build cmake -U . # -U参数清除所有缓存我习惯在build目录下创建clean.sh#!/bin/bash rm -f CMakeCache.txt rm -rf CMakeFiles/ rm -f cmake_install.cmake Makefile rm -f *.so *.a echo CMake cache cleaned每次编译前执行./clean.sh cmake .. make杜绝缓存干扰。5.4 竞赛环境应急方案当apt不可用时的离线编译器部署ACM区域赛现场服务器常禁用网络apt install直接失败。我的离线方案是在相同Ubuntu版本的机器上用apt download下载所有依赖apt download build-essential gdb # 下载的.deb包build-essential_12.9ubuntu3_all.deb, gcc-11_11.3.0-1ubuntu1~22.04_amd64.deb等用dpkg-deb -I检查依赖关系dpkg-deb -I build-essential_12.9ubuntu3_all.deb \| grep Depends # 输出Depends: gcc ( 4:11.2), g ( 4:11.2), make, dpkg-dev ( 1.17.11)递归下载所有依赖包打包成compiler-offline.tar.gz现场用sudo dpkg -i *.deb安装--force-depends跳过未满足依赖通常已包含。实测证明22.04系统上build-essential全套离线包仅127MBU盘携带毫无压力。这是我在三次区域赛现场验证过的保底方案比背诵编译命令靠谱得多。6. 工具链版本验证与跨平台一致性保障6.1 版本矩阵校验确保GCC、CMake、GDB三者协同工作工具链不是孤立的版本错配会导致隐性故障。例如GCC 11.3需要CMake 3.16才能正确识别-stdc17而GDB 12.1需要glibc 2.34才能调试std::filesystem。我们建立版本校验脚本verify-env.sh#!/bin/bash # 检查GCC版本 GCC_VER$(gcc --version | head -n1 | awk {print $3}) if [[ $(echo $GCC_VER 11.0 | bc -l) -eq 1 ]]; then echo ERROR: GCC $GCC_VER too old, need 11.0 exit 1 fi # 检查CMake版本 CMAKE_VER$(cmake --version | head -n1 | awk {print $3}) if [[ $(echo $CMAKE_VER 3.16 | bc -l) -eq 1 ]]; then echo ERROR: CMake $CMAKE_VER too old, need 3.16 exit 1 fi # 检查GDB版本 GDB_VER$(gdb --version | head -n1 | awk {print $4}) if [[ $(echo $GDB_VER 12.0 | bc -l) -eq 1 ]]; then echo ERROR: GDB $GDB_VER too old, need 12.0 exit 1 fi # 检查glibc版本 GLIBC_VER$(ldd --version | head -n1 | awk {print $NF}) if [[ $(echo $GLIBC_VER 2.34 | bc -l) -eq 1 ]]; then echo ERROR: glibc $GLIBC_VER too old, need 2.34 exit 1 fi echo All tools version OK: GCC $GCC_VER, CMake $CMAKE_VER, GDB $GDB_VER, glibc $GLIBC_VER把这个脚本加入CI流程每次提交代码前自动运行。某次团队协作中一位成员本地用GCC 12.2编译但CI服务器是GCC 11.3脚本提前报错避免了std::spanC20特性导致的编译失败。6.2 Docker镜像一致性保障用Dockerfile固化开发环境虽然不推荐日常开发用Docker但CI/CD和团队协作必须统一环境。我们的Dockerfile不继承ubuntu:22.04而是用ubuntu:22.04作为基础再精准安装FROM ubuntu:22.04 # 设置时区和语言 ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone ENV LANGC.UTF-8 # 安装基础工具 RUN apt-get update apt-get install -y \ build-essential \ gdb \ git \ curl \ wget \ vim \ rm -rf /var/lib/apt/lists/* # 验证安装 RUN gcc --version g --version cmake --version gdb --version # 复制项目 WORKDIR /workspace COPY . . # 构建 RUN mkdir build cd build cmake .. -DCMAKE_BUILD_TYPEDebug make CMD [./build/hello]关键点在于 rm -rf /var/lib/apt/lists/*清理APT缓存使镜像体积减少120MB。构建命令docker build -t hello-cpp .生成的镜像docker run --rm hello-cpp输出Hello from Linux C!证明环境完全一致。这个Dockerfile被用在GitLab CI中每次push自动触发构建确保代码在任何机器上都能编译通过。7. 性能调优与资源监控让编译和调试更高效7.1 并行编译加速make -j参数的科学计算make -j不是越大越好。-j$(nproc)在16核机器上启动16个编译进程但每个进程需500MB内存16*500MB8GB若服务器只有4GB内存会触发OOM Killer杀进程。科学算法是最佳-j值 min(可用CPU核心数, 可用内存GB / 0.5)例如8GB内存16核服务器min(16, 8/0.5)min(16,16)16而4GB内存16核min(16,4/0.5)min(16,8)8。实测数据内存CPU核心-j值编译10万行耗时4GB1682m18s4GB16163m42s频繁swap8GB16161m55s在CMakeLists.txt中可设置# 启用并行编译 set(CMAKE_MAKE_PROGRAM make -j8)这样cmake --build .自动使用-j8无需每次手动输。7.2 GDB内存调试技巧用info proc mappings定位内存泄漏valgrind虽好但启动慢比原生慢20倍。GDB内置内存分析更快gdb ./hello (gdb) run # 程序运行后暂停 (gdb) info proc mappings # 输出类似 # 0x555555554000 0x555555555000 0x1000 0x0 /home/user/hello # 0x7ffff7a00000