linux 跟踪内存,用strace跟踪malloc内存分配

strace介绍

strace是一个非常有用的命令,它用于记录和跟踪程序运行期间收到的信号和调用的系统调用。

strace的简单使用

ubuntu64:~$ strace cat /dev/null

execve("/bin/cat", ["cat", "/dev/null"], [/* 32 vars */]) = 0

brk(NULL) = 0x112e000

access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

. . .

read(3, "", 131072) = 0

munmap(0x7f19a65be000, 139264) = 0

close(3) = 0

close(1) = 0

close(2) = 0

exit_group(0) = ?

+++ exited with 0 +++

每一行表示一个系统调用, 左边为系统调用的名称和参数, 右边为系统调用返回的结果。

参数

-c 统计每一系统调用的所执行的时间,次数和出错的次数等.

-d 输出strace关于标准错误的调试信息.

-f 跟踪由fork调用所产生的子进程.

-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.

-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.

-h 输出简要的帮助信息.

-i 输出系统调用的入口指针.

-q 禁止输出关于脱离的消息.

-r 打印出相对时间关于,,每一个系统调用.

-t 在输出中的每一行前加上时间信息.

-tt 在输出中的每一行前加上时间信息,微秒级.

-ttt 微秒级输出,以秒了表示时间.

-T 显示每一调用所耗的时间.

-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.

-V 输出strace的版本信息.

-x 以十六进制形式输出非标准字符串

-xx 所有字符串以十六进制形式输出.

-a column

设置返回值的输出位置.默认 为40.

-e expr

指定一个表达式,用来控制如何跟踪.格式如下:

[qualifier=][!]value1[,value2]...

qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.例如:

-eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none.

注意有些shell使用!来执行历史记录里的命令,所以要使用\\.

-e trace=set

只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.

-e trace=file

只跟踪有关文件操作的系统调用.

-e trace=process

只跟踪有关进程控制的系统调用.

-e trace=network

跟踪与网络有关的所有系统调用.

-e strace=signal

跟踪所有与系统信号有关的 系统调用

-e trace=ipc

跟踪所有与进程通讯有关的系统调用

-e abbrev=set

设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.

-e raw=set

将指 定的系统调用的参数以十六进制显示.

-e signal=set

指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.

-e read=set

输出从指定文件中读出 的数据.例如:

-e read=3,5

-e write=set

输出写入到指定文件中的数据.

-o filename

将strace的输出写入文件filename

-p pid

跟踪指定的进程pid.

-s strsize

指定输出的字符串的最大长度.默认为32.文件名一直全部输出.

-u username

以username 的UID和GID执行被跟踪的命令

用strace查看malloc内存分配

我在博客 c语言内存无法释放 中曾经提到过 :malloc采用了两中不同的方式来处理内存申请。

1. 若分配内存小于 128k ,调用 sbrk() ,将堆顶指针向高地址移动,获得新的虚存空间。

2. 若分配内存大于 128k ,调用 mmap() ,在文件映射区域中分配匿名虚存空间。

现在我们就strace 跟踪在那篇博客中的 Case #3, 在这之前我先修改 Case #3的代码,添加代码(完整的代码在博客尾部):

int *list;

list = malloc(1024*1024);

free(list);

这段代码用于查看当申请的内存大于128k时, malloc的处理方法。

strace 跟踪结果如下:

ubuntu64:~$ strace ./test_mem

execve("./test_mem", ["./test_mem"], [/* 32 vars */]) = 0

. . .

brk(0xd0e000) = 0xd0e000 //通过将堆顶向高地址移动到0xd0e000为进程分配内存

write(1, "before malloc, the top of heap i"..., 43before malloc, the top of heap is 0xced000) = 43

write(1, "address of a is 0xced420 top of "..., 62address of a is 0xced420 top of heap after malloc is 0xd0e000) = 62

brk(0xd40000) = 0xd40000 // 同样通过移动堆顶分配内存

write(1, "address of a is 0xd06430 top of "..., 62address of a is 0xd06430 top of heap after malloc is 0xd40000) = 62

