20 printf 的调试

这篇具有很好参考价值的文章主要介绍了20 printf 的调试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在最开始的 cmd 编程中, 我们会使用到的最常见的输出, 包括一些时候调试的时候 我们最常使用到的函数 那肯定是 printf 了 

我们这里来调试一下 这个 printf 

还有一个原因是 之前在调试 malloc 的时候, malloc 虚拟内存分配的调试(1) 可以发现, 不仅仅是在 malloc 的时候调用了 malloc, 在 printf 的时候也调用了 malloc 

然后 我们这里来看一下 具体的情况, 以及一些 抽象的理解映射到 代码上面怎么处理的 

也可以参考一下 printf 命令 二者有一些相似之处, 不过一个是 可执行程序, 一个是 glibc 提供的库函数 

测试用例

同样是基于 这个最简单的 case, 不过这里 我们关注的是 printf 

root@ubuntu:~/ClionWorkStations/HelloWorld# cat Test01Sum.c 
#include "stdio.h"

int main(int argc, char** argv) {

int x = 2;
int y = 3;
int z = x + y;

char *p1 = (char *)malloc(20);
char *p2 = (char *)malloc(20);

*p1 = '1';
*(p1+1) = '2';

free(p2);

void *p3 = realloc(p1, 10);
printf("p1 : 0x%x - 0x%x \n", p1, p2);
printf("p3 : 0x%x - 0x%x \n", p3, p3);

}

printf 的核心流程

看一下 我们这里断点的位置, 确实是在 main 中的第一个输出的位置 

20 printf 的调试

大致的流程是 找到第一个占位符的位置, 然后输出 第一个占位符之前的常量字符串 到 s 

然后之后 从第一个占位符开始 循环处理每一个 占位符 

20 printf 的调试

处理当前占位符, 结合 占位符指定的格式 分为数字类输出 和 字符串类输出, 分别在 process_arg, process_string_arg 中输出 

这两个宏中 做的不同格式的 格式化的相关操作 

并且 查找下一个占位符, 输出两个占位符之间的常量字符串, 如果没有下一个占位符, 输出剩余的常量字符串到 s 

20 printf 的调试

我们这里是按照 十六进制 输出 p1地址, 因此 走的是 process_arg, 处理之前 s 中内容如下 

20 printf 的调试

 process_arg 宏处理完成之后, s 中的内容增加了作为参数的 p1 的地址的 十六进制 表示 

20 printf 的调试

查找下一个 占位符, 输出当前占位符 和 下一个 占位符之间的 常量字符串 

其实 和 printf 程序 还是有一些 相似之处的 

20 printf 的调试

printf 的输出

 如果当前 buf 是 LINE_BUF, 并且 正在输出 

则当前 待输出数据中包含 回车 的时候, 必须要 输出到设备, 输出内容到 回车 的位置 

然后 将带输出字符串 拷贝到 buf 中 

如果 待输出字符串大小超过了 缓冲区间大小, 或者是 行缓冲 碰到了 换行, 则要求输出内容到设备 

然后 如果还剩余待输出内容, 则输出内容到 缓冲/设备 

20 printf 的调试

然后 如果还剩余待输出内容, 则输出内容到 缓冲/设备 

判断根据 blockSize 对齐之后需要输出多少字节的内容到 缓冲/设备, 然后递归调用 new_do_write 来输出 (todo/block_size) 个blockSize 的内容到 缓冲/设备 

然后 将剩余的待输出数据 输出到 缓冲 

比如 todo 为 248, blockSize 为 100, 则递归调用 new_do_write 输出 200 个字节到 缓冲/设备 

剩余的 48 字节通过下面的 IO_default_xsputn 输出到 缓冲 

20 printf 的调试

printf 的持久化输出是基于系统调用 write 来实现的 

将缓冲的数据 通过 write 输出到 fp 中 

20 printf 的调试

在内核层面, 看到这一次 write 如下[这里调整了应用程序, 输出 和 上下文输出不太一样, 不过意思一样]

这里 有空我们, 展开来讲讲, 这里的 tty 的输出 

20 printf 的调试

printf 分配的缓冲区间

这里的 _IO_BUFSIZ 的宏为 8192, 下面的 st.st_blksize 为 1024 

优先取的后者, 因此 printf 输出 buf 的大小为 1024 字节

并且 上面, 如果是 字符设备, 还将 buf 增加了 行缓冲 的标记 

然后 这里分配的 缓冲区间, 也是来自于 malloc, 因此 分配的区间的地址信息, 可以根据 p1, p2 的地址 推导出来, 你可以试试 

一个简单地测试方式是 malloc 一个 p3, 然后 观察 p2, p3 之间的空间, 这块空间就是 printf 的缓冲区间 

20 printf 的调试

修改 用例如下 

root@ubuntu:~/ClionWorkStations/HelloWorld# cat Test01Sum.c 
#include "stdio.h"

int main(int argc, char** argv) {

int x = 2;
int y = 3;
int z = x + y;

char *p1 = (char *)malloc(20);
char *p2 = (char *)malloc(20);

*p1 = '1';
*(p1+1) = '2';

free(p2);
printf("p1 : 0x%x - 0x%x \n", p1, p2);

void *p3 = malloc(10);
printf("p1 : 0x%x - 0x%x \n", p1, p2);
printf("p3 : 0x%x - 0x%x \n", p3, p3);

}

