linux下程序运行到malloc处数次后出错,请教可能的出错原因,谢谢

ShiningIce 2006-10-16 10:53:54
简单说来就是在做小规模测试的时候仿佛没有问题,但是在大数据集测试时,这个动态分配并且有free操作的结构在malloc处运行了多次,系统给出如下出错信息:
Program received signal SIGSEGV, Segmentation fault.
(gdb) where
#0 0x400b0279 in free () from /lib/tls/libc.so.6
#1 0x400b1dfc in malloc () from /lib/tls/libc.so.6
#2 0x080729f0 in insert_write_entry (p=0xbffbf940, call_list=0x80a8e18, address=268440796, func=2, func_call_time=296999,
now=300325) at profiling.c:439 ------------//该行为下面的malloc语句行
#3 0x0804b694 in sim_main () at mem_profiling.c:129
#4 0x0805b74c in main (argc=4, argv=0xbffffa24, envp=0xbffffa38) at main.c:512

代码如下:
struct p_write_entry_t * cur, * temp;
temp = (struct p_write_entry_t *)malloc(sizeof(struct p_write_entry_t));

说明一下:不存在内存不够的问题;因为以前已经跑通了,现在在优化,内存空间要求上应该不存在问题。

不知道有哪些方面的原因可以这样?请赐教,谢谢:)
...全文
1632 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ShiningIce 2006-10-18
  • 打赏
  • 举报
回复
呵呵,应该我出来道歉哈,因为是我引起的
不过这个事情可以看出无论是HelianSis还是Wolf0403都是很严谨认真的人,大家在技术和学术上的讨论发生争论都是很正常的,大家的目的只有一个,在讨论中提高,如果得到了,那么大家都收获了,而且不打不相识嘛。
根据大家的建议,我把这个bug改掉了,原因呢,是我们用的pisa指令集的交叉编译器版本有点低,我对一个有自身带5个指针链的核心数据结构操作产生了其中一个指针的野指针操作,在一个比较小概率的地方发生了double-free而没有检测出来。
自己能抛砖引玉非常荣幸,不过程序又遇到其他bug了,应该还是差不多的原因,接着调...
再次谢谢大家!
Helianthus 2006-10-18
  • 打赏
  • 举报
回复
怎么说呢,我个人觉得事情的确有很多可能性,但是我们的作用就是利用手里得到的信息以
减少问题的分支数目。所以不能说根据部分事实做出的有依据的判断是无谓的猜测,事实上从前面我个人的分析也可以看出,我个人觉得在这个例子中,下溢造成问题的可能性远比上溢大得多。问题出在库函数内部,在参数不可能引入问题的情况下,自然是MEMORY内部的核心数据出了
问题。如果说没有工具,我们对问题就无能为力了?
当然,我也支持对代码的分析,但是代码很多,如果没有方向,在程序规模很大的时候我们往往会迷失方向的。依据问题的现场信息,尽可能地提供一个查找问题的方向怎么能说是无谓的猜测呢?我不是很理解。
当然,每一个人都有自己的做事风格,我理解。我无疑引发人生攻击,希望各位不要误解,谢谢!

HelianSis
2006/10/18
yingge 2006-10-17
  • 打赏
  • 举报
回复
没遇到过,个人认为不会是系统的原因

帮你顶=待高人解答吧。
飞哥 2006-10-17
  • 打赏
  • 举报
回复
似乎楼上狠有道理
Helianthus 2006-10-17
  • 打赏
  • 举报
回复
很显然,问题是因为内存越界造成的,这样的事情我遇到过很多次。
比如你分配了一块内存,但是在操作过程中出现了溢出(上溢或是下溢,从你的情况看,应该是下溢,也就是说你操作了内存指针偏移为负数的空间);导致这块内存在回收时因为其隐含在下溢空间内信息被异常修改,从而被加入到错误的内存空闲块队列中,当这块内存再次分配就会出现问题。

建议对你代码操作内存的地方做下溢检查,应该可以发现问题的。

HelianSiS
2006/10/17
Wolf0403 2006-10-17
  • 打赏
  • 举报
回复
呵呵,我只是觉得这里有点奇怪。

出错最常见的原因是某处越界访问写入数据,但是在进行静态代码分析和使用 valgrind 跟踪之前我不想做无谓的猜测。
zhenhaojia 2006-10-17
  • 打赏
  • 举报
回复
同意:Helianthus()
jy02379140 2006-10-17
  • 打赏
  • 举报