write(1, "address of a is 0xd1f440 top of "..., 62address of a is 0xd1f440 top of heap after malloc is 0xd40000) = 62

brk(0xd72000) = 0xd72000 // 同样通过移动堆顶分配内存

write(1, "address of a is 0xd38450 top of "..., 62address of a is 0xd38450 top of heap after malloc is 0xd72000) = 62

write(1, "address of a is 0xd51460 top of "..., 62address of a is 0xd51460 top of heap after malloc is 0xd72000) = 62

brk(0xda4000) = 0xda4000 // 同样通过移动堆顶分配内存

write(1, "address of a is 0xd6a470 top of "..., 62address of a is 0xd6a470 top of heap after malloc is 0xda4000) = 62

write(1, "address of a is 0xd83480 top of "..., 62address of a is 0xd83480 top of heap after malloc is 0xda4000) = 62

brk(0xdd6000) = 0xdd6000 // 同样通过移动堆顶分配内存

write(1, "address of a is 0xd9c490 top of "..., 62address of a is 0xd9c490 top of heap after malloc is 0xdd6000) = 62

write(1, "address of a is 0xdb54a0 top of "..., 62address of a is 0xdb54a0 top of heap after malloc is 0xdd6000) = 62

brk(0xe08000) = 0xe08000 // 同样通过移动堆顶分配内存

write(1, "address of a is 0xdce4b0 top of "..., 62address of a is 0xdce4b0 top of heap after malloc is 0xe08000) = 62

//用mmap在文件映射区为进程分配内存

mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0cd5140000

write(1, "malloc end\n", 11malloc end) = 11

write(1, "before free, the top of heap is "..., 41before free, the top of heap is 0xe08000) = 41

brk(0xd0e000) = 0xd0e000 //释放通过brk移动堆顶分配的内存

write(1, "after free, the top of heap is "..., 41after free, the top of heap is 0xd0e000) = 41

munmap(0x7f0cd5140000, 1052672) = 0 //释放mmap分配的内存

exit_group(0) = ?

+++ exited with 0 +++

结果中省略了程序加载部分内容,从输出结果可以看出:

1. 在为链表申请节点时, 因为每个节点size小于128k(128k是可以调整的), malloc直接通过brk()函数在堆上分配内存。

2. 为list分配内存时,因为它需要1M内存, 所以malloc通过mmap()函数在在文件映射区域分配内存。

附录

1. 32位系统中进程虚拟空间布局

00501aa43cb171ea998fa2397fc66022.gif

2. Case #3代码

#include

#include

#include

#include

typedef struct node

{

char a[1024*100];

struct node *next;

}node;

int main()

{

node *node_first = NULL, *node_now;

node *a;

int i;

char s_cmd[100];

sprintf(s_cmd, "pmap -d %lu | grep mapped", getpid());

printf("before malloc, the top of heap is 0x%lx\n", sbrk(0));

for(i=0;i<10;i++){

a=(node *)malloc(sizeof(node));

a->next=NULL;

if(node_first==NULL) node_first=a;

else node_now->next=a;

node_now=a;

printf("address of a is 0x%lx ", a);

printf("top of heap after malloc is 0x%lx\n", sbrk(0));

}

int *list;

list = malloc(1024*1024);

printf("malloc end\n");

printf("before free, the top of heap is 0x%lx\n", sbrk(0));

while(node_first!=NULL)

{

node_now=node_first->next;

free(node_first);

node_first=node_now;

}

printf("after free, the top of heap is 0x%lx\n", sbrk(0));

free(list);

return 0;

}

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

归一化、标准化和正则化

归一化 Normalization 归一化一般是将数据映射到指定的范围&#xff0c;用于去除不同维度数据的量纲以及量纲单位。 常见的映射范围有 [0, 1] 和 [-1, 1] &#xff0c;最常见的归一化方法就是 Min-Max 归一化&#xff1a; 举个例子&#xff0c;我们判断一个人的身体状况是否健…

