[Ada] Robustify traceback caching for executable in current dir
Any program calling Gnat.Traceback.Symbolic.Enable_Cache for dwarf based symbolization fails with a segmentation violation when spawned with an inaccurate argv[0] such that it couldn't be found on PATH. argv[0] is most often found on PATH. One plausible case where it isn't is when argv[0] is a mere file name and . isn't on PATH, which might happen out of imprecise exec calls. This change robustifies the Traceback.Symbolic implementation to work in this case as well, by just trying to work with argv[0] untouched as the executable file to fetch dwarf info from. 2018-05-21 Olivier Hainque <hainque@adacore.com> gcc/ada/ * libgnat/s-trasym__dwarf.adb (Executable_Name): Return argv[0] instead of empty string when argv[0] couldn't be found on PATH. (Enable_Cache): Raise Program_Error instead of attempting a null pointer dereference when the Exec_Module initialization failed. From-SVN: r260456
This commit is contained in:
parent
bbb9900657
commit
18c7a4eb87
@ -1,3 +1,10 @@
|
||||
2018-04-04 Olivier Hainque <hainque@adacore.com>
|
||||
|
||||
* libgnat/s-trasym__dwarf.adb (Executable_Name): Return argv[0] instead
|
||||
of empty string when argv[0] couldn't be found on PATH.
|
||||
(Enable_Cache): Raise Program_Error instead of attempting a null
|
||||
pointer dereference when the Exec_Module initialization failed.
|
||||
|
||||
2018-04-04 Piotr Trojanek <trojanek@adacore.com>
|
||||
|
||||
* libgnarl/a-reatim.ads (Clock_Time): Remove External aspect.
|
||||
|
@ -151,8 +151,8 @@ package body System.Traceback.Symbolic is
|
||||
|
||||
function Executable_Name return String;
|
||||
-- Returns the executable name as reported by argv[0]. If gnat_argv not
|
||||
-- initialized or if argv[0] executable not found in path, function returns
|
||||
-- an empty string.
|
||||
-- initialized, return an empty string. If the argv[0] executable is not
|
||||
-- found in the PATH, return it unresolved.
|
||||
|
||||
function Get_Executable_Load_Address return System.Address;
|
||||
pragma Import
|
||||
@ -289,6 +289,12 @@ package body System.Traceback.Symbolic is
|
||||
|
||||
-- Add all modules
|
||||
Init_Exec_Module;
|
||||
|
||||
if Exec_Module_State = Failed then
|
||||
raise Program_Error with
|
||||
"cannot enable cache, executable state initialization failed.";
|
||||
end if;
|
||||
|
||||
Cache_Chain := Exec_Module'Access;
|
||||
|
||||
if Include_Modules then
|
||||
@ -347,17 +353,33 @@ package body System.Traceback.Symbolic is
|
||||
return "";
|
||||
end if;
|
||||
|
||||
-- See if we can resolve argv[0] to a full path (to a file that we will
|
||||
-- be able to open). If the resolution fails, we were probably spawned
|
||||
-- by an imprecise exec call, typically passing a mere file name as
|
||||
-- argv[0] for a program in the current directory with '.' not on PATH.
|
||||
-- Best we can do is fallback to argv[0] unchanged in this case. If we
|
||||
-- fail opening that downstream, we'll just bail out.
|
||||
|
||||
declare
|
||||
Addr : constant System.Address :=
|
||||
locate_exec_on_path (Conv.To_Pointer (Gnat_Argv) (0));
|
||||
Result : constant String := Value (Addr);
|
||||
Argv0 : constant System.Address
|
||||
:= Conv.To_Pointer (Gnat_Argv) (0);
|
||||
|
||||
Resolved_Argv0 : constant System.Address
|
||||
:= locate_exec_on_path (Argv0);
|
||||
|
||||
Exe_Argv : constant System.Address
|
||||
:= (if Resolved_Argv0 /= System.Null_Address
|
||||
then Resolved_Argv0
|
||||
else Argv0);
|
||||
|
||||
Result : constant String := Value (Exe_Argv);
|
||||
|
||||
begin
|
||||
-- The buffer returned by locate_exec_on_path was allocated using
|
||||
-- malloc, so we should use free to release the memory.
|
||||
-- malloc and we should release this memory.
|
||||
|
||||
if Addr /= Null_Address then
|
||||
System.CRTL.free (Addr);
|
||||
if Resolved_Argv0 /= Null_Address then
|
||||
System.CRTL.free (Resolved_Argv0);
|
||||
end if;
|
||||
|
||||
return Result;
|
||||
|
Loading…
Reference in New Issue
Block a user