OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 27 Сентябрь, 2021 17:14

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 2 ] 
Автор Сообщение
СообщениеДобавлено: Суббота, 08 Февраль, 2020 23:37 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 501
Коллеги, предлагаю улучшить ядро. Опять ). Предлагаю дополнить его средством консольной "раскрутки стека" при авосте. Исключительно необходимая вещь при системном программировании, поскольку красивые ББ-шные стеки далеко не всегда могут быть показаны при системных ошибках.

Вот пример консольного дампа, заимствован у Ивана Андреевича Денисова:
ivan@debian:~/bbcp/BlackBox$ ./blackbox
TRAP 21 (precondition violated)

0: Ports.Port.Init [@=1841] <PC=0000002C FP=FFA0160C>
1: HostWindows.Directory.Open [@=34116] <PC=000032A1 FP=FFA01634>
2: StdDialog.Open [@=8136] <PC=00000EFD FP=FFA01990>
3: StdLog.Open [@=3796] <PC=00000541 FP=FFA01BD0>
4: Kernel.Call [@=37184] <PC=00002397 FP=FFA01BFC>

Как видите, за образец принят обычный ББ-шный дамп (трамп = трап-дамп:)

Чтобы сделать это счастье системщикам, я переделал DefaultTrapViewer и то, как он в ядре вызывается. Затем я наткнулся на проблему повторных авостов - тех, которые возникают во время обработки ранее возникшего авоста. И, чтобы ББ не падал молча, пришлось еще больше правок внести в механизм отработки авостов.

Поскольку эту работу я проделывал в тесном контакте с Иваном Андреичем, она внесена в ядро 1,8 и там может быть прочитана, попробована и критикована.

Поскольку обход стека используется не только при авосте, я выделил его в отдельный механизм в ядре. Он не экспортирован )). Однако, кмк, он хорош, и относится к разряду средств метапрограммирования или рефлексии - похож на GetRefProc и GetRefVar. Поэтому называется GetRefFrame.

Поскольку интерфейс ядра нужно беречь, и "пальцами и яйцами в солонку не тыкать", интерфейс GetRefFrame не экспортирован. Однако для своих нужд в другом модуле я дублирую этот код; это вполне возможно, и не опирается ни на какие другие секретные внутренности ядра. Мне было бы удобно, если бы ядро этот интерфейс опубликовало. Сначала пробовали разместить эти средства в Services, однако, поскольку они используются именно в самом ядре, это оказалось невозможным.

Приглашаю заинтересованных лиц вникнуть в предложение и высказать свою конструктивную критику и предложения. Вникнуть можно, скачав версию 1.8. (На днях туда из "горящего хобота" добавятся поправки для повторных авостов).


Последний раз редактировалось adimetrius Суббота, 08 Февраль, 2020 23:42, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 08 Февраль, 2020 23:40 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 501
Если бы интерфейс GetRefFrames экспортировался, то его документация была бы примерно такой:

FrameDesc* = RECORD (** Activation frame descriptor. *)
m*: Ident; (** m and p identify the procedure that the frame belongs to *)
p*: Ident;
depth*: INTEGER; (** depth of this frame: it's distance, in frames, from top of stack, or from the activation frame that was used to initialize FrameDesc with GetThisRefFrame *)
pos*: INTEGER; (** position in source text of the call of m.p that created this frame, if available; -1 => pc outside of BB; -2: module unloaded *)
ref-: INTEGER; (** reference number to be used with GetRefVar to explore m.p's frame vars *)
pc-: ADDRESS; (** address within the instruction that called m.p (instructions are multibyte) *)
fp-: ADDRESS; (** m.p's frame pointer, i.e. address of the frame *)
eos-: BOOLEAN (** end of stack *)
END;

PROCEDURE GetThisRefFrame* (VAR fr: FrameDesc; pc, fp: ADDRESS);
(** Initializes fr with descriptor of activation frame anchored with fp and belonging to procedure that pc belongs to (or points into).
Инициализирует fr и помещает в нее дескриптор кадра с базовым адресом fp и принадлежащей процедуре, которой принадлежит команда по адресу pc.
Например, если текущее значение регистра EIP присвоить pc, а регистра EBP присвоить fp, то fr будет содержать дескриптор текущей активации.
GetThisRefFrame не производит никаких проверок и не гарантирует безопасности: если ей передать произвольные или ошибочные значения, fr будет гарантированно содержать мусорные данные. Используйте на свой страх и риск.
GetThisRefFrame может быть полезна для узкого круга системных низкоуровневых задач, когда точно известно сочетание pc/fp в текущей цепочке вызовов; пример использования - в обработчике авостов.*)

PROCEDURE GetRefFrame* (VAR fr: FrameDesc); (* based on Kernel.DefaultTrapView *)
(** Allows to 'scan' thru the current activation chain frames (call stack). Assuming the current call chain is P0 -> P1 -> Pn -> GetRefFrame, and 'Frame/P' stands for 'activation frame of procedure P', the following postcondition describes GetRefFrame:

Post
fr is not initialized
fr' = Frame/Pn (* returns the frame description of caller of GetRefFrame *)
fr = Frame/Pn
fr' = Frame/Pn-1
(* goes back one step in the activation chain and returns the description of that frame *)

Позволяет получить дескрипторы процедурных кадров в текущей цепочке вызовов (стек вызовов). Пусть P0 -> P1 -> ... Pn -> GetRefFrame - текущая цепочка вызовов, а 'Frame/P' обозначает дескриптор активации процедуры P. Тогда следующее постусловие описывает GetRefFrame:
Post
fr не инициализирована
fr' = Frame/Pn
(* fr инициализирована и содержит дескриптор кадра процедуры, вызвавшей GetRefFrame *)
fr = Frame/Pn
fr' = Frame/Pn-1
(* возвращается на шаг назад по цепочке вызовов *)

Т.о. для инициализации fr достаточно вызвать GetRefFrame(fr), и fr будет содержать "собственный" дескриптор кадра процедуры, вызвавшей GetRefFrame. Полный обход текущей цепочки активации обеспечивается так:
GetRefFrame(fr);
REPEAT
...
GetRefFrame(fr)
UNTIL fr.eos

GetRefFrame безопасна, если fr инициализирована ею же. Другой способ - инициализировать fr с помощью GetThisRefFrame. В этом случае GetRefFrame небезопасна (т.е. может привести к бесконечным циклам и авостам).*)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

Часовой пояс: UTC + 3 часа


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

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2021, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB