5_vscode+valgrind+gdb调试程序

ops/2024/9/20 3:56:26/ 标签: vscode, gdb, valgrind, 调试

需求

  1. 项目程序, 读取串口数据, 出现程序崩溃问题
  2. valgrind 可以调试定位内存问题: 内存泄漏,非法地址访问,越界访问等内存问题
  3. vscode + gdb 可视化调试效果, 比命令行简单快捷很多
  4. 期望使用vscode + valgrind + gdb 调试程序内存异常, 崩溃退出的问题

环境准备
sudo apt install valgrind gdb

调试

valgrind__gdb__9">1.valgrind + gdb 命令行调试程序

1.代码

51_mem_valgrind调试_内存泄漏_非法地址访问_越界.c

#include <stdio.h>
#include <string.h>
#include <stdint.h>// 1.内存泄漏
void memory_leak(void)
{char *p = (char *)malloc(1024);memset(p, 0, 1024);
}// 2.非法地址访问
void invalid_address_access(void)
{// uint8_t *p = 0x12345678;uint8_t *p = NULL;uint8_t val = *p;printf("val = %d\n", val);
}// 3.栈空间越界 读写
void corss_border_read_write(void)
{uint32_t a = 0x10;uint32_t *p = &a + 0x8;// 越界读 -- 导致逻辑错误printf("Invalid address read %x\n", *p);// 越界写 -- 程序错误*p = 0x12345678;printf("Invalid address write %x\n", *p);
}// 4.堆空间越界访问, 属于2.非法地址访问int main()
{memory_leak();corss_border_read_write();invalid_address_access();return 0;
}
2.编译

scons编译
SConstruct

env = Environment()
env["PROGSUFFIX"] = ".out"            # 可执行后缀.out
env["CCFLAGS"] = " -g3 -O0 -Wall"  # gdb 调试开关
env.Program("51_mem_valgrind调试_内存泄漏_非法地址访问_越界.c")

scons

g++ -o 51_mem_valgrind调试_内存泄漏_非法地址访问_越界.o -c -g3 -O0 --std=c99 51_mem_valgrind调试_内存泄漏_非法地址访问_越界.c
g++ -o 51_mem_valgrind调试_内存泄漏_非法地址访问_越界.out 51_mem_valgrind调试_内存泄漏_非法地址访问_越界.o

valgrindvgdb_73">3.valgrind开启vgdb调试

valgrind --leak-check=full --show-leak-kinds=all --vgdb=yes --vgdb-error=0 51_mem_valgrind调试_内存泄漏_非法地址访问_越界.out

3279 Memcheck, a memory error detector
3279 Copyright © 2002-2017, and GNU GPL’d, by Julian Seward et al.
3279 Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
3279 Command: ./51_mem_valgrind_____________________________________________.out
3279
3279 (action at startup) vgdb me …
3279
3279 TO DEBUG THIS PROCESS USING GDB: start GDB like this
3279 /path/to/gdb ./51_mem_valgrind调试_内存泄漏_非法地址访问_越界.out
3279 and then give GDB the following command
3279 target remote | /usr/lib/x86_64-linux-gnu/valgrind/…/…/bin/vgdb --pid=3279
3279 --pid is optional if only one valgrind process is running

valgrind 参数说明:

  • –leak-check=full 内存泄漏检测
  • –show-leak-kinds=all 详细各种异常检测
  • –vgdb=yes --vgdb-error=0 开启vgdb
gdb__93">4.gdb 调试

gdb 51_mem_valgrind调试_内存泄漏_非法地址访问_越界.out

Reading symbols from ./51_mem_valgrind调试_内存泄漏_非法地址访问_越界.out…
(gdb) target remote|vgdb #远程到vgdb调试
Remote debugging using |vgdb
relaying data between gdb and process 3279
Reading symbols from /usr/lib/debug/.build-id/7a/e2aaae1a0e5b262df913ee0885582d2e327982.debug…
0x0000000004001100 in _start () from /lib64/ld-linux-x86-64.so.2
c 按c开始运行

命令行效果如图:
![[<a class=valgrind+gdb调试程序.jpg]]" />

vscode__valgrind__gdb_109">2.vscode + valgrind + gdb调试

vscode_launchjson_110">1.vscode launch.json配置

使用国内几个大模型, 都无法给出正确可用的配置
在外网github搜到一个可参考的配置方法
链接: https://github.com/microsoft/vscode-cpptools/issues/4531
william-r-dieter commented on Aug 28, 2020
Here is the launch.json that worked for me:
launch.json

           "customLaunchSetupCommands" : [{"description": "Attach to valgrind","text": "target remote | /usr/lib64/valgrind/../../bin/vgdb","ignoreFailures": false  }],

vscode开启valgrind调试核心配置 launch.json

            "setupCommands": [{"description": "vgdb","text": "target remote | /usr/bin/vgdb ","ignoreFailures": true}],

launch.json 完整配置
注意不能照抄, 我的默认编译构建工具是scons

{"version": "0.2.0","configurations": [{"name": "(gdb) 启动","type": "cppdbg","request": "launch","program": "${fileDirname}/${fileBasenameNoExtension}.out","args": [],"stopAtEntry": false,"cwd": "${fileDirname}","environment": [],"externalConsole": false,"MIMode": "gdb","setupCommands": [{"description": "为 gdb 启用整齐打印","text": "-enable-pretty-printing","ignoreFailures": true},{"description": "vgdb","text": "target remote | /usr/bin/vgdb ","ignoreFailures": true}],"preLaunchTask": "scons"}]
}

valgrind_vgdb_173">2.valgrind 开启vgdb调试

valgrind --leak-check=full --show-leak-kinds=all --vgdb=yes --vgdb-error=0 51_mem_valgrind调试_内存泄漏_非法地址访问_越界.out

vscode_gdb_176">3.vscode 启动gdb远程

参考 1.vscode launch.json配置
F5 运行

效果如图
![[<a class=vscode+valgrind+gdb调试程序.jpg]]" />

总结

  1. valgrind + gdb 可以快速定位问题点
  2. 有概率gdb调试退出时, valgrind没有退出, 使用kill -9 强制退出kill -9 valgrind_pid
  3. 项目中使用cppcheck + valgrind, 找出潜在的问题5-6个问题点,其中一个映像深刻
    1. 字节缓冲区, data_len变量为异常值(默认128, 异常时为156023), 导致指针索引地址越界
  • 当通过C 指针索引地址时, 如果索引为异常值, 导致越界,或非法访问, 确实有风险.
  • python列表,索引值越界会报异常
  • c++ vector<uint8_t> 索引值越界会报异常

反思

  1. c++中尝试尽量将 bytes字节数据 转为vector<uint8_t> 处理
  2. 提交代码之前,进入安全稳定自测: valgrind, lsof, ss 排查内存,文件句柄,套接字资源是否有泄漏,漏洞,网络安全
  3. 尝试使用安全的语言, 如rust, 确认是否会有此问题

我是一名 嵌入式-系统-网络-机器人爱好者



http://www.ppmy.cn/ops/5267.html

相关文章

洛谷P4913 二叉树深度

【洛谷P4913 深基16.例3】二叉树深度 文章目录 【洛谷P4913 深基16.例3】二叉树深度题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 正确代码 题目描述 有一个 n ( n ≤ 1 0 6 ) n(n \le 10^6) n(n≤106) 个结点的二叉树。给出每个结点的两个子结点编号&#xff08;…

4月20日最大子数组和+买卖股票的最好时机Ⅱ

53.最大子数组和 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4]…

App测试中iOS和Android的差异

1、系统版本&#xff1a; iOS和Android系统版本的更新速度、使用人数比例以及功能的不同都可能导致应用程序在不同操作系统版本上的表现和兼容性存在区别。 例如&#xff0c;在iOS平台上&#xff0c;很多用户会更快地升级到最新版本的iOS系统&#xff0c;而在Android平台上&a…

C++语言·类和对象(下)

1. 初始化列表 我们回忆上节写的MyQueue类&#xff0c;其中有两个栈类和一个int类型&#xff0c;栈类因为其特殊性&#xff0c;要开空间&#xff0c;所以我们必须手搓Stack类的构造函数。但是正常来说MyQueue自动生成的构造函数会调用自定义类型的默认构造函数&#xff0c;也就…

【从浅学到熟知Linux】环境变量详谈(含使用程序获取环境变量的3种方法、如何查看环境变量)

&#x1f3e0;关于专栏&#xff1a;Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程及数据库等内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 环境变量基本概念查看环境变量的方法环境变量相关命令环境变量组织方式及获取环境变量的3种方法验…

NLP学习(1)-搭建环境

前言 仅记录学习笔记&#xff0c;如有错误欢迎指正。 环境搭建 一、环境软件安装&#xff1a; 1、Anaconda安装&#xff08;一款可以同时创建和管理多个python环境的软件&#xff09; (1) 安装链接&#xff1a; https://blog.csdn.net/m0_61531676/article/details/126290…

恒峰智慧科技-高效灭火:森林消防水源泵的优势与应用

在保护自然环境和人类生命安全的今天&#xff0c;森林防火的重要性日益凸显。然而&#xff0c;传统的消防方式往往受限于地理条件、人力和技术等因素&#xff0c;效率不高。这时&#xff0c;一种高效的森林消防设备——水源泵就显得尤为重要。 森林消防水源泵&#xff0c;顾名思…

Python 中整洁的并行输出

原文&#xff1a;https://bernsteinbear.com/blog/python-parallel-output/ 代码&#xff1a;https://gist.github.com/tekknolagi/4bee494a6e4483e4d849559ba53d067b Python 并行输出 使用进程和锁并行输出多个任务的状态。 注&#xff1a;以下代码在linux下可用&#xff0c…

