* [PATCH v5] Fix crash in AIX when current working directory is NULL
@ 2026-07-23 7:21 Aditya Vidyadhar Kamath
2026-07-24 13:25 ` Tom Tromey
0 siblings, 1 reply; 7+ messages in thread
From: Aditya Vidyadhar Kamath @ 2026-07-23 7:21 UTC (permalink / raw)
To: ulrich.weigand, simon.marchi, tom
Cc: gdb-patches, Aditya.Kamath1, sangamesh.swamy, PRAJWAL.B.MEHENDARKAR
From: Aditya Kamath <Aditya.Kamath1@ibm.com>
This issue is seen in other targets as well.
In AIX if we do not have read permission in a current directory we get,
gdb ~/gdb_tests/simple_test
gdb: warning: error finding working directory: A parameter must be a directory.
GNU gdb (GDB) 18.0.50.20260619-git
Copyright (C) 2026 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64-ibm-aix7.2.0.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
+------------------------------------------------------------------------------+
| Find the GDB manual online at: |
| http://www.gnu.org/software/gdb/documentation/. |
| For help, type "help". |
| Type "apropos word" to search for commands related to "word". |
+------------------------------------------------------------------------------+
Reading symbols from //gdb_tests/simple_test...
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string: construction from null is not valid
Fatal signal: IOT/Abort trap
----- Backtrace -----
0x100943f1b gdb_internal_backtrace_1
//home/binutils-gdb/gdb/bt-utils.c:122
0x100944027 _Z22gdb_internal_backtracev
//home/binutils-gdb/gdb/bt-utils.c:173
0x10060faa7 handle_fatal_signal
//home/binutils-gdb/gdb/event-top.c:1008
0x4fdf ???
---------------------
A fatal error internal to GDB has been detected, further
debugging is not possible. GDB will now terminate.
This is a bug, please report it. For instructions, see:
<https://www.gnu.org/software/gdb/bugs/>.
=============================
The reason for the same above is that in AIX, the variable current_directory in dwarf2/read.c
can be NULL if getcwd () fails during GDB initialisation. When this happens the dwarf2_per_bfd
construction initialisation list captured_cwd to NULL resulting in this segmentation fault shown above.
There are two reasons this happened:
1: The current working directory got deleted in another terminal.
2: Insufficient permission to read the current directory or its parent/predicissor directory.
This patch is a fix to the same.
Afer this fix we get GDB loaded correctly.
gdb ~/gdb_tests/simple_test
gdb: warning: error finding working directory: A parameter must be a directory.
GNU gdb (GDB) 18.0.50.20260619-git
Copyright (C) 2026 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64-ibm-aix7.2.0.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
+------------------------------------------------------------------------------+
| Find the GDB manual online at: |
| http://www.gnu.org/software/gdb/documentation/. |
| For help, type "help". |
| Type "apropos word" to search for commands related to "word". |
+------------------------------------------------------------------------------+
Reading symbols from //gdb_tests/simple_test...
(gdb) q
Also adding a test case for the same.
The reason I could not do it in a simple exp file is AIX is protecting the currrent working
directory when I try to delete. It says The requested resource is busy.
So I had to write a C code the fork () and child will delete the current working directory.
Then from here exec gdb with a binary having dwarf symbols to reproduce the crash.
---
gdb/dwarf2/read.c | 9 ++-
gdb/dwarf2/read.h | 7 +-
gdb/testsuite/gdb.base/getcwd-fail-helper.c | 84 +++++++++++++++++++++
gdb/testsuite/gdb.base/getcwd-fail.c | 20 +++++
gdb/testsuite/gdb.base/getcwd-fail.exp | 70 +++++++++++++++++
5 files changed, 186 insertions(+), 4 deletions(-)
create mode 100644 gdb/testsuite/gdb.base/getcwd-fail-helper.c
create mode 100644 gdb/testsuite/gdb.base/getcwd-fail.c
create mode 100644 gdb/testsuite/gdb.base/getcwd-fail.exp
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 114c608fde3..5b163041e02 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -859,7 +859,9 @@ dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
bool can_copy_)
: obfd (obfd),
can_copy (can_copy_),
- captured_cwd (current_directory),
+ captured_cwd (current_directory != nullptr
+ ? std::optional<std::string> (current_directory)
+ : std::nullopt),
captured_debug_dir (debug_file_directory)
{
if (names == NULL)
@@ -6735,7 +6737,10 @@ try_open_dwop_file (dwarf2_per_bfd *per_bfd, const char *file_name, int is_dwp,
gdb::unique_xmalloc_ptr<char> absolute_name;
desc = openp (search_path, flags, file_name, O_RDONLY | O_BINARY,
- &absolute_name, per_bfd->captured_cwd.c_str ());
+ &absolute_name,
+ (per_bfd->captured_cwd.has_value ()
+ ? per_bfd->captured_cwd->c_str ()
+ : nullptr));
if (desc < 0)
return NULL;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 15dd2abf3a1..a7c1861a64d 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -757,8 +757,11 @@ struct dwarf2_per_bfd
abstract_to_concrete;
/* Current directory, captured at the moment that object this was
- created. */
- std::string captured_cwd;
+ created. If nullopt, the working directory was unavailable
+ which means getcwd failed either due to directory deletion or
+ permission issues. So paths should be treated as absolute. */
+ std::optional<std::string> captured_cwd;
+
/* Captured copy of debug_file_directory. */
std::string captured_debug_dir;
};
diff --git a/gdb/testsuite/gdb.base/getcwd-fail-helper.c b/gdb/testsuite/gdb.base/getcwd-fail-helper.c
new file mode 100644
index 00000000000..1cedc7090e8
--- /dev/null
+++ b/gdb/testsuite/gdb.base/getcwd-fail-helper.c
@@ -0,0 +1,84 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2026 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Helper to reproduce getcwd failure by deleting cwd via child process. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+int
+main (int argc, char *argv[])
+{
+ const char *temp_dir = argv[1];
+ const char *gdb_path = argv[2];
+
+ /* Create and change to temp directory. */
+ if (mkdir (temp_dir, 0755) != 0)
+ {
+ perror ("mkdir failed");
+ return 1;
+ }
+
+ if (chdir (temp_dir) != 0)
+ {
+ perror ("chdir failed");
+ return 1;
+ }
+
+ /* child deletes directory, parent execs GDB. */
+ pid_t pid = fork ();
+ if (pid < 0)
+ {
+ perror ("fork failed");
+ return 1;
+ }
+
+ if (pid == 0)
+ {
+ /* cd to / and delete the temp directory. */
+ if (chdir ("/") != 0)
+ exit (1);
+
+ if (rmdir (temp_dir) != 0)
+ exit (1);
+
+ exit (0);
+ }
+
+ /* wait for child to delete directory. */
+ int status;
+ waitpid (pid, &status, 0);
+
+ if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
+ {
+ fprintf (stderr, "Failed to delete directory\n");
+ return 1;
+ }
+
+ /* Exec GDB. */
+ char **gdb_args = malloc ((argc - 1) * sizeof (char *));
+ gdb_args[0] = (char *) gdb_path;
+ for (int i = 3; i < argc; i++)
+ gdb_args[i - 2] = argv[i];
+ gdb_args[argc - 2] = NULL;
+
+ execv (gdb_path, gdb_args);
+ perror ("execv failed");
+ return 1;
+}
diff --git a/gdb/testsuite/gdb.base/getcwd-fail.c b/gdb/testsuite/gdb.base/getcwd-fail.c
new file mode 100644
index 00000000000..e2d20ce9349
--- /dev/null
+++ b/gdb/testsuite/gdb.base/getcwd-fail.c
@@ -0,0 +1,20 @@
+# Copyright 2026 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+int
+main (void)
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/getcwd-fail.exp b/gdb/testsuite/gdb.base/getcwd-fail.exp
new file mode 100644
index 00000000000..e0283753932
--- /dev/null
+++ b/gdb/testsuite/gdb.base/getcwd-fail.exp
@@ -0,0 +1,70 @@
+# Copyright 2026 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test GDB when current working directory has been deleted.
+# Reproduces crash: getcwd() returns NULL.
+
+standard_testfile .c
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} {
+ return -1
+}
+
+# Compile helper program
+set helper_src "${srcdir}/${subdir}/getcwd-fail-helper.c"
+set helper_bin [standard_output_file "getcwd-fail-helper"]
+
+# Debug needs to be there so we can trigger getcwd the dwarf2/read.c code.
+if {[gdb_compile $helper_src $helper_bin executable {debug}] != ""} {
+ untested "failed to compile helper"
+ return -1
+}
+
+set temp_dir [standard_output_file "temp_getcwd_test"]
+set gdb_path [transform $GDB]
+
+# The test code creates temp dir, child deletes it, parent execs GDB
+set test "gdb in deleted cwd"
+set spawn_id [remote_spawn host "$helper_bin $temp_dir $gdb_path -nw -nx -q $binfile"]
+
+set crashed 0
+
+remote_expect host 30 {
+ -re "terminate called.*logic_error.*basic_string.*construction from null" {
+ set crashed 1
+ exp_continue
+ }
+ -re "Fatal signal.*IOT/Abort" {
+ set crashed 1
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ if {$crashed} {
+ fail "$test - crashed"
+ } else {
+ pass "$test"
+ }
+ }
+ eof {
+ if {$crashed} {
+ fail "$test - crashed with std::logic_error"
+ } else {
+ pass "$test"
+ }
+ }
+ timeout {
+ fail "$test - timeout"
+ }
+}
--
2.51.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5] Fix crash in AIX when current working directory is NULL
2026-07-23 7:21 [PATCH v5] Fix crash in AIX when current working directory is NULL Aditya Vidyadhar Kamath
@ 2026-07-24 13:25 ` Tom Tromey
2026-07-27 6:48 ` Aditya Kamath
0 siblings, 1 reply; 7+ messages in thread
From: Tom Tromey @ 2026-07-24 13:25 UTC (permalink / raw)
To: Aditya Vidyadhar Kamath
Cc: ulrich.weigand, simon.marchi, tom, gdb-patches, Aditya.Kamath1,
sangamesh.swamy, PRAJWAL.B.MEHENDARKAR
>>>>> Aditya Vidyadhar Kamath <akamath996@gmail.com> writes:
Sorry about this, but I didn't closely read the test in the earlier
reviews.
> + /* Exec GDB. */
> + char **gdb_args = malloc ((argc - 1) * sizeof (char *));
> + gdb_args[0] = (char *) gdb_path;
> + for (int i = 3; i < argc; i++)
> + gdb_args[i - 2] = argv[i];
> + gdb_args[argc - 2] = NULL;
execing gdb seems problematic, for instance with a cross build gdb won't
be the same host architecture as this test program.
Is it not possible to start gdb, change its directory, and then remove
the working directory from the .exp file?
Tom
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH v5] Fix crash in AIX when current working directory is NULL
2026-07-24 13:25 ` Tom Tromey
@ 2026-07-27 6:48 ` Aditya Kamath
2026-07-27 12:02 ` Ulrich Weigand
0 siblings, 1 reply; 7+ messages in thread
From: Aditya Kamath @ 2026-07-27 6:48 UTC (permalink / raw)
To: Tom Tromey, Aditya Vidyadhar Kamath
Cc: Ulrich Weigand, simon.marchi, tom, gdb-patches,
SANGAMESH MALLAYYA, PRAJWAL B MEHENDARKAR
[-- Attachment #1: Type: text/plain, Size: 1248 bytes --]
Hi Tom, Ulrich and community members,
>execing gdb seems problematic, for instance with a cross build gdb won't
>be the same host architecture as this test program.
>Is it not possible to start gdb, change its directory, and then remove
>the working directory from the .exp file?
The reason I could not do it in a simple .exp file is AIX is protecting the current working
directory when I try to delete. It says the requested resource is busy.
So, I had to write a C code the fork () and child will delete the current working directory to mimic another terminal deleting the current working directory.
Then from the parent exec gdb with a binary having dwarf symbols to reproduce the crash.
For example:
bash-5.3# mkdir gdb_test
bash-5.3# cd gdb_test
bash-5.3# pwd
/tmp/gdb_test
bash-5.3#
bash-5.3# rm -rf ../*
rm: cannot remove '../gdb_test': The requested resource is busy.
bash-5.3#
This is the issue. We need to find a way to mimic someone deleting the cwd from another terminal in one test case. In the .exp file from what I know we cannot find a way to delete the current working directory and still start GDB from the deleted directory. Let me know if I am wrong here.
Thanks and regards,
Aditya.
[-- Attachment #2: Type: text/html, Size: 4824 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5] Fix crash in AIX when current working directory is NULL
2026-07-27 6:48 ` Aditya Kamath
@ 2026-07-27 12:02 ` Ulrich Weigand
2026-07-28 7:00 ` Aditya Kamath
0 siblings, 1 reply; 7+ messages in thread
From: Ulrich Weigand @ 2026-07-27 12:02 UTC (permalink / raw)
To: akamath996, tom, Aditya Kamath
Cc: gdb-patches, SANGAMESH MALLAYYA, PRAJWAL B MEHENDARKAR, simon.marchi
Aditya Kamath <Aditya.Kamath1@ibm.com> wrote:
>This is the issue. We need to find a way to mimic someone deleting the
>cwd from another terminal in one test case. In the .exp file from what
>I know we cannot find a way to delete the current working directory
>and still start GDB from the deleted directory. Let me know if I am
>wrong here.
It seems to me this is special enough that there is no particular
point in attempting to run this test in remote (or any non-default)
scenarios. However, we would still need to prevent the test from
being *attempted* in those scenarios. That should be possible by
using appropriate "require" lines, in particular
require isnative
require ![is_remote target]
require {istarget *-*-aix*}
The last line may be too strict if we also want to test on Linux
or other Unix hosts; but we need to ensure the host is at least
Unixy enough to support fork. Maybe something like
require allow_fork_tests
would be OK (given that we also require isnative).
Bye,
Ulrich
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5] Fix crash in AIX when current working directory is NULL
2026-07-27 12:02 ` Ulrich Weigand
@ 2026-07-28 7:00 ` Aditya Kamath
2026-07-28 10:09 ` Ulrich Weigand
0 siblings, 1 reply; 7+ messages in thread
From: Aditya Kamath @ 2026-07-28 7:00 UTC (permalink / raw)
To: Ulrich Weigand, akamath996, tom
Cc: gdb-patches, SANGAMESH MALLAYYA, PRAJWAL B MEHENDARKAR, simon.marchi
[-- Attachment #1: Type: text/plain, Size: 539 bytes --]
Hi Ulrich,
>require isnative
>require ![is_remote target]
>require {istarget *-*-aix*}
>The last line may be too strict if we also want to test on Linux
>or other Unix hosts; but we need to ensure the host is at least
>Unixy enough to support fork. Maybe something like
>require allow_fork_tests
Thanks for this idea. Yes, I have implemented the same in v6 of this patch.
But I am still thinking about Tom’s concern about GDB cross platform for this test.
V6 also does not overcome the same.
Regards,
Aditya.
[-- Attachment #2: Type: text/html, Size: 3744 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5] Fix crash in AIX when current working directory is NULL
2026-07-28 7:00 ` Aditya Kamath
@ 2026-07-28 10:09 ` Ulrich Weigand
2026-07-28 12:35 ` Aditya Kamath
0 siblings, 1 reply; 7+ messages in thread
From: Ulrich Weigand @ 2026-07-28 10:09 UTC (permalink / raw)
To: akamath996, tom, Aditya Kamath
Cc: gdb-patches, SANGAMESH MALLAYYA, PRAJWAL B MEHENDARKAR, simon.marchi
Aditya Kamath <Aditya.Kamath1@ibm.com> wrote:
>>require isnative
>>require ![is_remote target]
>>require {istarget *-*-aix*}
>
>>The last line may be too strict if we also want to test on Linux
>>or other Unix hosts; but we need to ensure the host is at least
>>Unixy enough to support fork. Maybe something like
>
>require allow_fork_tests
>
>
>Thanks for this idea. Yes, I have implemented the same in v6 of this
>patch.
Just to be clear: if you already require linux or aix targets (as v6
does), then there is no need to *also* require allow_fork_tests -
this will always be true on those platforms.
>But I am still thinking about Tom’s concern about GDB cross platform
>for this test.
The point of those "require" statement is exactly that the test will
simply not be run in any GDB cross-platform environment, only with
native tests. That should address this concern?
Bye,
Ulrich
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5] Fix crash in AIX when current working directory is NULL
2026-07-28 10:09 ` Ulrich Weigand
@ 2026-07-28 12:35 ` Aditya Kamath
0 siblings, 0 replies; 7+ messages in thread
From: Aditya Kamath @ 2026-07-28 12:35 UTC (permalink / raw)
To: Ulrich Weigand, akamath996, tom
Cc: gdb-patches, SANGAMESH MALLAYYA, PRAJWAL B MEHENDARKAR, simon.marchi
[-- Attachment #1: Type: text/plain, Size: 573 bytes --]
Hi Ulrich, Tom and community members,
>The point of those "require" statement is exactly that the test will
>simply not be run in any GDB cross-platform environment, only with
>native tests. That should address this concern?
Now I found it.
https://github.com/gitGNU/gnu_dejagnu/blob/f3817d617ee6c8c1edd04a7fc68daee6dbc4d9c2/lib/framework.exp#L244C1-L252C2
The definition is in Dejagnu which is why I was not able to understand and get this. So asked that I am not clear how.
Yes, it is clear now :)
Sending v7 with corrections.
Thanks,
Aditya.
[-- Attachment #2: Type: text/html, Size: 2722 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-28 12:36 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-23 7:21 [PATCH v5] Fix crash in AIX when current working directory is NULL Aditya Vidyadhar Kamath
2026-07-24 13:25 ` Tom Tromey
2026-07-27 6:48 ` Aditya Kamath
2026-07-27 12:02 ` Ulrich Weigand
2026-07-28 7:00 ` Aditya Kamath
2026-07-28 10:09 ` Ulrich Weigand
2026-07-28 12:35 ` Aditya Kamath
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox