当前位置: 首页 > news >正文

C/C++的printf会调用malloc()

排查内存问题(或相关的疑难杂症)时,可能一句printf就能让bug出现,或者赶走bug。你可能觉得很神奇,但这并不神奇。

至少我们可以在 Linux-x64 下,通过 malloc hook,来验证当前的编译环境下, printf 确实是调用了 malloc。 而 malloc 底层也不是吃素的, 默认是 glibc 的 ptmalloc 这个内存管理器, 如果本身你的程序把内存控制块写坏了, 继续 malloc 那就容易出现问题, 也就表现为 printf 影响了 bug 的出现。

来看代码。 伸手党可以直接看 godbolt:
https://godbolt.org/z/PPYMW613d
在这里插入图片描述

hook.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <malloc.h> // malloc_usable_size
#include <inttypes.h>
#include <pthread.h>// 颜色定义
#define GREEN "\x1b[32m"
#define YELLOW "\x1b[33m"
#define BLUE "\x1b[34m"
#define RESET "\x1b[0m"// 线程局部存储防止递归
static __thread int reentrancy_guard = 0;// 真实函数指针
static void* (*real_malloc)(size_t size) = NULL;
static void (*real_free)(void* ptr) = NULL;
static void* (*real_realloc)(void* ptr, size_t size) = NULL;// 初始化函数,使用 pthread_once 确保只初始化一次
static pthread_once_t init_once = PTHREAD_ONCE_INIT;static void init_real_functions() {//real_malloc = dlsym(RTLD_NEXT, "malloc");real_malloc = (void* (*)(size_t))dlsym(RTLD_NEXT, "malloc");real_free = (void (*)(void*))dlsym(RTLD_NEXT, "free");real_realloc = (void* (*)(void*, size_t))dlsym(RTLD_NEXT, "realloc");if (!real_malloc || !real_free || !real_realloc) {const char *error = "Error in `dlsym`\n";write(STDERR_FILENO, error, sizeof("Error in `dlsym`\n") - 1);_exit(1);}
}// malloc 钩子实现
void* malloc(size_t size) {if (reentrancy_guard) {return real_malloc ? real_malloc(size) : NULL;}pthread_once(&init_once, init_real_functions);reentrancy_guard++;void* ptr = real_malloc(size);reentrancy_guard--;if (ptr) {char buffer[256];int len = snprintf(buffer, sizeof(buffer), BLUE "malloc %ld %p\n" RESET, size, ptr);write(STDERR_FILENO, buffer, len);}return ptr;
}// free 钩子实现
void free(void* ptr) {if (reentrancy_guard) {if (real_free) real_free(ptr);return;}pthread_once(&init_once, init_real_functions);reentrancy_guard++;if (ptr) {size_t size = malloc_usable_size(ptr);char buffer[256];int len = snprintf(buffer, sizeof(buffer), GREEN "free %ld %p\n" RESET, size, ptr);write(STDERR_FILENO, buffer, len);}real_free(ptr);reentrancy_guard--;
}// realloc 钩子实现
void* realloc(void* ptr, size_t size) {if (reentrancy_guard) {return real_realloc ? real_realloc(ptr, size) : NULL;}pthread_once(&init_once, init_real_functions);reentrancy_guard++;void* new_ptr = real_realloc(ptr, size);reentrancy_guard--;if (new_ptr) {char buffer[256];int len = snprintf(buffer, sizeof(buffer), YELLOW "realloc %ld %p %p\n" RESET, size, ptr, new_ptr);write(STDERR_FILENO, buffer, len);}return new_ptr;
}

编译:

gcc -shared -fPIC hook4.c -o hook.so -ldl -O2

使用

int main()
{printf("Hello, World");return 0;
}
g++ main.cpp
LD_PRELOAD=./hook.so ./a.out

输出内容:

malloc 4096 0x3a842b0
Hello, World

相关文章:

C/C++的printf会调用malloc()