主流App UI设计,7个在线平台供您选择!

在数字时代&#xff0c;用户界面&#xff08;UI&#xff09;设计变得非常重要&#xff0c;因为良好的UI设计可以改善用户体验&#xff0c;增强产品吸引力。随着技术的发展&#xff0c;越来越多的应用程序 ui在线设计网站的出现为设计师和团队提供了一种全新的创作方式。本文将盘…

A9 STM32_HAL库函数 之 DAC通用驱动所有函数的介绍及使用

A9 STM32_HAL库函数 之 DAC通用驱动所有函数的介绍及使用 1 通用定时器&#xff08;TIM&#xff09;预览1.1 HAL_DAC_Init1.2 HAL_DAC_DeInit1.3 HAL_DAC_MspInit1.4 HAL_DAC_MspDeInit1.5 HAL_DAC_Start1.6 HAL_DAC_Stop1.7 HAL_DAC_Start_DMA1.8 HAL_DAC_Stop_DMA1.9 HAL_DAC…

设计模式代码实战-桥接模式

1、问题描述 小明家有一个万能遥控器&#xff0c;能够支持多个品牌的电视。每个电视可以执行开机、关机和切换频道的操作&#xff0c;请你使用桥接模式模拟这个操作。 输入示例 6 0 2 1 2 0 4 0 3 1 4 1 3 输出示例 Sony TV is ON TCL TV is ON Switching Sony TV channel S…

mac 最小化全部程序回到桌面(基于alfred workflow)

前言 换到 mac 系统之后&#xff0c;很多快捷键根本就不好用&#xff0c;组合太多了&#xff0c;除了 cmd Q/W/A/S/X/R/Z/C/V &#xff0c;个人认为其它的真的一坨屎。像我的需求就是&#xff0c;开的窗口太多了&#xff0c;我需要全部最小化&#xff0c;再重新打开我需要那个…

[生活][杂项] 如何正确打开编织袋

编织袋打开的正确姿势 面对单线分离右边的线头&#xff0c;然后依次拉开即可

“手撕“三大特性之一的<继承>(上)

目录 一、为什么需要继承 二、什么是继承 三、继承怎么写 四、成员的访问 1.父类与子类的成员变量不同名 2.父类与子类的成员变量同名 3.父类与子类的成员方法不同名 4.父类与子类的成员方法同名 五、super关键字 一、为什么需要继承 先让我们看一段Java代码&#…

二维码门楼牌管理应用平台建设:取保候审的智能化监管

文章目录 前言一、取保候审的传统监管困境二、二维码门楼牌管理应用平台的优势三、取保候审备案信息的智能化处理四、保障居民合法权益五、展望未来 前言 随着信息技术的飞速发展&#xff0c;二维码门楼牌管理应用平台已成为现代社区治理的重要工具。本文重点探讨如何借助该平…

1、MYSQL系列-深入理解Mysql索引底层数据结构与算法

索引的本质 索引是帮助MySQL高效获取数据的排好序的数据结构 索引数据结构 二叉树红黑树Hash表BTree B-Tree B-Tree 叶节点具有相同的深度&#xff0c;叶节点的指针为空&#xff0c;所有索引元素不重复&#xff0c;节点中的数据索引从左到右递增排列 BTree(B-Tree变种) 非叶…

oepncv android 使用笔记

目录 cmakelist配置&#xff1a; 读取图片例子 需要下载&#xff1a; OpenCV-android-sdk cmakelist配置&#xff1a; set(OpenCV_DIR D:/GZ/soft/rknn-toolkit2/rknn-toolkit2-master/rknpu2/examples/3rdparty/opencv/OpenCV-android-sdk/sdk/native/jni/abi-${CMAKE_AND…

从零实现诗词GPT大模型:了解Transformer架构

专栏规划: https://qibin.blog.csdn.net/article/details/137728228 这篇文档我们开始对GPT的核心组件Transformer进行一个详细的讲解, 加急编写中…

COIN++: Neural Compression Across Modalities 论文阅读笔记

1. 论文基本信息 发布于&#xff1a; TMLR 2022 2. 创新点 使用元学习将编码时间减少了两个数量级以上&#xff0c;将编码共享结构进行编码&#xff0c;并对该网络应用调制来编码实例特定信息。量化和熵编码调制。虽然我们的方法在压缩和速度方面都大大超过了 COIN&#xff0…

docker初始化进程

docker run --init 是一个 Docker 命令的选项&#xff0c;用于在容器中运行一个初始化进程&#xff08;通常是 tini&#xff09;。这个初始化进程负责处理一些 Unix 信号&#xff08;如 SIGTERM 和 SIGCHLD&#xff09;&#xff0c;并确保容器中的进程能够正确地被管理和清理。…