diff options
author | Olivier Hainque <hainque@adacore.com> | 2018-05-21 14:51:09 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2018-05-21 14:51:09 +0000 |
commit | 18c7a4eb877d3c3df5975a3841f76cb05897d1e9 (patch) | |
tree | 0751981fbf86e8b4224a605d0371d452a9e89d44 /gcc/ada/libgnat | |
parent | bbb99006570016986e821b7ddad581b0f2042c44 (diff) | |
download | gcc-18c7a4eb877d3c3df5975a3841f76cb05897d1e9.zip gcc-18c7a4eb877d3c3df5975a3841f76cb05897d1e9.tar.gz gcc-18c7a4eb877d3c3df5975a3841f76cb05897d1e9.tar.bz2 |
[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
Diffstat (limited to 'gcc/ada/libgnat')
-rw-r--r-- | gcc/ada/libgnat/s-trasym__dwarf.adb | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/gcc/ada/libgnat/s-trasym__dwarf.adb b/gcc/ada/libgnat/s-trasym__dwarf.adb index fb35b60..732a5e2 100644 --- a/gcc/ada/libgnat/s-trasym__dwarf.adb +++ b/gcc/ada/libgnat/s-trasym__dwarf.adb @@ -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; |