在 SysUtils.Format / System.Move 中寻找随机 EAccessViolation 的原因
Looking for a cause of random EAccessViolation in SysUtils.Format / System.Move
我(我的应用程序的用户)遇到奇怪的 EAccessViolation 错误,一段代码没有错误的编程逻辑。 DisplayData 函数只是设置标签的标题 - 没有编译时错误,没有错误数据发送到 SysUtils.Format() 函数。
MadExcept 调用堆栈如下所示:
main thread (60):
00406a33 +067 MyApp.exe System 137 +0 Move
00452c9e +13e MyApp.exe System.SysUtils AddBuf
0045365d +931 MyApp.exe System.SysUtils WideFormatBuf
004528c0 +014 MyApp.exe System.SysUtils FormatBuf
00452ab4 +0c0 MyApp.exe System.SysUtils FmtStr
004529d2 +00e MyApp.exe System.SysUtils Format
004529b7 +01b MyApp.exe System.SysUtils Format
00b3aa55 +185 MyApp.exe mainunit 1506 +14 TMainForm.DisplayData
错误并非总是出现,函数可以调用几次(相同的参数)并且没有错误,然后随机出现错误。
我猜这里的内存有问题(有足够的可用内存) - 但不知道如何帮助用户 - 或在哪里寻找原因。
对这里可能发生的事情有什么想法吗?
...正如大卫要求显示真实代码,这里是:
TRadioButton(rgOperation.Controls[Integer(SelectedItem.Operation)]).Caption :=
TRadioButton(rgOperation.Controls[Integer(SelectedItem.Operation)]).Caption +
Format(' %s',[SelectedItem.History.OperationOn.TargetStr]);
在哪里:
rgOperation 是一个 TRadioGroup。该组中有 4 个单选按钮。
SelectedItem.Operation 是一个枚举 (0..3)。 SelectedItem.History.OperationOn.TargetStr 是一个字符串。 SelectedItem.History.OperationOn 的调用中没有任何内容为 nil。
如果
Format('%s', [SelectedItem.History.OperationOn.TargetStr])
导致 Format
内部发生访问冲突,那么唯一合理的结论是
SelectedItem.History.OperationOn.TargetStr
无效。所以,也许 SelectedItem.History.OperationOn
都是有效的,但 TargetStr
是无效的。这可能不太可能,因为我认为 TargetStr
是一个字符串,您必须非常努力地工作才能破坏字符串变量。
更有可能是SelectedItem
或History
或OperationOn
无效。也许其中之一是指已被内存管理器销毁并重新使用的对象。您使用过时的引用可能会导致您观察到的错误。
您可能会发现完全调试模式下的完整 FastMM 内存管理器 运行 有助于识别故障。如果您在对象被销毁后使用它,那么完全调试 FastMM 很可能会为您识别它。
我(我的应用程序的用户)遇到奇怪的 EAccessViolation 错误,一段代码没有错误的编程逻辑。 DisplayData 函数只是设置标签的标题 - 没有编译时错误,没有错误数据发送到 SysUtils.Format() 函数。
MadExcept 调用堆栈如下所示:
main thread (60):
00406a33 +067 MyApp.exe System 137 +0 Move
00452c9e +13e MyApp.exe System.SysUtils AddBuf
0045365d +931 MyApp.exe System.SysUtils WideFormatBuf
004528c0 +014 MyApp.exe System.SysUtils FormatBuf
00452ab4 +0c0 MyApp.exe System.SysUtils FmtStr
004529d2 +00e MyApp.exe System.SysUtils Format
004529b7 +01b MyApp.exe System.SysUtils Format
00b3aa55 +185 MyApp.exe mainunit 1506 +14 TMainForm.DisplayData
错误并非总是出现,函数可以调用几次(相同的参数)并且没有错误,然后随机出现错误。
我猜这里的内存有问题(有足够的可用内存) - 但不知道如何帮助用户 - 或在哪里寻找原因。
对这里可能发生的事情有什么想法吗?
...正如大卫要求显示真实代码,这里是:
TRadioButton(rgOperation.Controls[Integer(SelectedItem.Operation)]).Caption :=
TRadioButton(rgOperation.Controls[Integer(SelectedItem.Operation)]).Caption +
Format(' %s',[SelectedItem.History.OperationOn.TargetStr]);
在哪里: rgOperation 是一个 TRadioGroup。该组中有 4 个单选按钮。 SelectedItem.Operation 是一个枚举 (0..3)。 SelectedItem.History.OperationOn.TargetStr 是一个字符串。 SelectedItem.History.OperationOn 的调用中没有任何内容为 nil。
如果
Format('%s', [SelectedItem.History.OperationOn.TargetStr])
导致 Format
内部发生访问冲突,那么唯一合理的结论是
SelectedItem.History.OperationOn.TargetStr
无效。所以,也许 SelectedItem.History.OperationOn
都是有效的,但 TargetStr
是无效的。这可能不太可能,因为我认为 TargetStr
是一个字符串,您必须非常努力地工作才能破坏字符串变量。
更有可能是SelectedItem
或History
或OperationOn
无效。也许其中之一是指已被内存管理器销毁并重新使用的对象。您使用过时的引用可能会导致您观察到的错误。
您可能会发现完全调试模式下的完整 FastMM 内存管理器 运行 有助于识别故障。如果您在对象被销毁后使用它,那么完全调试 FastMM 很可能会为您识别它。