slf4j绑定器_用于ADFLogger的SLF4J绑定–缺少的部分

slf4j绑定器由于最好的原因&#xff0c;在我的日常工作中&#xff0c;我希望为ADF Logger Oracle ADF提供一个SLF4J适配器。 毫不奇怪&#xff0c;slf4j没有用于ADFLogger的适配器&#xff0c;但是由于ADFLogger只是Java Util Logging的轻巧包装&#xff0c;因此花了一个多小时…

核心网

在我们正式讲解之前&#xff0c;我想通过这张网络简图帮助大家认识一下全网的网络架构&#xff0c;通过对全网架构的了解&#xff0c;将方便您对后面每一块网络细节的理解。 这张图分为左右两部分&#xff0c;右边为无线侧网络架构&#xff0c;左边为固定侧网络架构。 无线侧…

JDK 11:轻松取出单文件Java源代码程序

JDK 11 Early Access Builds包含与JEP 330相关的预览功能&#xff08;“启动单个文件源代码程序”&#xff09;。 我之前在“ Shebang即将来到Java&#xff1f; ”和“ 为JDK 11提议的JEP 329和JEP 330 ”&#xff0c;由于JDK 11 Early Access Builds&#xff0c;在这篇文章中…

瑞利、莱斯与Nakagami-m信道衰落模型

一、信道的定义与调制信道的数学模型 1.信道的定义与分类 信道&#xff08;Channel&#xff09;是指以传输媒质为基础的信号通道。根据新到的定义&#xff0c;如果信道仅是指信号的传输媒质&#xff0c;这种信道称为狭义信道&#xff1b;如果这种信道不仅是传输媒质&#xff…

linux用if语句编程序,Shell 脚本基础 - 使用 if 语句进行条件检测

Bourne Shell 的 if 语句和大部分编程语言一样 - 检测条件是否真实&#xff0c;如果条件为真&#xff0c;shell 会执行这个 if 语句指定的代码块&#xff0c;如果条件为假&#xff0c;shell 就会跳过 if 代码块&#xff0c;继续执行之后的代码。if 语句的语法&#xff1a;if[判…

卫星导航定位 -- 坐标系统与时间系统

原文https://blog.csdn.net/f2157120/article/details/81210843 1 协议天球坐标系 以地球质心为坐标原点&#xff0c;以地球自转的轴为z轴 2 协议地球坐标系 3 WGS-84坐标系 4 CGS2000坐标系统 5 直角坐标系与大地坐标系转换 6 大地坐标系转换 7 时间系统 8 GNSS时间系统 …

博弈论学科整体概览

一、博弈论的概念 博弈论又被称为对策论&#xff08;Game Theory&#xff09;既是现代数学的一个新分支&#xff0c;也是运筹学的一个重要学科。博弈论主要研究公式化了的激励结构间的相互作用。是研究具有斗争或竞争性质现象的数学理论和方法。博弈论考虑游戏中的个体的预测行…

linux 进程组id 错乱,【Linux】终端,进程组,作业,会话及作业控制

终端概念在UNIX系统中,用用户通过终端登录系统后得到一一个Shell进程,这个终端成为Shell进程的控制终端 (Controlling Terminal),控制终端是保存在PCB中的信息,而我们知道fork会复制PCB中的信息,因此由Shell进程启动的其它进程的控制终端也是这个终端。默认情况 下(没有重定向)…

纳什均衡

纳什均衡&#xff08;或者纳什平衡&#xff09;&#xff0c;Nash equilibrium ,又称为非合作博弈均衡&#xff0c;是博弈论的一个重要策略组合&#xff0c;以约翰纳什命名。 定义 经济学定义 数学定义 纳什均衡的定义&#xff1a;在博弈G﹛S1,…,Sn&#xff1a;u1,…&#x…

奇异值分解(SVD)原理与在降维中的应用