回复
可能下标越界.溢出了..
回答完毕
Helianthus 2006-10-17
  • 打赏
  • 举报
回复
Wolf0403网友,你好:
你问的问题很不错。
我们看到的函数调用栈显示正如你所说的,malloc中嵌套调用了free。
但是这之间并没有关系。malloc函数的内部实现有很多,为什么就不能
有内部间接调用free的?事实上我在一些自成体系的嵌入式软件中的memory
模块里面就发现类似的例子。
我还是把我当时分析这个问题的思路大致说一说,
1. 首先从问题的描述和现场的堆栈函数调用关系,说明程序CRASH在free函数中。
在通常情况下,除非接口传入的参数有误,一般情况下象free这一类的函数
是不会出问题(当然,memory模块的核心数据被破坏也会导致类似的问题)
2. 可是因为malloc函数的参数接口非常简单,只有一个数据块的长度,因此我们
可以立即知道这次CRASH不是因为非法参数导致的,问题出在了MEMORY自己的核心
数据上。
3. 正如我刚才和你说的,我曾经遇到过这样的版本,malloc分配内存是根据输入参数
需要内存块的大小来决定从内部空闲内存块队列上某一个具体大小队列中获取指定的
数据。现在CRASH了,说明这里面的数据出现了问题。
4. 在通常情况下,我们是不能对MEMORY数据的内存破坏的。当时如果我们对分配的
内存块操作溢出的话,事情就可能发生变化。因为大多数MEMORY模块都会在分配给
用户内存块前端预留一定的字节空间用于说明该分配内存的信息,如大小信息等。
这样当内存被回收的时候,MEMORY模块就能根据前端的信息快速的定位出该内存块
应该被回收到哪一个SIZE的内存队列中。当时如果这个SIZE信息被CRASH的话,
由于被添加到错误的队列上,后续再执行内存分配就会出现问题,这也是我为什么说
可以先检查下溢的原因吧。
5. 至于你说的为什么malloc会调用free,老实说我也不知道。当时我觉得这取决于malloc
的内部实现,而我曾经看过这样的实现,所以我不觉得奇怪。
6. 当然,从我上面的个人的分析来看,也许不是内存下溢造成的,只是我个人觉得这种
方式的可能性大一些。至于LINUX下面对内存分析的工具,MEM_WATCH,valgrind都可以。
更简单的是利用MEM_WATCH的思路自己对malloc、free等函数直接重定向更简单一些吧。

当然,这只是我个人对这个问题的初步分析。如果有现场的话,可以直接看看寄存器就知道
CRASH的指令到底试图操作的是哪一个内存队列,不过这需要作者直接再深入看看。


谢谢!

HelianSiS
2006/10/17
7.
ShiningIce 2006-10-17
  • 打赏
  • 举报
回复
好的,谢谢Wolf0403
Wolf0403 2006-10-17
  • 打赏
  • 举报
回复
Helianthus:

仔细看 gdb 的 where 输出了么?free 从 malloc 中被调用,怎么解释?

检查程序的内存使用问题就用我说的 valgrind
ShiningIce 2006-10-17
  • 打赏
  • 举报
回复
我对linux还不是太熟悉,刚搜了下动态内存扫描工具没有发现linux下使用的;能说得详细一些么?如使用什么工具,简单的操作等,真的谢谢啊~
Helianthus 2006-10-17
  • 打赏
  • 举报
回复
象下面这样的代码就是一个下溢的例子。
问题也许不在于你所改动的地方,也可能是以前代码的残留问题。
这样的问题引发错误本质上和内存的使用程度有比较大的关系,内存紧张这样的问题暴露
出来的概率也非常高。用动态内存扫描工具找一找吧。

long index = -1;
char * ptr = malloc(100);
if (ptr)
{
ptr[index] = '\0';//内存下溢!!!
free(ptr);
}

HelianSiS
2006/10/17
ShiningIce 2006-10-17
  • 打赏
  • 举报
回复
谢谢 HelianSiS,那请问典型的内存下溢操作是什么呢?空栈时出栈,或者其他什么?
我改动的地方基本都是属于双链的增删操作,怎么会产生下溢不大明白。谢谢:)
Wolf0403 2006-10-17
  • 打赏
  • 举报
回复
#0 0x400b0279 in free () from /lib/tls/libc.so.6
#1 0x400b1dfc in malloc () from /lib/tls/libc.so.6