排查内存问题&#xff08;或相关的疑难杂症&#xff09;时&#xff0c;可能一句printf就能让bug出现&#xff0c;或者赶走bug。你可能觉得很神奇&#xff0c;但这并不神奇。 至少我们可以在 Linux-x64 下&#xff0c;通过 malloc hook&#xff0c;来验证当前的编译环境下&…...

spring mvc源码学习笔记之五

pom.xml 内容如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…...

3272 小蓝的漆房

将devc设置支持编译就能用新的遍历方式 for(auto &x : s)//遍历容器s&#xff0c;变量为x /* 多循环的嵌套&#xff1a; 计数是否需要重置为0; 是否因为ans定义成全局变量导致ans在比较多时候会出现错误*/ /* 1.对于一个标准色&#xff0c;对目标数组遍历&#xff0c; 如…...

MySQL使用触发器进行备份

触发器脚本备份 实现方案&#xff1a; 1.配置mysql调用外部脚本的插件mysqludf 链接&#xff1a;https://pan.baidu.com/s/1MCrf1u_SRWwcZoxM9JDNiw 提取码&#xff1a;kgt0 解压 2.解压后放进&#xff1a; mysql安装路径/lib/plugin/ 3.在mysql执行命令创建自定义函数&…...

数据结构与算法-顺序表

数据结构 顺序表 基本概念 顺序表&#xff1a;顺序存储的线性表链式表&#xff1a;链式存储的线性表&#xff0c;简称链表 顺序存储就是将数据存储到一片连续的内存中&#xff0c;在C语言环境下&#xff0c;可以是具名的栈数组&#xff0c;也可以是匿名的堆数组。 存储方式…...

OpenAI CEO 奥特曼发长文《反思》

OpenAI CEO 奥特曼发长文《反思》 --- 引言&#xff1a;从 ChatGPT 到 AGI 的探索 ChatGPT 诞生仅一个多月&#xff0c;如今我们已经过渡到可以进行复杂推理的下一代模型。新年让人们陷入反思&#xff0c;我想分享一些个人想法&#xff0c;谈谈它迄今为止的发展&#xff0c;…...

Shell编程详解

文章目录 一、Linux系统结构二、Shell介绍1、Shell简介2、Shell种类3、Shell查询和切换 三、Shell基础语法1、注释2、本地变量3、环境变量3.1、查看环境变量3.2、临时设置环境变量3.3、永久设置环境变量 4、特殊变量5、控制语句5.1、shell中的中括号5.2、if语句5.3、for循环5.4…...

跨站脚本攻击(XSS)详解

跨站脚本攻击&#xff08;XSS&#xff09;详解 跨站脚本攻击&#xff08;XSS&#xff0c;Cross-Site Scripting&#xff09;是一种通过在网页中注入恶意脚本&#xff0c;攻击用户浏览器的漏洞。攻击者可以利用XSS窃取用户敏感信息、劫持会话、或在受害者浏览器中执行恶意操作。…...

03-QT中的QMainWindow+对话框QDialog

文章目录 1.QMainWindow1.1菜单栏1.2 工具栏1.3 状态栏1.4 铆接部件1.5 核心部件&#xff08;中心部件&#xff09;1.6 资源文件 2.对话框2.1 基本概念2.2 标准对话框2.3 自定义消息框2.4 消息对话框2.5 标准文件对话框 1.QMainWindow QMainWindow是一个为用户提供主窗口程序的…...

c# 中Parallel.ForEach 对其中一个变量进行赋值 引发报错

在 C# 中使用 Parallel.ForEach 方法时&#xff0c;如果你尝试在并行循环中对共享变量进行赋值&#xff0c;很可能会遇到线程安全问题或竞争条件&#xff08;race conditions&#xff09;&#xff0c;这可能导致数据不一致、程序崩溃或其他不可预测的行为。 问题描述 假设你有…...

ElasticSearch备考 -- 整体脉络梳理