输出如下, 可以推导出 printf 的 buf 地址为 0x602050, 大小为 (0x602440 - 0x602030) = 0x410 = 1040 

计算方式为 ALIGN_UP((1024 + 8), 16) = 1040 

地址为 p2 之后的空间, p3 之前的空间 

p1 : 0x602010 - 0x602030 
p1 : 0x602010 - 0x602030 
p3 : 0x602440 - 0x602440 

 完文章来源地址https://www.toymoban.com/news/detail-429519.html

到了这里,关于20 printf 的调试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32+HAL库调试printf串口打印

    目录 1 新建cubemx工程  2 配置系统时钟 3 配置串口引脚 4 生成keil工程 5 补充代码 5.1 重定向printf 5.2 main函数 6 编译烧录 7 实验现象         选择对应芯片         主频为64MHz         对应给到usart2的时钟也为64MHz            查阅原理图,可知usart2引脚连接了USB串口      

    2024年02月09日
    浏览(49)
  • STM32串口printf调试输出(SSCOM V5.13.1)

    PC与CPU相互通信就是通过USB Type_C接口和USB电平转换实现的。 我们可以看到,CPU通过管脚USART1连接CH340C芯片将USB转串口,实现PC与CPU之间的通信。 当然,这里用的是CH340的芯片,我们就需要安装ch340串口。 按住Ctrl+s生成代码。 在usart.h中添加头文件stdio.h 标准库的 printf函数 能方

    2024年02月12日
    浏览(50)
  • 使用clion配合STM32CubeMX开发stm32(包含断点调试,查看寄存器值,printf重定向)

    在嵌入式领域中开发以ARM公司的Cortex M内核为代表的单片机时程序员使用最多的IDE一定是Keil公司的MDK4 MDK5,而Keil已经脱离现代智能IDE,近年来IAR逐步向现代智能IDE靠近但还不足,一些芯片原厂提供了基于eclipse改装版IDE,这些工具在调试方面有优势,比如查看外设寄存器,内

    2024年04月24日
    浏览(50)
  • nuxt3:我们开始吧-开发-配置-部署

    一、背景介绍 2022 年 11 月 16 日,全球最大的 Nuxt 会议 Nuxt Nation 2022 在线举行,并正式发布了 Nuxt.js 3.0 的第一个稳定版本。Nuxt 3 是基于  Vite 、 Vue3  和  Nitro  的 Nuxt 框架的现代重写,具有一流的 Typescript 支持,是两年多研究、社区反馈、创新和实验的结果。为每个人提供了

    2023年04月12日
    浏览(45)
  • 讯飞版ChatGPT突然开始内测!我们连夜一手实测

    明敏 萧箫 发自 凹非寺 量子位 | 公众号 QbitAI 科大讯飞版ChatGPT产品,提前交卷了! 就在昨夜,讯飞骤然向开发者提供了内测通道,取名为 讯飞星火认知大模型 对外开启内测。 还有个神奇的英文名字Spark Desk,据说有“火花桌面智能助手”的意思。 讯飞这波操作,多少有点“

    2024年02月01日
    浏览(46)
  • PaddleX入门教程3:开始使用我们自己的模型进行推理

    首先我们要从网上下载几张图片,一张菠菜的、一张胡萝卜的、一张茄子的、一张西红柿的,建议找一些相对辨识度比较高的。因为我们现在的模型,可能没有那么强大。 如下:保存为jpg格式, 注意文件名的命名 。 然后,将 这些图片放置到前面我们的模型目录下。  此时

    2024年02月07日
    浏览(60)
  • 我们都低估了GPT-4,它才是梦开始的地方

    从今年开始 最近这两个月 AI技术带来的冲击一个接一个 我们的团队都在忙着研究各种AI 性能力这个方面 还真不如自己马上上手 用这些软件感受来的那么强烈 我觉得至少有几个产品 大家可以去试一下 第一 大家赶紧去看一个church GBT plus的账号 然后亲身体验一下GPT4的底层能力

    2023年04月12日
    浏览(39)
  • AI 图像生成工具可以取代摄影师吗?让我们从原理开始聊聊

    AI 的风已经吹向了每一个人,在这篇文章中我们一起来聊一聊 AI 图像生成的原理以及未来。 作为一个非职业的摄影爱好者,我通常会在 Instagram 上面搜罗各种各样的优质图片并将其放进我的收藏夹。其中,有一位我关注了很久的德国摄影师,他的作品有很多值得我学习的地方

    2024年02月03日
    浏览(45)
  • 袋鼠云春季生长大会最新议程来啦!4月20日我们云上见

    如今,数字经济正逐步走向深化应用、规范发展、普惠共享的新阶段,数字经济与实体经济深度融合、基础软件国产化替代成为数字时代主潮流。数字工具如何让千行百业共同实现韧性生长? 「 2023 袋鼠云春季生长大会」乘风而起,带来数实融合趋势下的产品焕新升级剖析、

    2023年04月17日
    浏览(85)
  • Net 高级调试之一:开始认识一些调试工具

    一、简介 从今天开始一个长系列,Net 高级调试的相关文章,我自从学习了之后,以前很多模糊的地方现在很清楚了,原来自己的功力还是不够,所以有很多不明白,通过学习 Net 高级调试,眼前豁然开朗,茅塞顿开。其实,刚开始要学习《Net 高级调试》,还是很是很困难的

    2024年02月08日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包