what the hell...
从没经历过。帮顶。。

建议用 valgrind 的 memcheck 辅助检查一下看看有没有更多隐含的错误,也许可以帮助推断。
随着元宇宙概念兴起与虚拟数字人技术快速发展,虚拟主播、在线教育虚拟助教、元宇宙社交等应用场景对实时动作表情驱动系统提出更高需求。当前主流动作捕捉方案多依赖专业光学动捕设备或深度相机,设备成本高昂、部署复杂,难以在普通用户场景普及。本研究设计并实现一套基于普通单目摄像头的虚拟数字人实时动作表情驱动系统,旨在降低数字人内容生产门槛。系统采用Unity作为主开发引擎,结合Blender进行数字人模型构建与BlendShape表情系统制作,使用MediaPipe框架实现人脸关键点检测与人体姿态估计,通过C#脚本完成实时数据理与渲染控制。系统包含五个关键模块:人脸关键点检测(MediaPipe Face Mesh提取468个关键点)、人体姿态估计(MediaPipe Pose识别33个骨骼关键点)、表情迁移映射、动作平滑优化(卡尔曼滤波与贝塞尔曲线插值消除抖动)、实时渲染(60fps流畅渲染,支持直播推流与视频录制)。实验结果表明,系统在普通笔记本上可实现60fps实时驱动,人脸关键点检测准确率达98.7%,人体姿态估计平均误差小于5像素,表情迁移相似度达92.3%。 【课程报告内容】 摘要 第1章 绪论 第2章 相关技术与理论基础 第3章 系统架构设计 第4章 关键模块设计与实现 第5章 实验与结果分析 第6章 总结与展望 参考文献
内容概要:本文提出了一种基于蒙特卡洛模拟与拉格朗日松弛法的分散式优化策略,用于解决电动汽车充电站在分时电价机制下的有序充电调度问题。通过蒙特卡洛方法模拟电动汽车充电行为的随机性,生成多样化负荷场景,构建以降低电网负荷波动和用户充电成本为目标的优化模型;采用拉格朗日松弛法对耦合约束进行解耦,实现分布式求解,在保障用户隐私的同时提升计算效率。文中设计了详细的仿真场景,系统分析了该调度策略对电网负荷特性和用户经济性的影响,验证了所提方法在实际应用中的有效性与可行性。; 适合人群:具备电力系统运行、优化算法理论及Matlab编程能力的研究生、科研人员以及从事智能电网与电动汽车相关领域的工程技术人员。; 使用场景及目标:①应用于城市规模化充电站集群的有序充电管理,实现电网“削峰填谷”;②为电力公司制定科学合理的分时电价政策提供量化分析工具;③支撑智能电网中需求侧资源的分布式协同优化调度研究与系统设计。; 阅读建议:建议结合提供的Matlab代码深入理解算法实现流程,重点掌握蒙特卡洛场景生成机制与拉格朗日松弛迭代求解过程,可通过调整参数设置复现不同工况下的仿真结果,以深化对分散式优化机制与调度效果之间关系的理解。
内容概要:本文研究了基于阶跃响应的V-Tiger自动增益调整PID控制器优化方法,并提供了完整的Matlab代码实现。通过深入分析PID控制的核心性能指标与V-Tiger控制器的动态特性,提出了一种融合阶跃响应特征提取与多目标协同优化的自动整定方案,设计了具备自适应迭代校正能力的优化机制,有效提升了控制系统的响应速度、稳定性和抗干扰能力。文中系统阐述了整定原理、算法架构设计及性能验证流程,通过仿真实验充分验证了该方法在复杂工业控制场景下实现高精度参数自整定的可行性与优越性,为智能PID控制提供了可复现、可拓展的技术路径。; 适合人群:具备自动控制理论基础和Matlab编程能力,从事控制工程、自动化、电气工程等领域研究的研发人员及高校研究生。; 使用场景及目标:①应用于需要高精度PID参数整定的工业控制系统中,如电机驱动、温度控制、电力电子变换器等;②为科研人员提供一种可复现、可扩展的智能PID整定方法,用于提升系统动态性能与鲁棒性;③作为教学案例帮助学生理解PID整定原理与现代优化算法的融合应用。; 阅读建议:建议读者结合文中的Matlab代码逐模块运行与调试,重点关注阶跃响应特征提取与增益优化策略的实现逻辑,同时可尝试将其应用于实际控制系统中进行对比验证,以深化对自动整定机制的理解。

70,038

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