Печать сообщения об исключении в Ada Last_Chance_Handler
Я нахожусь в процессе изучения Ada с использованием компилятора GNAT с использованием IDE AdaCore GPS (GPL), нацеленного на аппаратное обеспечение ARM "без платы" (STM32F4 с использованием среды выполнения Ravenscar SFP).
Для моей встроенной работы на основе ARM я пришел из C/C++ фона.
Во всяком случае, я реализовал "обработчик последнего шанса", который определяется следующим образом:
procedure Last_Chance_Handler (Msg : System.Address; Line : Integer);
pragma Export (C, Last_Chance_Handler, "__gnat_last_chance_handler");
Вот фактическая процедура (фрагмент из .adb
файл),
procedure Last_Chance_Handler (Msg : System.Address; Line : Integer) is
begin
LEDs_All_On;
-- Put_Line("Detail :" & Address_To_String(Msg));
Put_Line("Line :" & Line'Image);
loop
null;
end loop;
end Last_Chance_Handler;
Msg
аргумент документируется следующим образом,
Параметр Msg - это строка с нулевым символом в конце, представляющая исходное местоположение оператора повышение, сгенерированного компилятором, или строка нулевой длины, если используется прагма Suppress_Exception_Locations.
Я пытался выяснить, как преобразовать null
прекращены Msg
байтов в строку Ада, чтобы я мог отобразить его с помощью Put_Line()
вызов (при отладке я могу получить доступ к этому типу вывода через механизм полухостинга).
Ранее я отображал записи Ada (представляющие регистры устройств и т. Д.) На адреса физической памяти, устанавливая их 'Address
приписать постоянное значение. Тем не менее, это первый раз, когда я пытался получить доступ к памяти через System.Address
значение хранится в переменной.
Кто-нибудь может подсказать, как я мог бы реализовать Address_To_String()
процедура?
Я экспериментировал с байтовыми массивами Ады и неконтролируемыми преобразованиями между ними и System.Address
также с указателями Ады, но до сих пор у меня не было никакого успеха.
Любая помощь или предложения будут с благодарностью!
Большое спасибо,
...Максимум
3 ответа
Если вы заходите в last_chance_handler, то, возможно, что-то сломано, и вам не следует слишком полагаться на свою среду. Ada.Text_IO - очень тяжелый пакет. Вы должны стараться избегать этого вообще и особенно здесь.
Вы можете попробовать что-то вроде этого:
with GNAT.IO;
with System.Storage_Elements;
procedure Last_Chance_Handler
(Msg : System.Address; Line : Integer)
is
use System.Storage_Elements; -- make "+" visible for System.Address
function Peek (Addr : System.Address) return Character
is
C : Character with Address => Addr;
begin
return C;
end Peek;
A : System.Address := Msg;
begin
GNAT.IO.Put ("line :");
GNAT.IO.Put (line); -- avoid the secondary stack for Line'Image
GNAT.IO.New_Line;
while Peek(A) /= ASCII.NUL loop
GNAT.IO.Put (Peek(A));
A := A + 1;
end loop;
GNAT.IO.New_Line;
end;
На всякий случай, если из ответа Джейкоба не было ясно, вы можете
with Interfaces.C.Strings;
procedure Last_Chance_Handler
(Msg : Interfaces.C.Strings.chars_ptr; Line : Integer);
принимая во внимание документированное описание Msg
,
Вероятно, операция, которую вы ищете Interfaces.C.Strings.Value
, Он принимает аргумент типа Interfaces.C.Strings.chars_ptr
(эквивалентно char *
в в) и возвращает String
,