奇异值分解 奇异值分解(Singular Value Decomposition&#xff0c;以下简称SVD)是在机器学习领域广泛应用的算法&#xff0c;它不光可以用于降维算法中的特征分解&#xff0c;还可以用于推荐系统&#xff0c;以及自然语言处理等领域。是很多机器学习算法的基石。本文就对SVD的…

自相关函数与互相关函数

1 概念 1 自相关函数 2 互相关函数 从定义式中可以看到&#xff0c;互相关函数和卷积运算类似&#xff0c;也是两个序列滑动相乘&#xff0c;但是区别在于&#xff1a;互相关的两个序列都不翻转&#xff0c;直接滑动相乘&#xff0c;求和&#xff1b;卷积的其中一个序列需要先…

Linux as4开启telnet,linux as4 虚拟机 上开启 telnet 和ssh 和 ftp 服务

1.telnet服务开启(1)输入[rootrehat ~]# chkconfig krb5-telnet --listkrb5-telnet on这是你的服务存在的状态&#xff0c;如果没有的话&#xff0c;可能是你的telnet名字和我的不一样&#xff0c;也可能是你的那个rpm包没有安装。我第一次的Linux中是没有安装的&#xff0…

5G的场景、需求、通信速率

5G三大典型场景 5G有三大典型场景&#xff0c;这三大场景描述了5G的需求也反应了5G与4G的不同&#xff0c;如图所示&#xff0c;三大场景分别为&#xff1a;增强型移动宽带通信&#xff08;eMBB&#xff09;&#xff0c;大规模机器型通信&#xff08;eMTC&#xff09;和超高可…

linux7禁用ipv6,RHEL 7 及 CentOS 7 彻底禁用IPv6的方法

原标题&#xff1a;RHEL 7 及 CentOS 7 彻底禁用IPv6的方法IPv6在未来可能成为主流&#xff0c;但是就目前而言&#xff0c;很多软件对IPv6的支持并不是很完善&#xff0c;可能导致各类问题。RHEL 7 & CentOS 7 在启动时默认是加载IPv6相关模块的&#xff0c;而禁用IPV6的方…

宏基站、分布式基站、小基站

基站即公用移动通信基站&#xff0c;是无线电台站的一种形式&#xff0c;是指在一定的无线电覆盖区中&#xff0c;通过移动通信交换中心&#xff0c;与移动电话终端之间进行信息传递的无线电收发信电台。 目前&#xff0c;在 5G时代 &#xff0c;“ 宏基站 为主&#xff0c; 小…

struts2面试问题_Struts2面试问答

struts2面试问题Struts2是用Java开发Web应用程序的著名框架之一。 最近&#xff0c;我写了很多Struts2教程 &#xff0c;在这篇文章中&#xff0c;我列出了一些重要的Struts2面试问题以及答案&#xff0c;以帮助您进行面试。 什么是Struts2&#xff1f; Struts1和Struts2之间…

什么是Mesh网络

网络间的通信原理 假设你的名字叫小不点&#xff0c;你住在一个大院子里&#xff0c;你的邻居有很多小伙伴&#xff0c;在门口传达室还有个看大门的李大爷&#xff0c;李大爷就是你的网关。当你想跟院子里的某个小伙伴玩&#xff0c;只要你在院子里大喊一声他的名字&#xff0…

根据谁创建资源授权资源

我的一位同事向我提出了一个关于StackOverflow的有趣问题&#xff0c;并由于我在Spring方面的经验&#xff0c;建议我回答一个很好的问题。 问题是&#xff1a;“ 如何基于使用注释在REST中创建资源的用户来授权特定资源 。” 要点是&#xff1a; 我想做的是创建一个名为Aut…

netbeans7.4_NetBeans 7.4的本机Java打包

netbeans7.4成为“ NetBeans 74 NewAndNoteworthy ”页面的NetBeans 7.4的新功能之一是“本机打包 ”&#xff0c;在该页面上被描述为“ JavaSE项目现在支持使用JavaFX提供的本机打包技术来创建本机包。 ” 我将使用一个非常简单的示例来演示NetBeans 7.4中的本机打包功能。 下…