Обработка исключений

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Обработка исключений

Сообщение Sheff » 25.09.2011 19:26:35

Здрасте)
Хочу разобраться как FPC обрабатывает исключения. Методом тыка и Ctrl+Alt+D нашел, что для try используется fpc_PushExceptAddr, и в конце концов (когда надо убрать фрейм) - fpc_PopAddrStack. но не могу понять где именно передается адрес обработчика. В Delphi было явно написано
Код: Выделить всё
push OFFSET _myHandler
push fs:[0]
mov fs:[0], esp

и возможно ли (знаю что возможно) не знаю как )) чтобы при обработке какого либо исключения попасть не в текущий блок обработки, а в блок более высокого уровня... т.е. в результате нижеследующего нужно получить "ОК!"
Код: Выделить всё
try
  try
    DestroyCurrentFrame;
    raise Exception.Create
  except
    WriteLn('опача!');
  end;
except
  WriteLn('ок!');
end;

заранее спс )

Добавлено спустя 54 минуты 3 секунды:
сделал вот так:
Код: Выделить всё
procedure fpc_PopAddrStack; [external name 'FPC_POPADDRSTACK'];

получилось. но можно ли так делать вообще? где хранится этот блок TExceptAddr? в стеке? судя по исходникам никакого GetMem И FreeMem там нет. или это может делает компилятор?
Sheff
незнакомец
 
Сообщения: 3
Зарегистрирован: 25.09.2011 19:10:16

Re: Обработка исключений

Сообщение Sergei I. Gorelkin » 25.09.2011 21:11:02

Адрес обработчика в явном виде отсутствует. Используется setjmp/longjmp, код выглядит примерно так:

Код: Выделить всё
var  // создаются компилятором
  exceptaddr: TExceptAddr;
  jmpbuf: tjmpbuf;

// начало fpc_pushexceptaddr
exceptaddr.buf:=jmpbuf;
exceptaddr.next:=exceptaddrstack;
exceptaddrstack:=@exceptaddr;
// конец fpc_pushexceptaddr

if setjmp(jmpbuf)=0 then
   // код секции try
else
  // cюда попадаем при исключении


При самостоятельном вызове fpc_popaddrstack возможно уничтожить совсем не том фрейм, который планировалось, т.к. компилятор вставляет их по собственному усмотрению (не только там, где в программе написано try).
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Обработка исключений

Сообщение Sheff » 25.09.2011 22:04:22

Спасибо, Сергей. до меня кажется дошло!
SetJmp считывает адрес следующей команды после нее в Jmp_Buf. и при исключении управление передается по этому адресу. А там как раз стоит проверка условия
test %eax, %eax

не радует только немного убогий ассемблерный отладчик в Lazarus.. а как посмотреть состояние стека? ну или хотя бы может есть окошко дампа памяти, я чтото не нашел. или может есть какая-то полезная сторонняя утилита для таких средств?

Добавлено спустя 1 минуту 27 секунд:
При самостоятельном вызове fpc_popaddrstack возможно уничтожить совсем не том фрейм, который планировалось, т.к. компилятор вставляет их по собственному усмотрению (не только там, где в программе написано try).

а может есть мануальчик где-нидудь?
Sheff
незнакомец
 
Сообщения: 3
Зарегистрирован: 25.09.2011 19:10:16

Re: Обработка исключений

Сообщение Sergei I. Gorelkin » 25.09.2011 23:15:54

Sheff писал(а):а может есть мануальчик где-нидудь?

Мануальчика нет, и в этой области возможны несовместимые изменения без предупреждения.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Обработка исключений

Сообщение Sheff » 26.09.2011 11:27:24

а в теории могла бы быть возможность иметь доступ к переменным (except.inc)?
Код: Выделить всё
ThreadVar
  ExceptAddrStack   : PExceptAddr;
  ExceptObjectStack : PExceptObject;


т.е. я конечно могу добавить пару функций в objpash.inc/except.inc чтото типа:
Код: Выделить всё
function GetExceptAddrStack: PPointer;
begin
  Result := @ExceptAddrStack
end;


но может есть более санкционированные средства? я что-то не нашел...
Sheff
незнакомец
 
Сообщения: 3
Зарегистрирован: 25.09.2011 19:10:16

Re: Обработка исключений

Сообщение Sergei I. Gorelkin » 26.09.2011 16:20:00

Для доступа к ExceptObjectStack имеется ф-ция RaiseList.
ExceptAddrStack публично недоступен. В теории и на практике надо двигаться в направлении интеграции с обработкой исключений в ОС, а у них все по-разному. Например, в win64 такой сущности вообще нет.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru