Я получаю исключения SIGSEGV (11)
в многоплатформенных приложениях с, казалось бы, простым кодом. Кажется, отладчик ведет меня в другое место каждый раз, когда это происходит. Поэтому я собрал простое приложение, чтобы продемонстрировать это. Это не происходит в Windows, но это происходит на всех других платформах. Windows отлично работает. Это единственный пример, который я могу воссоздать каждый раз и демонстрировать ниже, из библиотеки XSuperObject
.Получение ошибок SIGSEGV (11) во многих местах
Запустите новое пустое многоплатформенное приложение и добавьте только одну кнопку.
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
, он принимает меня в какой-то System.Character.inc
файл на линии 1394
, которая, как представляется, представляет собой кучу двоичных данных:
db $59,$40,$00,$00,$00,$00,$00,$40,$8F,$40,$00,$00,$00,$00,$00
В некоторых случаях я получаю это исключение повторно за то, что кажется бесконечным. Я не могу проследить, откуда он. Мне не повезло в этом, все, что я нахожу, либо на другом языке, и без ответа, либо на другом паскале IDE (например, Lazarus). Время от времени, в том же сценарии, что и выше, приложение просто блокируется, а не дает это исключение. Также иногда отладчик не принимает меня нигде, когда я нажимаю Break
.
Я понимаю, что означает исключение (по сути, такое же, как Access Violation), но почему я получаю это исключение на всех платформах, отличных от Windows?
ПРИМЕЧАНИЕ
мне удалось исправить это в одном месте в прошлом, используя дженерики TList<>
, а не традиционный осуждается TList
. Но это всего лишь одно, и я изо всех сил пытаюсь выяснить причину, по которой я получаю это исключение во многих местах. Это сражалось уже несколько недель.
Я использую Delphi XE7 Update 2, и моя копия XSuperObject
была обновлена прямо сейчас с последней, но не удачей.
Я также установил последнюю версию Fix Pack IDE и все еще не повезло.
ОБНОВЛЕНИЕ
Когда, например, работает этот же приложение изнутри тренажера IOS, (IOS 7.1) без отладки, я получаю следующее:
Access violation at address 0060907D, accessing address 00000000.
UPDATE
Вот отчет аварии из OSX (слишком большой, чтобы поместиться здесь):
UPDATE
Это почти похоже на указатель s как-то развращаются. В большинстве случаев, которые я видел до сих пор, это происходит, когда я обращаюсь к указателю, который должен быть инициализирован. Например, когда у меня был классический TList, он позволял мне использовать его просто отлично, за исключением случаев, когда я пытался прочитать один из указателей, и у меня была такая же ошибка. Тот же самый точный код отлично работает в Windows. Например, MyObj:= TMyObj(MyTList[0]);
, где я вижу правильный указатель, есть, но все равно производит это исключение. К сожалению, поскольку я пытался воспроизвести этот конкретный сценарий, я не могу.
UPDATE
я просто наконец-то удалось пошагово 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'.См. Мое обновление выше. Я ожидал, что кто-то еще должен был столкнуться с этим раньше и знает, что происходит, но я думаю, что я единственный человек в мире, с которым это происходит? –