应用程序关闭后,弹出异常提示窗口,不知如何定位错误的代码?

时间:2021-07-28 19:57:40
调试应用程序时,关闭应用程序就弹出一个异常提示窗口。提示窗口的内容为“Exception EInvalidPointer in module OceanProject.exe at 00002864. Invalid pointer operation”。查看CPU,发现断点停留在系统SysReallocMem的FreeMem部分,可能是内存释放出错。但是不知道该如何定位源代码哪个部分出错了?应用程序是一个多文档窗口,子窗口为手动创建的,子窗口关闭时手动释放,而对话框为手动创建,也是对话框关闭时就手动释放。这个问题,不是随时都可以出现的,而是随机出现。请教各位大侠,该如何分析和解决?

17 个解决方案

#1


这种情况,可能是因为使用了其他的内存管理,最后Delphi内存管理器释放后,又做了其他的释放事件,就会导致你所说的上述情况

#2


出现这种情况,一般是你使用了自定义动态变量,就是除了Delphi能内存自动管理的 string、wideString、动态数组、Variants及接口 以外的 动态变量。这些动态变量需要你自己进行内存释放。一般用FreeMem来释放,用GerMem来创建。Dispose释放由New创建的变量。

#3


在你的关闭代码前设置断点,跟踪一下即可,可能是变量已经释放,然后再次调用释放出错

#4


最好的办法,调试。呵呵

#5


关注。。。

#6


可以分析,通过弹出的访问地址,基本可以定位到某行,或者某个函数的调用。

#7


不过你这个很简单了,直接找指针释放的地方就可以确定出错位置。

freemem
或者dispose
函数

#8


楼上,说的有点道理。可是,出问题的应用程序调用new、dispose各一次,而freemem根本没用。使用new为一个记录变量分配内存,然后把它保存TList变量中。从TList读取记录变量后,就调用dispose释放。
主要指针释放的地方是VCL的代码部分释放,自己的应用程序没用释放指针的代码。

#9


6楼说的,弹出异常提示框后,就查看CPU,发现断点停留在系统SysReallocMem的FreeMem部分。可是还是不知道源代码中那部分调用FreeMem出了问题。

#10


一直怀疑是不是内存出了问题,是不是什么地方释放了不存在的内存。可是,使用CheckMemv.pas添加到应用程序检查内存,发现了十个泄露的地方。可是不明白产生的日志什么意思,怎么通过它分析和定位代码出错的地方?
请教各位大侠,在开发中都使用啥工具检查内存问题?谢谢。

#11


if Assigned(p) then
  dispose(p) or freemem(p);

#12


设置断点调试,看具体在什么地方出错,一般是先释放了某个对象,而后又使用了这个被释放掉的对象。

#13


内存函数是否没有释放。根踪查到问题.

#14


静下心,设置断点一步一步跟踪,别人的都只是建议

#15


楼主,给你推荐一个错误处理控件:EurekaLog,用过之后相信你会一直用它的。安装上后注意在它的配置里面启用它,当发生错误后,它会告诉你错误出现在源代码行,以及调用顺序。

#16


是要释放的单元在你操作释放之前已经被释放了,或者你所指向的单元根本就不存在~

#17


使用15楼推荐工具EurekaLog,重现了问题。通过EurekaLog的调用堆栈CallBack的相关信息,发现程序弹出异常后,程序的堆栈最上面的函数为一个串口组件ApdCommPort(对应的文件为Awuser.pas)的关闭串口的DonePortPrim,出问题的代码为释放发送缓冲区的操作(调用FreeMem函数)。后面分析程序,出现这种问题的原因可能是串口正在发送数据(串口发送数据的操作在定时器的定时中断中执行),突然人为地关闭窗口,因为在关闭窗口的操作中有关闭串口的操作,可是没有关闭定时器。
后面,在窗口的关闭中,第一个操作就先把执行串口发送数据的操作的定时器关闭。这样,问题就不会重现。
多谢15楼的大侠,提供的工具,还有感谢各位大侠的帮助。

#1


这种情况,可能是因为使用了其他的内存管理,最后Delphi内存管理器释放后,又做了其他的释放事件,就会导致你所说的上述情况

#2


出现这种情况,一般是你使用了自定义动态变量,就是除了Delphi能内存自动管理的 string、wideString、动态数组、Variants及接口 以外的 动态变量。这些动态变量需要你自己进行内存释放。一般用FreeMem来释放,用GerMem来创建。Dispose释放由New创建的变量。

#3


在你的关闭代码前设置断点,跟踪一下即可,可能是变量已经释放,然后再次调用释放出错

#4


最好的办法,调试。呵呵

#5


关注。。。

#6


可以分析,通过弹出的访问地址,基本可以定位到某行,或者某个函数的调用。

#7


不过你这个很简单了,直接找指针释放的地方就可以确定出错位置。

freemem
或者dispose
函数

#8


楼上,说的有点道理。可是,出问题的应用程序调用new、dispose各一次,而freemem根本没用。使用new为一个记录变量分配内存,然后把它保存TList变量中。从TList读取记录变量后,就调用dispose释放。
主要指针释放的地方是VCL的代码部分释放,自己的应用程序没用释放指针的代码。

#9


6楼说的,弹出异常提示框后,就查看CPU,发现断点停留在系统SysReallocMem的FreeMem部分。可是还是不知道源代码中那部分调用FreeMem出了问题。

#10


一直怀疑是不是内存出了问题,是不是什么地方释放了不存在的内存。可是,使用CheckMemv.pas添加到应用程序检查内存,发现了十个泄露的地方。可是不明白产生的日志什么意思,怎么通过它分析和定位代码出错的地方?
请教各位大侠,在开发中都使用啥工具检查内存问题?谢谢。

#11


if Assigned(p) then
  dispose(p) or freemem(p);

#12


设置断点调试,看具体在什么地方出错,一般是先释放了某个对象,而后又使用了这个被释放掉的对象。

#13


内存函数是否没有释放。根踪查到问题.

#14


静下心,设置断点一步一步跟踪,别人的都只是建议

#15


楼主,给你推荐一个错误处理控件:EurekaLog,用过之后相信你会一直用它的。安装上后注意在它的配置里面启用它,当发生错误后,它会告诉你错误出现在源代码行,以及调用顺序。

#16


是要释放的单元在你操作释放之前已经被释放了,或者你所指向的单元根本就不存在~

#17


使用15楼推荐工具EurekaLog,重现了问题。通过EurekaLog的调用堆栈CallBack的相关信息,发现程序弹出异常后,程序的堆栈最上面的函数为一个串口组件ApdCommPort(对应的文件为Awuser.pas)的关闭串口的DonePortPrim,出问题的代码为释放发送缓冲区的操作(调用FreeMem函数)。后面分析程序,出现这种问题的原因可能是串口正在发送数据(串口发送数据的操作在定时器的定时中断中执行),突然人为地关闭窗口,因为在关闭窗口的操作中有关闭串口的操作,可是没有关闭定时器。
后面,在窗口的关闭中,第一个操作就先把执行串口发送数据的操作的定时器关闭。这样,问题就不会重现。
多谢15楼的大侠,提供的工具,还有感谢各位大侠的帮助。