在 Ada Last_Chance_Handler 中打印异常消息
Printing the exception message in an Ada Last_Chance_Handler
我正在使用 GNAT 编译器学习 Ada,使用 AdaCore GPS (GPL) IDE,针对 ARM "bare board" 硬件(STM32F4 使用 Ravenscar SFP 运行时)。
对于基于 ARM 的嵌入式工作,我有 C/C++ 背景。
无论如何,我实现了一个"last chance handler",定义如下,
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
参数记录如下,
The Msg parameter is a C null-terminated string representing the
source location of the raise statement, as generated by the compiler,
or a zero-length string if pragma Suppress_Exception_Locations is
used.
我一直在试图弄清楚如何将 null
终止的 Msg
字节转换为 Ada 字符串,以便我可以使用 Put_Line()
调用显示它(调试时我可以通过 semihosting 机制访问这种类型的输出。
我之前通过将 Ada 记录(代表设备寄存器等)的 'Address
属性设置为常量值来将它们映射到物理内存地址。但是,这是我第一次尝试通过变量中保存的 System.Address
值访问内存。
谁能建议我如何实施 Address_To_String()
程序?
我试验过 Ada 字节数组和它们与 System.Address
之间未经检查的转换,也试验过 Ada 指针,但到目前为止我还没有取得任何成功。
如有任何帮助或建议,我们将不胜感激!
非常感谢,
...最大
您要查找的操作可能是Interfaces.C.Strings.Value
。它采用 Interfaces.C.Strings.chars_ptr
类型的参数(相当于 C 中的 char *
)和 returns a String
.
以防万一 不清楚,您完全可以自由声明
with Interfaces.C.Strings;
procedure Last_Chance_Handler
(Msg : Interfaces.C.Strings.chars_ptr; Line : Integer);
牢记 Msg
的文档描述。
如果你遇到 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;
我正在使用 GNAT 编译器学习 Ada,使用 AdaCore GPS (GPL) IDE,针对 ARM "bare board" 硬件(STM32F4 使用 Ravenscar SFP 运行时)。
对于基于 ARM 的嵌入式工作,我有 C/C++ 背景。
无论如何,我实现了一个"last chance handler",定义如下,
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
参数记录如下,
The Msg parameter is a C null-terminated string representing the source location of the raise statement, as generated by the compiler, or a zero-length string if pragma Suppress_Exception_Locations is used.
我一直在试图弄清楚如何将 null
终止的 Msg
字节转换为 Ada 字符串,以便我可以使用 Put_Line()
调用显示它(调试时我可以通过 semihosting 机制访问这种类型的输出。
我之前通过将 Ada 记录(代表设备寄存器等)的 'Address
属性设置为常量值来将它们映射到物理内存地址。但是,这是我第一次尝试通过变量中保存的 System.Address
值访问内存。
谁能建议我如何实施 Address_To_String()
程序?
我试验过 Ada 字节数组和它们与 System.Address
之间未经检查的转换,也试验过 Ada 指针,但到目前为止我还没有取得任何成功。
如有任何帮助或建议,我们将不胜感激!
非常感谢,
...最大
您要查找的操作可能是Interfaces.C.Strings.Value
。它采用 Interfaces.C.Strings.chars_ptr
类型的参数(相当于 C 中的 char *
)和 returns a String
.
以防万一
with Interfaces.C.Strings;
procedure Last_Chance_Handler
(Msg : Interfaces.C.Strings.chars_ptr; Line : Integer);
牢记 Msg
的文档描述。
如果你遇到 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;