Нарушение прав доступа в Delphi - PullRequest
3 голосов
/ 30 ноября 2011

В приложении delphi, когда я перемещаю мышь к компоненту с подсказкой, я вижу эту ошибку: «Нарушение доступа по адресу 00484F3B в модуле« Plibrary.exe ». Чтение адреса 0000026C» Почему это случилось?

Стек вызовов:

:758e9617 KERNELBASE.RaiseException + 0x54 
:458bf456 System.@UStrCmp 
:00407558 @UStrCmp + $2C 
Forms.TApplication.SetHint(???) 
Forms.TApplication.Idle(???) 
Forms.TApplication.HandleMessage 
Forms.TApplication.Run Plibrary.Plibrary 
:75ca1194 kernel32.BaseThreadInitThunk + 0x12 
:7752b3f5 ntdll.RtlInitializeExceptionChain + 0x63 
:7752b3c8 ntdll.RtlInitializeExceptionChain + 0x36" 

А код ошибки в файле System.pas в строке 17732: «MOV ESI, [ESP]»

Редактировать (из комментария):

В файле stay.pas при этой процедуре:

procedure TMainForm.ShowHint(Sender: TObject); 
begin 
  if Length(Application.Hint) > 0 then begin 
    StatusBar.SimplePanel := True; 
    StatusBar.SimpleText := Application.Hint; //this line gives error 
  end else    
    StatusBar.SimplePanel := False; 
end;

Ответы [ 2 ]

6 голосов
/ 30 ноября 2011

Чтение адреса 0000026C

Этот очень низкий адрес указывает на смещение к полю элемента nil ссылки на объект. Запустите под отладчиком и убедитесь, что отладчик настроен на исключение. Когда это произойдет, вы сможете определить, какая ссылка на объект nil.

Вполне возможно, что AV происходит в коде VCL, хотя почти наверняка это произойдет из-за ошибки в вашем коде. Если отладчик не выходит из строя в очень полезном месте, включите отладочные DCU в параметрах проекта, чтобы увидеть исходный код VCL в точке возникновения исключения.

Предоставленная вами трассировка стека предполагает, что ошибка находится в TApplication.SetHint при выполнении сравнения строк. Первая строка TApplication.SetHint гласит:

if FHint <> Value then

Бьюсь об заклад, смещение FHint из TApplication равно $026C, и что ваша переменная Application каким-то образом установлена ​​на nil. Тем не менее, я не понимаю, почему ошибка не была бы поднята ранее на Length(Application.Hint). Отладить это довольно сложно!

Посмотрев на макет TApplication, я думаю, мы можем исключить Application, являющееся nil. Возможно, FHint как-то поврежден, а может быть, даже Value. Я думаю, что для отслеживания этого потребуется доступ к реальному коду и среде отладки.

1 голос
/ 30 ноября 2011

На основании информации, представленной в трассировке стека:

TApplication.Idle:

Control := DoMouseIdle;
if FShowHint and (FMouseControl = nil) then
  CancelHint;
Application.Hint := GetLongHint(GetHint(Control)); // SetHint is called next:

TApplication.SetHint:

if FHint <> Value then // This is the UStrCmp which fails with a Int overflow

String + IntOverflow -> не заканчивающаяся строка. Таким образом, наиболее вероятной причиной является строка без терминатора.

Так откуда взялась строка ...

  • GetHint (Control) ищет элемент управления (который находится в местах, где вы щелкнули курсором) и его родительский элемент для подсказки, которая не является пустой.

  • GetLongHint ищет строку для | и, если найден, использует часть после | иначе он использует полную строку.

  • UStrCmp, это длинные фрагменты кода ассемблера, которые вызывают другие фрагменты кода ассемблера. Некоторые из них могут вызвать ошибку EIntegerOverflow.

Консультировать

Используйте отладчик (с включенным debug dcu), чтобы увидеть, какая строка не имеет терминатора (0 символов в конце). И если вы найдете это, попробуйте решить его или расширить вопрос, если вам нужна дополнительная помощь от нас.

...