aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@adacore.com>2018-05-21 14:51:09 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-05-21 14:51:09 +0000
commit18c7a4eb877d3c3df5975a3841f76cb05897d1e9 (patch)
tree0751981fbf86e8b4224a605d0371d452a9e89d44 /gcc/ada
parentbbb99006570016986e821b7ddad581b0f2042c44 (diff)
downloadgcc-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')
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/libgnat/s-trasym__dwarf.adb38
2 files changed, 37 insertions, 8 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index a62bbe1..fa449bf 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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.
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;