【发布时间】:2015-01-01 00:37:18
【问题描述】:
我一直在使用看似简单的代码的多平台应用程序中收到 SIGSEGV (11) 异常。每次发生这种情况时,调试器似乎都会将我带到不同的地方。所以我拼凑了一个简单的应用程序来演示这一点。它不会发生在 Windows 中,但会发生在所有其他平台上。 Windows 工作正常。我每次都能重新创建并在下面演示的唯一示例来自XSuperObject 库。
启动一个新的空白多平台应用程序并添加一个按钮。
DFM
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 259
ClientWidth = 310
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object Button1: TButton
Position.X = 136.000000000000000000
Position.Y = 96.000000000000000000
TabOrder = 0
Text = 'Button1'
OnClick = Button1Click
end
end
现在只为这个按钮的OnClick 事件添加一个处理程序。
代码
unit uMain;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
XSuperObject;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
uses
IOUtils;
procedure TForm1.Button1Click(Sender: TObject);
var
O: ISuperObject;
L: TStringList;
FN: String;
begin
FN:= TPath.Combine(TPath.GetHomePath, 'MyApp');
ForceDirectories(FN);
FN:= TPath.Combine(FN, 'Test.json');
O:= SO;
O.S['foo']:= 'bar';
L:= TStringList.Create;
try
L.Text:= O.AsJSON(True);
L.SaveToFile(FN);
finally
L.Free;
end;
O:= TSuperObject.ParseFile(FN); // <-- SIGSEGV (11) happens here
end;
end.
例如,在使用 OSX 的测试中,按下按钮会产生异常:
Project SIGSEGVTest raised exception class SIGSEGV (11).
当我点击Break 时,它会将我带到1394 行上的一些System.Character.inc 文件,这似乎是一堆某种二进制文件:
db $59,$40,$00,$00,$00,$00,$00,$40,$8F,$40,$00,$00,$00,$00,$00
在某些情况下,我反复收到此异常,似乎是无限的。我似乎无法追踪它的来源。我没有任何运气来搜索这个,我发现的所有内容要么是另一种语言,没有答案,要么是另一种 pascal IDE(例如 Lazarus)。时不时地,在与上述相同的情况下,应用程序只是锁定而不是给出这个异常。有时,当我单击Break 时,调试器不会带我去任何地方。
我确实理解异常的含义(与访问冲突基本相同),但为什么我在除 Windows 之外的所有平台上都出现此异常?
注意
过去,我确实设法通过使用泛型 TList<> 而不是传统的已弃用 TList 来解决此问题。但这只是一个,我正在努力找出我在这么多地方得到这个异常的真正原因。已经为此奋斗了好几个星期了。
我正在使用 Delphi XE7 Update 2,我的 XSuperObject 副本现在刚刚更新为最新版本,但运气不佳。
我还安装了最新的 IDE Fix Pack,但仍然没有成功。
更新
例如,当在 iOS 模拟器 (iOS 7.1) 中运行相同的应用程序而不进行调试时,我会得到以下信息:
Access violation at address 0060907D, accessing address 00000000.
更新
这是来自 OSX 的崩溃报告(太大,无法放入此处):
更新
似乎指针以某种方式被破坏了。到目前为止,在我看到的大多数情况下,当我访问一个应该初始化的指针时就会发生这种情况。例如,当我有一个经典的 TList 时,它让我可以很好地使用它,除非我尝试读取其中一个指针并且我得到了同样的错误。完全相同的代码在 Windows 中完美运行。例如,MyObj:= TMyObj(MyTList[0]); 在那里我可以看到正确的指针,但无论如何都会产生这个异常。不幸的是,由于我试图重现这种特殊情况,我不能。
更新
我终于设法单步执行XSuperObject 库(以前我在尝试设置断点以单步执行时遇到了其他奇怪的问题)。它在以下构造函数中的第 587 行中断:
constructor TBaseJSON<T, Typ>.Create(JSON: String; const CheckDate: Boolean);
type PInterface = ^IInterface;
var
JVal: IJSONAncestor;
PIntf: PInterface;
begin
FCheckDate := CheckDate;
if (Self.InheritsFrom(TSuperArray)) and (Trim(JSON) = '{}') then JSON := '[]';
JVal := TJSONObject.ParseJSONValue(JSON, FCheckDate);
if JVal.QueryInterface(GetTypeData(TypeInfo(T)).Guid, FJSONObj) = S_OK then // <-- Happens here
FInterface := TValue.From<T>(FJSONObj).AsInterface
else
FCasted := JVal
end;
【问题讨论】:
-
现在回顾我过去的工作,我意识到我在生产应用程序中解决了这个完全相同的错误,方法是先将它加载到一个字符串列表然后解析它。似乎是唯一的办法。不过我还是很想知道为什么。
-
你需要找到给出错误的代码
-
@David 我终于设法通过了
XSuperObject库。请参阅上面的更新。我有点期待其他人以前一定遇到过这种情况并且知道发生了什么,但我想我是世界上唯一发生这种情况的人? -
深入挖掘。 JVAL 是零吗?还是 TypeInfo 返回 nil?
-
@David 他们都不是
nil。
标签: delphi firemonkey segmentation-fault delphi-xe7