1、 search 、Update、reindex ElasticSearch 备考 -- 查询&高亮&排序 ElasticSearch 备考 -- 聚合查询 ElasticSearch 备考 -- 异步检索 2、search temple ElasticSearch备考 -- Search template 3、custom analyzer ElasticSearch 备考 -- 自定义分词 2、…...

vue Element Ui Upload 上传 点击一个按钮,选择多个文件后直接上传,使用防抖解决多次上传的问题。

问题&#xff1a; 在使用Element Ui Upload 上传文件时&#xff0c;选择多个文件上传时&#xff0c;on-change事件会一个一个返回上传的文件&#xff0c;导致前端不知道什么时候可以拿到全部上传的文件&#xff0c;再一起调后台接口。 解决方法&#xff1a; 上传文件后&…...

【HF设计模式】05-单例模式

声明&#xff1a;仅为个人学习总结&#xff0c;还请批判性查看&#xff0c;如有不同观点&#xff0c;欢迎交流。 摘要 《Head First设计模式》第5章笔记&#xff1a;结合示例应用和代码&#xff0c;介绍单例模式&#xff0c;包括遇到的问题、采用的解决方案、以及达到的效果。…...

运维人员的Python详细学习路线

以下是一条适合运维人员的Python详细学习路线&#xff1a; 一、基础入门阶段&#xff08;第1 - 2个月&#xff09; 环境搭建与基础语法&#xff08;第1个月&#xff09; 安装与配置 在运维常用的操作系统&#xff08;如Linux或Windows&#xff09;上安装Python。对于Linux系统…...

软件体系结构与设计模式

在软件开发中&#xff0c;软件体系结构和设计模式是两个至关重要的概念。它们帮助开发者设计出易于理解、可扩展、可维护的系统。尽管这两个概念密切相关&#xff0c;但它们分别关注系统的不同方面&#xff1a;软件体系结构关注的是系统整体结构的设计&#xff0c;而设计模式则…...

安徽省地图arcgis数据美化后mxd文件shp格式下载后内容测评

标题中的“安徽省地图arcgis数据美化后mxd文件shp格式”揭示了这个压缩包的内容是经过GIS处理的、针对安徽省地图数据。ArcGIS是一款由Esri公司开发的专业地理信息系统软件&#xff0c;用于处理、分析和展示地理空间数据。MXD文件是ArcGIS的项目文件&#xff0c;包含了地图布局…...

MySQL数据库备份与恢复策略

数据是企业和应用的核心资产,可靠的备份和恢复策略是确保数据安全性和业务连续性的关键。在本篇文章中,我们将详细介绍 MySQL 数据库的备份和恢复方法,包括逻辑备份、物理备份、自动化备份,以及常见问题的处理方法。 一、逻辑备份 逻辑备份是通过导出数据库的结构和数据生…...

go语言zero框架中教务crm系统的在职继承和离职交接的设计与实践

在GoZero中实现一个在职继承和离职交接的通用模块&#xff0c;涉及到顾问离职交接客户、领导离职交接审批单据等功能。为了使这个模块通用且易于扩展&#xff0c;我们可以分成几个部分&#xff1a; 1. **数据模型设计**&#xff1a;我们首先需要设计离职交接相关的数据模型。 …...

C# 设计模式(结构型模式):桥接模式

C# 设计模式&#xff08;结构型模式&#xff09;&#xff1a;桥接模式 在软件设计中&#xff0c;我们经常会遇到系统的变化频繁&#xff0c;或者需要灵活扩展功能的场景。这时&#xff0c;桥接模式&#xff08;Bridge Pattern&#xff09;便显得尤为重要。桥接模式是一个结构型…...

C# 设计模式(行为型模式):解释器模式

C# 设计模式&#xff08;行为型模式&#xff09;&#xff1a;解释器模式 (Interpreter Pattern) 什么是解释器模式&#xff1f; 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;用于定义一种语言的语法表示&#xff0c;并提供一个解释…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...