aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/Makefile.in1
-rw-r--r--gdb/NEWS11
-rw-r--r--gdb/doc/gdb.texinfo28
-rw-r--r--gdb/doc/python.texi2
-rw-r--r--gdb/infrun.c27
-rw-r--r--gdb/infrun.h3
-rw-r--r--gdb/python/py-color.c5
-rw-r--r--gdb/python/py-disasm.c11
-rw-r--r--gdb/python/py-registers.c3
-rw-r--r--gdb/remote.c2
-rw-r--r--gdb/riscv-canonicalize-syscall-gen.c20
-rw-r--r--gdb/riscv-linux-tdep.h6
-rw-r--r--gdb/solib-svr4.c55
-rw-r--r--gdb/solib.c269
-rw-r--r--gdb/solist.h4
-rwxr-xr-xgdb/syscalls/riscv-canonicalize-syscall-gen.py4
-rw-r--r--gdb/testsuite/gdb.base/bg-execution-repeat.exp11
-rw-r--r--gdb/testsuite/gdb.base/default.exp2
-rw-r--r--gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c6
-rw-r--r--gdb/testsuite/gdb.base/dlmopen-ns-ids.exp133
-rw-r--r--gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw4.exp71
-rw-r--r--gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw5.exp75
-rw-r--r--gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld234-dw5.exp70
-rw-r--r--gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw4.exp70
-rw-r--r--gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw5.exp81
-rw-r--r--gdb/testsuite/gdb.dwarf2/macro-source-path.exp.tcl (renamed from gdb/testsuite/gdb.dwarf2/macro-source-path.exp)250
-rw-r--r--gdb/testsuite/gdb.python/py-color.exp33
-rw-r--r--gdb/testsuite/gdb.python/py-disasm.exp.tcl5
-rw-r--r--gdb/testsuite/gdb.python/py-disasm.py18
-rw-r--r--gdb/testsuite/gdb.python/py-frame.exp15
30 files changed, 961 insertions, 330 deletions
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 9275f8d..68b5e56 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -769,6 +769,7 @@ ALL_64_TARGET_OBS = \
mips-sde-tdep.o \
mips-tdep.o \
mips64-obsd-tdep.o \
+ riscv-canonicalize-syscall-gen.o \
riscv-fbsd-tdep.o \
riscv-linux-tdep.o \
riscv-none-tdep.o \
diff --git a/gdb/NEWS b/gdb/NEWS
index 4baed29..164e872 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -40,6 +40,12 @@
namespace into which the library was loaded, if more than one namespace
is active.
+* New built-in convenience variables $_active_linker_namespaces and
+ $_current_linker_namespace. These show the number of active linkage
+ namespaces, and the namespace to which the current location belongs to.
+ In systems that don't support linkage namespaces, these always return 1
+ and [[0]] respectively.
+
* Add record full support for rv64gc architectures
* New commands
@@ -56,6 +62,11 @@ show riscv numeric-register-names
(e.g 'x1') or their abi names (e.g. 'ra').
Defaults to 'off', matching the old behaviour (abi names).
+info linker-namespaces
+info linker-namespaces [[N]]
+ Print information about the given linker namespace (identified as N),
+ or about all the namespaces if no argument is given.
+
* Changed commands
info sharedlibrary
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d54ad65..48b193b 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -13046,6 +13046,18 @@ variable which may be @samp{truecolor} or @samp{24bit}. Other color spaces are
determined by the "Co" termcap which in turn depends on the @env{TERM}
environment variable.
+@vindex $_active_linker_namespaces@r{, convenience variable}
+@item $_active_linker_namespaces
+Number of active linkage namespaces in the inferior. In systems with no
+support for linkage namespaces, this variable will always be set to @samp{1}.
+
+@vindex $_current_linker_namespace@r{, convenience variable}
+@item $_current_linker_namespace
+The namespace which contains the current location in the inferior. This
+returns GDB's internal identifier for namespaces, which is @samp{[[@var{n}]]}
+where @var{n} is a zero-based namespace number. In systems with no support
+for linkage namespaces, this variable will always be set to @samp{[[0]]}.
+
@end table
@node Convenience Funs
@@ -22212,6 +22224,22 @@ less useful than setting a catchpoint, because it does not allow for
conditions or commands as a catchpoint does.
@table @code
+@kindex info linker-namespaces
+@item info linker-namespaces
+@item info linker-namespaces @code{[[@var{n}]]}
+
+With no argument, print the number of linker namespaces which are
+currently active --- that is, namespaces that have libraries loaded
+into them. Then, it prints the number of libraries loaded into each
+namespace, and all the libraries loaded into them, in the same way
+as @code{info sharedlibrary}.
+
+If an argument @code{[[@var{n}]]} is provided, only prints the
+library count and the libraried for the provided namespace @var{n}.
+The surrounding square brackets are optional.
+@end table
+
+@table @code
@item set stop-on-solib-events
@kindex set stop-on-solib-events
This command controls whether @value{GDBN} should give you control
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 80f4c14..45f5f70 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -7136,6 +7136,8 @@ Direct 24-bit RGB colors.
@end table
+It is not possible to sub-class the @code{Color} class.
+
@node Architectures In Python
@subsubsection Python representation of architectures
@cindex Python architectures
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 3d5ede8..0b87287 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -3972,7 +3972,8 @@ delete_just_stopped_threads_single_step_breakpoints (void)
void
print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
- const struct target_waitstatus &ws)
+ const struct target_waitstatus &ws,
+ process_stratum_target *proc_target)
{
infrun_debug_printf ("target_wait (%s [%s], status) =",
waiton_ptid.to_string ().c_str (),
@@ -3981,6 +3982,20 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
result_ptid.to_string ().c_str (),
target_pid_to_str (result_ptid).c_str ());
infrun_debug_printf (" %s", ws.to_string ().c_str ());
+
+ if (proc_target != nullptr)
+ infrun_debug_printf (" from target %d (%s)",
+ proc_target->connection_number,
+ proc_target->shortname ());
+}
+
+/* Wrapper for print_target_wait_results above for convenience. */
+
+static void
+print_target_wait_results (ptid_t waiton_ptid,
+ const execution_control_state &ecs)
+{
+ print_target_wait_results (waiton_ptid, ecs.ptid, ecs.ws, ecs.target);
}
/* Select a thread at random, out of those which are resumed and have
@@ -4332,7 +4347,8 @@ prepare_for_detach (void)
event.ptid = do_target_wait_1 (inf, pid_ptid, &event.ws, 0);
if (debug_infrun)
- print_target_wait_results (pid_ptid, event.ptid, event.ws);
+ print_target_wait_results (pid_ptid, event.ptid, event.ws,
+ event.target);
handle_one (event);
}
@@ -4388,7 +4404,7 @@ wait_for_inferior (inferior *inf)
ecs.target = inf->process_target ();
if (debug_infrun)
- print_target_wait_results (minus_one_ptid, ecs.ptid, ecs.ws);
+ print_target_wait_results (minus_one_ptid, ecs);
/* Now figure out what to do with the result of the result. */
handle_inferior_event (&ecs);
@@ -4669,7 +4685,7 @@ fetch_inferior_event ()
switch_to_target_no_thread (ecs.target);
if (debug_infrun)
- print_target_wait_results (minus_one_ptid, ecs.ptid, ecs.ws);
+ print_target_wait_results (minus_one_ptid, ecs);
/* If an error happens while handling the event, propagate GDB's
knowledge of the executing state to the frontend/user running
@@ -5232,7 +5248,8 @@ poll_one_curr_target (struct target_waitstatus *ws)
event_ptid = target_wait (minus_one_ptid, ws, TARGET_WNOHANG);
if (debug_infrun)
- print_target_wait_results (minus_one_ptid, event_ptid, *ws);
+ print_target_wait_results (minus_one_ptid, event_ptid, *ws,
+ current_inferior ()->process_target ());
return event_ptid;
}
diff --git a/gdb/infrun.h b/gdb/infrun.h
index 2067fd5..b9b64ac 100644
--- a/gdb/infrun.h
+++ b/gdb/infrun.h
@@ -256,7 +256,8 @@ extern void print_stop_event (struct ui_out *uiout, bool displays = true);
/* Pretty print the results of target_wait, for debugging purposes. */
extern void print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
- const struct target_waitstatus &ws);
+ const struct target_waitstatus &ws,
+ process_stratum_target *proc_target);
extern int signal_stop_state (int);
diff --git a/gdb/python/py-color.c b/gdb/python/py-color.c
index 9e29ee2..c48d14e 100644
--- a/gdb/python/py-color.c
+++ b/gdb/python/py-color.c
@@ -64,7 +64,8 @@ create_color_object (const ui_file_style::color &color)
bool
gdbpy_is_color (PyObject *obj)
{
- return PyObject_IsInstance (obj, (PyObject *) &colorpy_object_type);
+ gdb_assert (obj != nullptr);
+ return PyObject_TypeCheck (obj, &colorpy_object_type) != 0;
}
/* See py-color.h. */
@@ -312,7 +313,7 @@ PyTypeObject colorpy_object_type =
get_attr, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
"GDB color object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
diff --git a/gdb/python/py-disasm.c b/gdb/python/py-disasm.c
index 9ca8d22..17064dc 100644
--- a/gdb/python/py-disasm.c
+++ b/gdb/python/py-disasm.c
@@ -1311,12 +1311,13 @@ gdbpy_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
return {};
}
- /* Check the result is a DisassemblerResult (or a sub-class). */
- if (!PyObject_IsInstance (result.get (),
- (PyObject *) &disasm_result_object_type))
+ /* Check the result is a DisassemblerResult. */
+ if (!PyObject_TypeCheck (result.get (), &disasm_result_object_type))
{
- PyErr_SetString (PyExc_TypeError,
- _("Result is not a DisassemblerResult."));
+ PyErr_Format
+ (PyExc_TypeError,
+ _("Result from Disassembler must be gdb.DisassemblerResult, not %s."),
+ Py_TYPE (result.get ())->tp_name);
gdbpy_print_stack ();
return std::optional<int> (-1);
}
diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c
index 78a806c..9be2e3c 100644
--- a/gdb/python/py-registers.c
+++ b/gdb/python/py-registers.c
@@ -403,8 +403,7 @@ gdbpy_parse_register_id (struct gdbarch *gdbarch, PyObject *pyo_reg_id,
PyErr_SetString (PyExc_ValueError, "Bad register");
}
/* The register could be a gdb.RegisterDescriptor object. */
- else if (PyObject_IsInstance (pyo_reg_id,
- (PyObject *) &register_descriptor_object_type))
+ else if (PyObject_TypeCheck (pyo_reg_id, &register_descriptor_object_type))
{
register_descriptor_object *reg
= (register_descriptor_object *) pyo_reg_id;
diff --git a/gdb/remote.c b/gdb/remote.c
index 7dc057c..75cc21c 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -4943,7 +4943,7 @@ remote_target::process_initial_stop_replies (int from_tty)
event_ptid = target_wait (waiton_ptid, &ws, TARGET_WNOHANG);
if (remote_debug)
- print_target_wait_results (waiton_ptid, event_ptid, ws);
+ print_target_wait_results (waiton_ptid, event_ptid, ws, this);
switch (ws.kind ())
{
diff --git a/gdb/riscv-canonicalize-syscall-gen.c b/gdb/riscv-canonicalize-syscall-gen.c
index 3749fc3..67e5410 100644
--- a/gdb/riscv-canonicalize-syscall-gen.c
+++ b/gdb/riscv-canonicalize-syscall-gen.c
@@ -250,7 +250,7 @@ riscv64_canonicalize_syscall (int syscall)
case 219: return gdb_sys_keyctl;
case 220: return gdb_sys_clone;
case 221: return gdb_sys_execve;
- case 222: return gdb_old_mmap;
+ case 222: return gdb_sys_old_mmap;
case 223: return gdb_sys_fadvise64;
case 224: return gdb_sys_swapon;
case 225: return gdb_sys_swapoff;
@@ -270,7 +270,7 @@ riscv64_canonicalize_syscall (int syscall)
case 239: return gdb_sys_move_pages;
/* case 240: return gdb_sys_rt_tgsigqueueinfo; */
/* case 241: return gdb_sys_perf_event_open; */
- /* case 242: return gdb_sys_accept4; */
+ case 242: return gdb_sys_accept4;
/* case 243: return gdb_sys_recvmmsg; */
/* case 258: return gdb_sys_riscv_hwprobe; */
/* case 259: return gdb_sys_riscv_flush_icache; */
@@ -336,6 +336,22 @@ riscv64_canonicalize_syscall (int syscall)
/* case 448: return gdb_sys_process_mrelease; */
/* case 449: return gdb_sys_futex_waitv; */
/* case 450: return gdb_sys_set_mempolicy_home_node; */
+ /* case 451: return gdb_sys_cachestat; */
+ /* case 452: return gdb_sys_fchmodat2; */
+ /* case 453: return gdb_sys_map_shadow_stack; */
+ /* case 454: return gdb_sys_futex_wake; */
+ /* case 455: return gdb_sys_futex_wait; */
+ /* case 456: return gdb_sys_futex_requeue; */
+ /* case 457: return gdb_sys_statmount; */
+ /* case 458: return gdb_sys_listmount; */
+ /* case 459: return gdb_sys_lsm_get_self_attr; */
+ /* case 460: return gdb_sys_lsm_set_self_attr; */
+ /* case 461: return gdb_sys_lsm_list_modules; */
+ /* case 462: return gdb_sys_mseal; */
+ /* case 463: return gdb_sys_setxattrat; */
+ /* case 464: return gdb_sys_getxattrat; */
+ /* case 465: return gdb_sys_listxattrat; */
+ /* case 466: return gdb_sys_removexattrat; */
default:
return gdb_sys_no_syscall;
}
diff --git a/gdb/riscv-linux-tdep.h b/gdb/riscv-linux-tdep.h
index 0f481b1..9dd9e37 100644
--- a/gdb/riscv-linux-tdep.h
+++ b/gdb/riscv-linux-tdep.h
@@ -15,8 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#ifndef RISCV_LINUX_TDEP_H
-#define RISCV_LINUX_TDEP_H
+#ifndef GDB_RISCV_LINUX_TDEP_H
+#define GDB_RISCV_LINUX_TDEP_H
#include "linux-record.h"
@@ -26,4 +26,4 @@
extern enum gdb_syscall riscv64_canonicalize_syscall (int syscall);
-#endif /* RISCV_LINUX_TDEP_H */
+#endif /* GDB_RISCV_LINUX_TDEP_H */
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 83cb389..2a2745d 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -451,6 +451,12 @@ svr4_maybe_add_namespace (svr4_info *info, CORE_ADDR lmid)
info->namespace_id.push_back (lmid);
info->active_namespaces.insert (i);
+
+ /* Create or update the convenience variable "active_namespaces".
+ It only needs to be updated here, as this only changes when a
+ dlmopen or dlclose call happens. */
+ set_internalvar_integer (lookup_internalvar ("_active_linker_namespaces"),
+ info->active_namespaces.size ());
}
/* Return whether DEBUG_BASE is the default namespace of INFO. */
@@ -3552,6 +3558,54 @@ svr4_num_active_namespaces ()
return info->active_namespaces.size ();
}
+/* See solib_ops::get_solibs_in_ns in solist.h. */
+static std::vector<const solib *>
+svr4_get_solibs_in_ns (int nsid)
+{
+ std::vector<const solib*> ns_solibs;
+ svr4_info *info = get_svr4_info (current_program_space);
+
+ /* If the namespace ID is inactive, there will be no active
+ libraries, so we can have an early exit, as a treat. */
+ if (info->active_namespaces.count (nsid) != 1)
+ return ns_solibs;
+
+ /* Since we only have the names of solibs in a given namespace,
+ we'll need to walk through the solib list of the inferior and
+ find which solib objects correspond to which svr4_so. We create
+ an unordered map with the names and lm_info to check things
+ faster, and to be able to remove SOs from the map, to avoid
+ returning the dynamic linker multiple times. */
+ CORE_ADDR debug_base = info->namespace_id[nsid];
+ std::unordered_map<std::string, const lm_info_svr4 *> namespace_solibs;
+ for (svr4_so &so : info->solib_lists[debug_base])
+ {
+ namespace_solibs[so.name]
+ = gdb::checked_static_cast<const lm_info_svr4 *>
+ (so.lm_info.get ());
+ }
+ for (const solib &so: current_program_space->solibs ())
+ {
+ auto *lm_inferior
+ = gdb::checked_static_cast<const lm_info_svr4 *> (so.lm_info.get ());
+
+ /* This is inspired by the svr4_same, by finding the svr4_so object
+ in the map, and then double checking if the lm_info is considered
+ the same. */
+ if (namespace_solibs.count (so.so_original_name) > 0
+ && namespace_solibs[so.so_original_name]->l_addr_inferior
+ == lm_inferior->l_addr_inferior)
+ {
+ ns_solibs.push_back (&so);
+ /* Remove the SO from the map, so that we don't end up
+ printing the dynamic linker multiple times. */
+ namespace_solibs.erase (so.so_original_name);
+ }
+ }
+
+ return ns_solibs;
+}
+
const struct solib_ops svr4_so_ops =
{
svr4_relocate_section_addresses,
@@ -3569,6 +3623,7 @@ const struct solib_ops svr4_so_ops =
svr4_find_solib_addr,
svr4_find_solib_ns,
svr4_num_active_namespaces,
+ svr4_get_solibs_in_ns,
};
void _initialize_svr4_solib ();
diff --git a/gdb/solib.c b/gdb/solib.c
index 4876f1a..5c5cfbd 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1010,84 +1010,61 @@ solib_add (const char *pattern, int from_tty, int readsyms)
}
}
-/* Implement the "info sharedlibrary" command. Walk through the
- shared library list and print information about each attached
- library matching PATTERN. If PATTERN is elided, print them
- all. */
+/* Helper function for "info sharedlibrary" and "info namespace".
+ This receives a list of solibs to be printed, and prints a table
+ with all the relevant data. If PRINT_NAMESPACE is true, figure out
+ the solib_ops of the current gdbarch, to calculate the namespace
+ that contains an solib.
+ Returns true if one or more solibs are missing debug information,
+ false otherwise. */
static void
-info_sharedlibrary_command (const char *pattern, int from_tty)
+print_solib_list_table (std::vector<const solib *> solib_list,
+ bool print_namespace)
{
- bool so_missing_debug_info = false;
- int addr_width;
- int nr_libs;
gdbarch *gdbarch = current_inferior ()->arch ();
- struct ui_out *uiout = current_uiout;
-
- if (pattern)
- {
- char *re_err = re_comp (pattern);
-
- if (re_err)
- error (_ ("Invalid regexp: %s"), re_err);
- }
-
/* "0x", a little whitespace, and two hex digits per byte of pointers. */
- addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
-
- update_solib_list (from_tty);
-
- /* ui_out_emit_table table_emitter needs to know the number of rows,
- so we need to make two passes over the libs. */
+ int addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
+ const solib_ops *ops = gdbarch_so_ops (gdbarch);
+ struct ui_out *uiout = current_uiout;
+ bool so_missing_debug_info = false;
- nr_libs = 0;
- for (const solib &so : current_program_space->solibs ())
- {
- if (!so.so_name.empty ())
- {
- if (pattern && !re_exec (so.so_name.c_str ()))
- continue;
- ++nr_libs;
- }
- }
+ /* There are 3 conditions for this command to print solib namespaces,
+ first PRINT_NAMESPACE has to be true, second the solib_ops has to
+ support multiple namespaces, and third there must be more than one
+ active namespace. Fold all these into the PRINT_NAMESPACE condition. */
+ print_namespace = print_namespace && ops->num_active_namespaces != nullptr
+ && ops->num_active_namespaces () > 1;
- /* How many columns the table should have. If the inferior has
- more than one namespace active, we need a column to show that. */
int num_cols = 4;
- const solib_ops *ops = gdbarch_so_ops (gdbarch);
- if (ops->num_active_namespaces != nullptr
- && ops->num_active_namespaces () > 1)
+ if (print_namespace)
num_cols++;
{
- ui_out_emit_table table_emitter (uiout, num_cols, nr_libs,
+ ui_out_emit_table table_emitter (uiout, num_cols, solib_list.size (),
"SharedLibraryTable");
/* The "- 1" is because ui_out adds one space between columns. */
uiout->table_header (addr_width - 1, ui_left, "from", "From");
uiout->table_header (addr_width - 1, ui_left, "to", "To");
- if (ops->num_active_namespaces != nullptr
- && ops->num_active_namespaces () > 1)
+ if (print_namespace)
uiout->table_header (5, ui_left, "namespace", "NS");
uiout->table_header (12 - 1, ui_left, "syms-read", "Syms Read");
uiout->table_header (0, ui_noalign, "name", "Shared Object Library");
uiout->table_body ();
- for (const solib &so : current_program_space->solibs ())
+ for (const solib *so : solib_list)
{
- if (so.so_name.empty ())
- continue;
-
- if (pattern && !re_exec (so.so_name.c_str ()))
+ if (so->so_name.empty ())
continue;
ui_out_emit_tuple tuple_emitter (uiout, "lib");
- if (so.addr_high != 0)
+ if (so->addr_high != 0)
{
- uiout->field_core_addr ("from", gdbarch, so.addr_low);
- uiout->field_core_addr ("to", gdbarch, so.addr_high);
+ uiout->field_core_addr ("from", gdbarch, so->addr_low);
+ uiout->field_core_addr ("to", gdbarch, so->addr_high);
}
else
{
@@ -1095,12 +1072,11 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
uiout->field_skip ("to");
}
- if (ops->num_active_namespaces != nullptr
- && ops->num_active_namespaces ()> 1)
+ if (print_namespace)
{
try
{
- uiout->field_fmt ("namespace", "[[%d]]", ops->find_solib_ns (so));
+ uiout->field_fmt ("namespace", "[[%d]]", ops->find_solib_ns (*so));
}
catch (const gdb_exception_error &er)
{
@@ -1109,32 +1085,157 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
}
if (!top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ()
- && so.symbols_loaded && !objfile_has_symbols (so.objfile))
+ && so->symbols_loaded && !objfile_has_symbols (so->objfile))
{
so_missing_debug_info = true;
uiout->field_string ("syms-read", "Yes (*)");
}
else
- uiout->field_string ("syms-read", so.symbols_loaded ? "Yes" : "No");
+ uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No");
- uiout->field_string ("name", so.so_name, file_name_style.style ());
+ uiout->field_string ("name", so->so_name, file_name_style.style ());
uiout->text ("\n");
}
}
- if (nr_libs == 0)
+ if (so_missing_debug_info)
+ uiout->message (_ ("(*): Shared library is missing "
+ "debugging information.\n"));
+}
+
+/* Implement the "info sharedlibrary" command. Walk through the
+ shared library list and print information about each attached
+ library matching PATTERN. If PATTERN is elided, print them
+ all. */
+
+static void
+info_sharedlibrary_command (const char *pattern, int from_tty)
+{
+ struct ui_out *uiout = current_uiout;
+
+ if (pattern)
+ {
+ char *re_err = re_comp (pattern);
+
+ if (re_err)
+ error (_ ("Invalid regexp: %s"), re_err);
+ }
+
+ update_solib_list (from_tty);
+
+ /* ui_out_emit_table table_emitter needs to know the number of rows,
+ so we need to make two passes over the libs. */
+
+ std::vector<const solib *> print_libs;
+ for (const solib &so : current_program_space->solibs ())
+ {
+ if (!so.so_name.empty ())
+ {
+ if (pattern && !re_exec (so.so_name.c_str ()))
+ continue;
+ print_libs.push_back (&so);
+ }
+ }
+
+ print_solib_list_table (print_libs, true);
+
+ if (print_libs.size () == 0)
{
if (pattern)
uiout->message (_ ("No shared libraries matched.\n"));
else
uiout->message (_ ("No shared libraries loaded at this time.\n"));
}
+}
+
+/* Implement the "info linker-namespaces" command. If the current
+ gdbarch's solib_ops object does not support multiple namespaces,
+ this command would just look like "info sharedlibrary", so point
+ the user to that command instead.
+ If solib_ops does support multiple namespaces, this command
+ will group the libraries by linker namespace, or only print the
+ libraries in the supplied namespace. */
+static void
+info_linker_namespace_command (const char *pattern, int from_tty)
+{
+ const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ /* This command only really makes sense for inferiors that support
+ linker namespaces, so we can leave early. */
+ if (ops->num_active_namespaces == nullptr)
+ error (_("Current inferior does not support linker namespaces." \
+ "Use \"info sharedlibrary\" instead"));
+
+ struct ui_out *uiout = current_uiout;
+ std::vector<std::pair<int, std::vector<const solib *>>> all_solibs_to_print;
+
+ if (pattern != nullptr)
+ while (*pattern == ' ')
+ pattern++;
+
+ if (pattern == nullptr || pattern[0] == '\0')
+ {
+ uiout->message (_ ("There are %d linker namespaces loaded\n"),
+ ops->num_active_namespaces ());
+
+ int printed = 0;
+ for (int i = 0; printed < ops->num_active_namespaces (); i++)
+ {
+ std::vector<const solib *> solibs_to_print
+ = ops->get_solibs_in_ns (i);
+ if (solibs_to_print.size () > 0)
+ {
+ all_solibs_to_print.push_back (std::make_pair
+ (i, solibs_to_print));
+ printed++;
+ }
+ }
+ }
else
{
- if (so_missing_debug_info)
- uiout->message (_ ("(*): Shared library is missing "
- "debugging information.\n"));
+ int ns;
+ /* Check if the pattern includes the optional [[ and ]] decorators.
+ To match multiple occurrences, '+' needs to be escaped, and every
+ escape sequence must be doubled to survive the compiler pass. */
+ re_comp ("^\\[\\[[0-9]\\+\\]\\]$");
+ if (re_exec (pattern))
+ ns = strtol (pattern+2, nullptr, 10);
+ else
+ {
+ char * end = nullptr;
+ ns = strtol (pattern, &end, 10);
+ if (end[0] != '\0')
+ error (_ ("Invalid linker namespace identifier: %s"), pattern);
+ }
+
+ all_solibs_to_print.push_back
+ (std::make_pair (ns, ops->get_solibs_in_ns (ns)));
+ }
+
+ bool ns_separator = false;
+
+ for (auto &solibs_pair : all_solibs_to_print)
+ {
+ if (ns_separator)
+ uiout->message ("\n\n");
+ else
+ ns_separator = true;
+ int ns = solibs_pair.first;
+ std::vector<const solib *> solibs_to_print = solibs_pair.second;
+ if (solibs_to_print.size () == 0)
+ {
+ uiout->message (_("Linker namespace [[%d]] is not active.\n"), ns);
+ /* If we got here, a specific namespace was requested, so there
+ will only be one vector. We can leave early. */
+ break;
+ }
+ uiout->message
+ (_ ("There are %ld libraries loaded in linker namespace [[%d]]\n"),
+ solibs_to_print.size (), ns);
+ uiout->message
+ (_ ("Displaying libraries for linker namespace [[%d]]:\n"), ns);
+
+ print_solib_list_table (solibs_to_print, false);
}
}
@@ -1715,6 +1816,44 @@ default_find_solib_addr (solib &so)
return {};
}
+/* Implementation of the current_linker_namespace convenience variable.
+ This returns the GDB internal identifier of the linker namespace,
+ for the current frame, in the form '[[<number>]]'. If the inferior
+ doesn't support linker namespaces, this always returns [[0]]. */
+
+static value *
+current_linker_namespace_make_value (gdbarch *gdbarch, internalvar *var,
+ void *ignore)
+{
+ const solib_ops *ops = gdbarch_so_ops (gdbarch);
+ const language_defn *lang = language_def (get_frame_language
+ (get_current_frame ()));
+ std::string nsid = "[[0]]";
+ if (ops->find_solib_ns != nullptr)
+ {
+ CORE_ADDR curr_pc = get_frame_pc (get_current_frame ());
+ for (const solib &so : current_program_space->solibs ())
+ if (solib_contains_address_p (so, curr_pc))
+ {
+ nsid = string_printf ("[[%d]]", ops->find_solib_ns (so));
+ break;
+ }
+ }
+
+
+ /* If the PC is not in an SO, or the solib_ops doesn't support
+ linker namespaces, the inferior is in the default namespace. */
+ return lang->value_string (gdbarch, nsid.c_str (), nsid.length ());
+}
+
+/* Implementation of `$_current_linker_namespace' variable. */
+
+static const struct internalvar_funcs current_linker_namespace_funcs =
+{
+ current_linker_namespace_make_value,
+ nullptr,
+};
+
void _initialize_solib ();
void
@@ -1727,6 +1866,13 @@ _initialize_solib ()
},
"solib");
+ /* Convenience variables for debugging linker namespaces. These are
+ set here, even if the solib_ops doesn't support them,
+ for consistency. */
+ create_internalvar_type_lazy ("_current_linker_namespace",
+ &current_linker_namespace_funcs, nullptr);
+ set_internalvar_integer (lookup_internalvar ("_active_linker_namespaces"), 1);
+
add_com (
"sharedlibrary", class_files, sharedlibrary_command,
_ ("Load shared object library symbols for files matching REGEXP."));
@@ -1737,6 +1883,9 @@ _initialize_solib ()
add_com ("nosharedlibrary", class_files, no_shared_libraries_command,
_ ("Unload all shared object library symbols."));
+ add_info ("linker-namespaces", info_linker_namespace_command,
+ _ ("Get information about linker namespaces in the inferior."));
+
add_setshow_boolean_cmd ("auto-solib-add", class_support, &auto_solib_add,
_ ("\
Set autoloading of shared library symbols."),
diff --git a/gdb/solist.h b/gdb/solist.h
index 0b7bbf9..6ab5a06 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -194,6 +194,10 @@ struct solib_ops
/* Returns the number of active namespaces in the inferior. */
int (*num_active_namespaces) ();
+
+ /* Returns all solibs for a given namespace. If the namespace is not
+ active, returns an empty vector. */
+ std::vector<const solib *> (*get_solibs_in_ns) (int ns);
};
/* A unique pointer to a so_list. */
diff --git a/gdb/syscalls/riscv-canonicalize-syscall-gen.py b/gdb/syscalls/riscv-canonicalize-syscall-gen.py
index aa07ac1..30e52b7 100755
--- a/gdb/syscalls/riscv-canonicalize-syscall-gen.py
+++ b/gdb/syscalls/riscv-canonicalize-syscall-gen.py
@@ -32,7 +32,7 @@
# options:
# -h, --help show this help message and exit
# -i INPUT, --input INPUT
-# path to riscv linux syscalls (riscv-glibc/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h)
+# path to riscv linux syscalls (glibc/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h)
import argparse
import re
@@ -142,7 +142,7 @@ def setup_parser() -> argparse.ArgumentParser:
"--input",
type=_Path,
required=True,
- help="path to riscv linux syscalls (riscv-glibc/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h)",
+ help="path to riscv linux syscalls (glibc/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h)",
)
return parser
diff --git a/gdb/testsuite/gdb.base/bg-execution-repeat.exp b/gdb/testsuite/gdb.base/bg-execution-repeat.exp
index b1496ee..d5580fb 100644
--- a/gdb/testsuite/gdb.base/bg-execution-repeat.exp
+++ b/gdb/testsuite/gdb.base/bg-execution-repeat.exp
@@ -67,6 +67,17 @@ proc test {continue_cmd} {
# enable the "set var" command with an interrupt / continue& pair.
gdb_test -no-prompt-anchor "interrupt"
+ set test "interrupt received"
+ set re [string_to_regexp "Program received signal SIGINT, Interrupt."]
+ gdb_expect {
+ -re $re {
+ pass $test
+ }
+ timeout {
+ fail "$test (timeout)"
+ }
+ }
+
# Allow the breakpoint to trigger.
gdb_test -no-prompt-anchor "set var do_wait=0"
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
index d4d6b20..3abd049 100644
--- a/gdb/testsuite/gdb.base/default.exp
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -699,6 +699,8 @@ set show_conv_list \
{$_gdb_minor = 1} \
{$_shell_exitsignal = void} \
{$_shell_exitcode = 0} \
+ {$_active_linker_namespaces = 1} \
+ {$_current_linker_namespace = <error: No registers.>}\
}
if [allow_python_tests] {
append show_conv_list \
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c
index 3bcd819..c7c038a 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c
@@ -41,6 +41,12 @@ main (void)
handle[2] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL);
assert (handle[2] != NULL);
+ for (dl = 2; dl >= 0; dl--)
+ {
+ fun = dlsym (handle[dl], "inc");
+ fun (dl);
+ }
+
dlclose (handle[0]); /* TAG: first dlclose */
dlclose (handle[1]); /* TAG: second dlclose */
dlclose (handle[2]); /* TAG: third dlclose */
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
index 3ddc07e..8f52199 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
@@ -105,4 +105,137 @@ proc test_info_shared {} {
"after unloading everything"
}
+# Run all tests related to the linkage namespaces convenience
+# variables, _active_namespaces and _current_namespaces.
+proc_with_prefix test_conv_vars {} {
+ clean_restart $::binfile
+
+ gdb_test "print \$_active_linker_namespaces" "1" \
+ "1 namespace before starting inferior"
+ gdb_test "print \$_current_linker_namespace" "No registers." \
+ "No current namespace before starting inferior"
+
+ if { ![runto_main] } {
+ return
+ }
+
+ gdb_test "print \$_active_linker_namespaces" "1" \
+ "Before activating namespaces"
+ gdb_test "print \$_current_linker_namespace" ".*\"\\\[\\\[0\\\]\\\]\"" \
+ "Still in the default namespace"
+
+ gdb_breakpoint "inc" allow-pending
+ gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"]
+
+ foreach_with_prefix dl {3 2 1} {
+ gdb_continue_to_breakpoint "inc"
+
+ gdb_test "print \$_current_linker_namespace" ".*\"\\\[\\\[$dl\\\]\\\]\"" \
+ "Verify we're in namespace $dl"
+ }
+
+ gdb_continue_to_breakpoint "first dlclose"
+ gdb_test "print \$_active_linker_namespaces" "4" "all SOs loaded"
+
+ gdb_test "next" ".*second dlclose.*" "close one SO"
+ gdb_test "print \$_active_linker_namespaces" "3" "one SOs unloaded"
+ gdb_test "next" ".*third dlclose.*" "close another SO"
+ gdb_test "print \$_active_linker_namespaces" "2" "two SOs unloaded"
+
+ # Restarting GDB so that we can test setting a breakpoint
+ # using the convenience variable, while a proper bp syntax
+ # isn't implemented for namespaces
+ clean_restart $::binfile
+ if {![runto_main]} {
+ return
+ }
+
+ # We need to load one SO because you can't have confitional
+ # breakpoints and pending breakpoints at the same time with
+ # gdb_breakpoint.
+ gdb_test "next" ".*assert.*" "load the first SO"
+ gdb_breakpoint "inc if \$_streq(\$_current_linker_namespace, \"\[\[2\]\]\")"
+ gdb_continue_to_breakpoint "inc"
+ gdb_continue_to_end "" continue 1
+}
+
+# Run several tests relating to the command "info namespaces".
+proc test_info_linker_namespaces {} {
+ clean_restart $::binfile
+
+ if { ![runto_main] } {
+ return
+ }
+
+ with_test_prefix "info linker-namespaces" {
+ gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"]
+ gdb_continue_to_breakpoint "TAG: first dlclose"
+ }
+
+ # First, test printing a single namespace, and ensure all of
+ # them are correct, using both syntaxes.
+ set found_all_libs false
+ gdb_test_multiple "info linker-namespaces \[\[0\]\]" "print namespace 0" -lbl {
+ -re "^\r\nThere are ($::decimal) libraries loaded in linker namespace \\\[\\\[0\\\]\\\]" {
+ # Some systems may add libc and libm to every loaded namespace,
+ # others may load only one or neither, because the SO doesn't
+ # actually use either library. The best we can do is check if
+ # we found the dynamic linker, and up to 2 more libraries.
+ set libs $expect_out(1,string)
+ set found_all_libs [expr $libs - 1 <= 2]
+ exp_continue
+ }
+ -re "^\r\n$::gdb_prompt $" {
+ gdb_assert $found_all_libs "the correct number of libraries was reported"
+ }
+ -re "(^\r\n)?\[^\r\n\]+(?=\r\n)" {
+ exp_continue
+ }
+ }
+ foreach_with_prefix ns {1 2 3} {
+ set found_test_so false
+ set found_all_libs false
+ gdb_test_multiple "info linker-namespaces $ns" "print namespace $ns" -lbl {
+ -re "^\r\nThere are ($::decimal) libraries loaded in linker namespace \\\[\\\[$ns\\\]\\\]" {
+ set libs $expect_out(1,string)
+ # Some systems may add libc and libm to every loaded namespace,
+ # others may load only one or neither, because the SO doesn't
+ # actually use either library. The best we can do is check if
+ # we found the dynamic linker, the test SO, and maybe up to 2
+ # more libraries.
+ set found_all_libs [expr $libs - 2 <= 2]
+ exp_continue
+ }
+ -re "^\r\n\[^\r\n\]+${::binfile_lib}\[^\r\n\]*(?=\r\n)" {
+ set found_test_so true
+ exp_continue
+ }
+ -re "^\r\n$::gdb_prompt $" {
+ gdb_assert $found_test_so "this testfle's SO was reported"
+ gdb_assert $found_all_libs "the correct number of libraries was reported"
+ }
+ -re "(^\r\n)?\[^\r\n\]+(?=\r\n)" {
+ exp_continue
+ }
+ }
+ }
+
+ # These patterns are simpler, and purposefully glob multiple lines.
+ # The point is to ensure that we find and display all the namespaces,
+ # without worrying about the libraries printed, since that was tested
+ # above.
+ gdb_test "info linker-namespaces" \
+ [multi_line "There are 4 linker namespaces loaded" \
+ "There are $::decimal libraries loaded in linker namespace ..0.." \
+ ".*" \
+ "There are $::decimal libraries loaded in linker namespace ..1.." \
+ ".*" \
+ "There are $::decimal libraries loaded in linker namespace ..2.." \
+ ".*" \
+ "There are $::decimal libraries loaded in linker namespace ..3.." \
+ ".*" ] "print namespaces with no argument"
+}
+
test_info_shared
+test_conv_vars
+test_info_linker_namespaces
diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw4.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw4.exp
new file mode 100644
index 0000000..c0c2635
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw4.exp
@@ -0,0 +1,71 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2022-2025 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/>.
+
+# Generate binaries imitating different ways source file paths can be passed to
+# compilers. Test printing macros from those binaries.
+
+# The do_test proc comes from macro-source-path.exp.tcl.
+source $srcdir/$subdir/macro-source-path.exp.tcl
+
+# When adding a test here, please consider adding an equivalent case to
+# `gdb.base/macro-source-path.exp`.
+
+# The following tests are based on the output of `clang-14 -gdwarf-4
+# -fdebug-macro -g3 <file>` (using its built-in assembler). With -gdwarf-4,
+# clang produces a .debug_macinfo section, not a .debug_macro section. But
+# this test still creates a .debug_macro section, that's good enough for what
+# we want to test.
+
+## test.c
+do_test filename 4 "test.c" 1 {
+} {
+ {"test.c" 0}
+}
+
+## ./test.c
+do_test dot-filename 4 "test.c" 1 {
+ "."
+} {
+ {"test.c" 1}
+}
+
+## ../cwd/test.c
+do_test dot-dot-cwd 4 "../cwd/test.c" 1 {
+ "../cwd"
+} {
+ {"test.c" 1}
+}
+
+## /tmp/cwd/test.c
+do_test absolute-cwd 4 "/tmp/cwd/test.c" 1 {
+} {
+ {"test.c" 0}
+}
+
+## ../other/test.c
+do_test dot-dot-other 4 "../other/test.c" 1 {
+ "../other"
+} {
+ {"test.c" 1}
+}
+
+## /tmp/other/test.c
+do_test absolute-other 4 "/tmp/other/test.c" 1 {
+ "/tmp"
+} {
+ {"other/test.c" 1}
+}
diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw5.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw5.exp
new file mode 100644
index 0000000..0b3239e
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-clang14-dw5.exp
@@ -0,0 +1,75 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2022-2025 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/>.
+
+# Generate binaries imitating different ways source file paths can be passed to
+# compilers. Test printing macros from those binaries.
+
+# The do_test proc comes from macro-source-path.exp.tcl.
+source $srcdir/$subdir/macro-source-path.exp.tcl
+
+# When adding a test here, please consider adding an equivalent case to
+# `gdb.base/macro-source-path.exp`.
+
+# The following tests are based on the output of `clang-14 -gdwarf-5
+# -fdebug-macro -g3 <file>` (using its built-in assembler)
+
+## test.c
+do_test filename 5 "test.c" 0 {
+ "/tmp/cwd"
+} {
+ {"test.c" 0}
+}
+
+## ./test.c
+do_test dot-filename 5 "test.c" 1 {
+ "/tmp/cwd"
+ "."
+} {
+ {"test.c" 0}
+ {"test.c" 1}
+}
+
+## ../cwd/test.c
+do_test dot-dot-cwd 5 "../cwd/test.c" 0 {
+ "/tmp/cwd"
+} {
+ {"../cwd/test.c" 0}
+}
+
+## /tmp/cwd/test.c
+do_test absolute-cwd 5 "/tmp/cwd/test.c" 1 {
+ "/tmp/cwd"
+} {
+ {"/tmp/cwd/test.c" 0}
+ {"test.c" 0}
+}
+
+## ../other/test.c
+do_test dot-dot-other 5 "../other/test.c" 0 {
+ "/tmp/cwd"
+} {
+ {"../other/test.c" 0}
+}
+
+## /tmp/other/test.c
+do_test absolute-other 5 "/tmp/other/test.c" 1 {
+ "/tmp/cwd"
+ "/tmp"
+} {
+ {"/tmp/other/test.c" 0}
+ {"other/test.c" 1}
+}
diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld234-dw5.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld234-dw5.exp
new file mode 100644
index 0000000..940f997
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld234-dw5.exp
@@ -0,0 +1,70 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2022-2025 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/>.
+
+# Generate binaries imitating different ways source file paths can be passed to
+# compilers. Test printing macros from those binaries.
+
+# The do_test proc comes from macro-source-path.exp.tcl.
+source $srcdir/$subdir/macro-source-path.exp.tcl
+
+# When adding a test here, please consider adding an equivalent case to
+# `gdb.base/macro-source-path.exp`.
+
+# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`,
+# gcc 11 paired with gas from binutils 2.34 (Ubuntu 20.04). It generates a v5
+# .debug_macro section, but a v3 .debug_line section.
+
+## test.c
+do_test filename 3 "test.c" 1 {
+} {
+ {"test.c" 0}
+}
+
+## ./test.c
+do_test dot-filename 3 "./test.c" 1 {
+ "."
+} {
+ {"test.c" 1}
+}
+
+## ../cwd/test.c
+do_test dot-dot-cwd 3 "../cwd/test.c" 1 {
+ "../cwd"
+} {
+ {"test.c" 1}
+}
+
+## /tmp/cwd/test.c
+do_test absolute-cwd 3 "/tmp/cwd/test.c" 1 {
+ "/tmp/cwd"
+} {
+ {"test.c" 1}
+}
+
+## ../other/test.c
+do_test dot-dot-other 3 "../other/test.c" 1 {
+ "../other"
+} {
+ {"test.c" 1}
+}
+
+## /tmp/other/test.c
+do_test absolute-other 3 "/tmp/other/test.c" 1 {
+ "/tmp/other"
+} {
+ {"test.c" 1}
+}
diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw4.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw4.exp
new file mode 100644
index 0000000..dea0308
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw4.exp
@@ -0,0 +1,70 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2022-2025 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/>.
+
+# Generate binaries imitating different ways source file paths can be passed to
+# compilers. Test printing macros from those binaries.
+
+# The do_test proc comes from macro-source-path.exp.tcl.
+source $srcdir/$subdir/macro-source-path.exp.tcl
+
+# When adding a test here, please consider adding an equivalent case to
+# `gdb.base/macro-source-path.exp`.
+
+# The following tests are based on the output of `gcc -gdwarf-4 -g3 <file>`,
+# gcc 11 paired with gas from binutils 2.38. With -gdwarf-4, gcc generates a
+# v4 (pre-standard) .debug_macro section.
+
+## test.c
+do_test filename 4 "test.c" 1 {
+} {
+ {"test.c" 0}
+}
+
+## ./test.c
+do_test dot-filename 4 "./test.c" 1 {
+ "."
+} {
+ {"test.c" 1}
+}
+
+## ../cwd/test.c
+do_test dot-dot-cwd 4 "../cwd/test.c" 1 {
+ "../cwd"
+} {
+ {"test.c" 1}
+}
+
+## /tmp/cwd/test.c
+do_test absolute-cwd 4 "/tmp/cwd/test.c" 1 {
+ "/tmp/cwd"
+} {
+ {"test.c" 1}
+}
+
+## ../other/test.c
+do_test dot-dot-other 4 "../other/test.c" 1 {
+ "../other"
+} {
+ {"test.c" 1}
+}
+
+## /tmp/other/test.c
+do_test absolute-other 4 "/tmp/other/test.c" 1 {
+ "/tmp/other"
+} {
+ {"test.c" 1}
+}
diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw5.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw5.exp
new file mode 100644
index 0000000..98a278e
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/macro-source-path-gcc11-ld238-dw5.exp
@@ -0,0 +1,81 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2022-2025 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/>.
+
+# Generate binaries imitating different ways source file paths can be passed to
+# compilers. Test printing macros from those binaries.
+
+# The do_test proc comes from macro-source-path.exp.tcl.
+source $srcdir/$subdir/macro-source-path.exp.tcl
+
+# When adding a test here, please consider adding an equivalent case to
+# `gdb.base/macro-source-path.exp`.
+
+# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`,
+# gcc 11 paired with gas from binutils 2.38.
+
+## test.c
+do_test filename 5 "test.c" 1 {
+ "/tmp/cwd"
+} {
+ {"test.c" 0}
+ {"test.c" 0}
+}
+
+## ./test.c
+do_test dot-filename 5 "./test.c" 1 {
+ "/tmp/cwd"
+ "."
+} {
+ {"test.c" 1}
+ {"test.c" 1}
+}
+
+## ../cwd/test.c
+do_test dot-dot-cwd 5 "../cwd/test.c" 1 {
+ "/tmp/cwd"
+ "../cwd"
+} {
+ {"test.c" 1}
+ {"test.c" 1}
+}
+
+## /tmp/cwd/test.c
+do_test absolute-cwd 5 "/tmp/cwd/test.c" 1 {
+ "/tmp/cwd"
+ "/tmp/cwd"
+} {
+ {"test.c" 1}
+ {"test.c" 0}
+}
+
+## ../other/test.c
+do_test dot-dot-other 5 "../other/test.c" 1 {
+ "/tmp/cwd"
+ "../other"
+} {
+ {"test.c" 1}
+ {"test.c" 1}
+}
+
+## /tmp/other/test.c
+do_test absolute-other 5 "/tmp/other/test.c" 1 {
+ "/tmp/cwd"
+ "/tmp/other"
+} {
+ {"test.c" 1}
+ {"test.c" 1}
+}
diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path.exp.tcl
index 1318f8e..ecaf685 100644
--- a/gdb/testsuite/gdb.dwarf2/macro-source-path.exp
+++ b/gdb/testsuite/gdb.dwarf2/macro-source-path.exp.tcl
@@ -17,12 +17,15 @@
# Generate binaries imitating different ways source file paths can be passed to
# compilers. Test printing macros from those binaries.
+#
+# The entry points for this test are in the various
+# gdb.dwarf2/macro-source-path-*.exp files.
load_lib dwarf.exp
require dwarf2_support
-standard_testfile .c
+standard_testfile macro-source-path.c
lassign [function_range main $srcdir/$subdir/$srcfile] \
main_start main_len
@@ -160,248 +163,3 @@ proc do_test { test_name lines_version DW_AT_name main_file_idx directories
}
}
}
-
-# When adding a test here, please consider adding an equivalent case to the test
-# of the same name in gdb.base.
-
-# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`,
-# gcc 11 paired with gas from binutils 2.38.
-
-## test.c
-do_test gcc11-ld238-dw5-filename 5 "test.c" 1 {
- "/tmp/cwd"
-} {
- {"test.c" 0}
- {"test.c" 0}
-}
-
-## ./test.c
-do_test gcc11-ld238-dw5-dot-filename 5 "./test.c" 1 {
- "/tmp/cwd"
- "."
-} {
- {"test.c" 1}
- {"test.c" 1}
-}
-
-## ../cwd/test.c
-do_test gcc11-ld238-dw5-dot-dot-cwd 5 "../cwd/test.c" 1 {
- "/tmp/cwd"
- "../cwd"
-} {
- {"test.c" 1}
- {"test.c" 1}
-}
-
-## /tmp/cwd/test.c
-do_test gcc11-ld238-dw5-absolute-cwd 5 "/tmp/cwd/test.c" 1 {
- "/tmp/cwd"
- "/tmp/cwd"
-} {
- {"test.c" 1}
- {"test.c" 0}
-}
-
-## ../other/test.c
-do_test gcc11-ld238-dw5-dot-dot-other 5 "../other/test.c" 1 {
- "/tmp/cwd"
- "../other"
-} {
- {"test.c" 1}
- {"test.c" 1}
-}
-
-## /tmp/other/test.c
-do_test gcc11-ld238-dw5-absolute-other 5 "/tmp/other/test.c" 1 {
- "/tmp/cwd"
- "/tmp/other"
-} {
- {"test.c" 1}
- {"test.c" 1}
-}
-
-# The following tests are based on the output of `gcc -gdwarf-4 -g3 <file>`,
-# gcc 11 paired with gas from binutils 2.38. With -gdwarf-4, gcc generates a
-# v4 (pre-standard) .debug_macro section.
-
-## test.c
-do_test gcc11-ld238-dw4-filename 4 "test.c" 1 {
-} {
- {"test.c" 0}
-}
-
-## ./test.c
-do_test gcc11-ld238-dw4-dot-filename 4 "./test.c" 1 {
- "."
-} {
- {"test.c" 1}
-}
-
-## ../cwd/test.c
-do_test gcc11-ld238-dw4-dot-dot-cwd 4 "../cwd/test.c" 1 {
- "../cwd"
-} {
- {"test.c" 1}
-}
-
-## /tmp/cwd/test.c
-do_test gcc11-ld238-dw4-absolute-cwd 4 "/tmp/cwd/test.c" 1 {
- "/tmp/cwd"
-} {
- {"test.c" 1}
-}
-
-## ../other/test.c
-do_test gcc11-ld238-dw4-dot-dot-other 4 "../other/test.c" 1 {
- "../other"
-} {
- {"test.c" 1}
-}
-
-## /tmp/other/test.c
-do_test gcc11-ld238-dw4-absolute-other 4 "/tmp/other/test.c" 1 {
- "/tmp/other"
-} {
- {"test.c" 1}
-}
-
-# The following tests are based on the output of `clang-14 -gdwarf-5
-# -fdebug-macro -g3 <file>` (using its built-in assembler)
-
-## test.c
-do_test clang14-dw5-filename 5 "test.c" 0 {
- "/tmp/cwd"
-} {
- {"test.c" 0}
-}
-
-## ./test.c
-do_test clang14-dw5-dot-filename 5 "test.c" 1 {
- "/tmp/cwd"
- "."
-} {
- {"test.c" 0}
- {"test.c" 1}
-}
-
-## ../cwd/test.c
-do_test clang14-dw5-dot-dot-cwd 5 "../cwd/test.c" 0 {
- "/tmp/cwd"
-} {
- {"../cwd/test.c" 0}
-}
-
-## /tmp/cwd/test.c
-do_test clang14-dw5-absolute-cwd 5 "/tmp/cwd/test.c" 1 {
- "/tmp/cwd"
-} {
- {"/tmp/cwd/test.c" 0}
- {"test.c" 0}
-}
-
-## ../other/test.c
-do_test clang14-dw5-dot-dot-other 5 "../other/test.c" 0 {
- "/tmp/cwd"
-} {
- {"../other/test.c" 0}
-}
-
-## /tmp/other/test.c
-do_test clang14-dw5-absolute-other 5 "/tmp/other/test.c" 1 {
- "/tmp/cwd"
- "/tmp"
-} {
- {"/tmp/other/test.c" 0}
- {"other/test.c" 1}
-}
-
-# The following tests are based on the output of `clang-14 -gdwarf-4
-# -fdebug-macro -g3 <file>` (using its built-in assembler). With -gdwarf-4,
-# clang produces a .debug_macinfo section, not a .debug_macro section. But
-# this test still creates a .debug_macro section, that's good enough for what
-# we want to test.
-
-## test.c
-do_test clang14-dw4-filename 4 "test.c" 1 {
-} {
- {"test.c" 0}
-}
-
-## ./test.c
-do_test clang14-dw4-dot-filename 4 "test.c" 1 {
- "."
-} {
- {"test.c" 1}
-}
-
-## ../cwd/test.c
-do_test clang14-dw4-dot-dot-cwd 4 "../cwd/test.c" 1 {
- "../cwd"
-} {
- {"test.c" 1}
-}
-
-## /tmp/cwd/test.c
-do_test clang14-dw4-absolute-cwd 4 "/tmp/cwd/test.c" 1 {
-} {
- {"test.c" 0}
-}
-
-## ../other/test.c
-do_test clang14-dw4-dot-dot-other 4 "../other/test.c" 1 {
- "../other"
-} {
- {"test.c" 1}
-}
-
-## /tmp/other/test.c
-do_test clang14-dw4-absolute-other 4 "/tmp/other/test.c" 1 {
- "/tmp"
-} {
- {"other/test.c" 1}
-}
-
-# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`,
-# gcc 11 paired with gas from binutils 2.34 (Ubuntu 20.04). It generates a v5
-# .debug_macro section, but a v3 .debug_line section.
-
-## test.c
-do_test gcc11-ld234-dw5-filename 3 "test.c" 1 {
-} {
- {"test.c" 0}
-}
-
-## ./test.c
-do_test gcc11-ld234-dw5-dot-filename 3 "./test.c" 1 {
- "."
-} {
- {"test.c" 1}
-}
-
-## ../cwd/test.c
-do_test gcc11-ld234-dw5-dot-dot-cwd 3 "../cwd/test.c" 1 {
- "../cwd"
-} {
- {"test.c" 1}
-}
-
-## /tmp/cwd/test.c
-do_test gcc11-ld234-dw5-absolute-cwd 3 "/tmp/cwd/test.c" 1 {
- "/tmp/cwd"
-} {
- {"test.c" 1}
-}
-
-## ../other/test.c
-do_test gcc11-ld234-dw5-dot-dot-other 3 "../other/test.c" 1 {
- "../other"
-} {
- {"test.c" 1}
-}
-
-## /tmp/other/test.c
-do_test gcc11-ld234-dw5-absolute-other 3 "/tmp/other/test.c" 1 {
- "/tmp/other"
-} {
- {"test.c" 1}
-}
diff --git a/gdb/testsuite/gdb.python/py-color.exp b/gdb/testsuite/gdb.python/py-color.exp
index 1b8e0c5..99b4689 100644
--- a/gdb/testsuite/gdb.python/py-color.exp
+++ b/gdb/testsuite/gdb.python/py-color.exp
@@ -97,3 +97,36 @@ gdb_test [concat "python print (c_red.escape_sequence (True) + " \
"\033\\\[31m\033\\\[42mred on green\033\\\[49m red on default\033\\\[39m" \
"escape sequences"
+gdb_test_multiline "Try to sub-class gdb.Color" \
+ "python" "" \
+ "class my_color(gdb.Color):" "" \
+ " def __init__(self):" "" \
+ " super().__init__('red')" "" \
+ "end" \
+ [multi_line \
+ "Python Exception <class 'TypeError'>: type 'gdb\\.Color' is not an acceptable base type" \
+ "Error occurred in Python: type 'gdb\\.Color' is not an acceptable base type"]
+
+gdb_test_multiline "Setup a color parameter and non gdb.Color object" \
+ "python" "" \
+ "class my_param(gdb.Parameter):" "" \
+ " def __init__(self):" "" \
+ " super().__init__('color-param', gdb.COMMAND_NONE, gdb.PARAM_COLOR)" "" \
+ " self.value = gdb.Color('red')" "" \
+ "color_param = my_param()" "" \
+ " " "" \
+ "class bad_type:" "" \
+ " @property" "" \
+ " def __class__(self):" "" \
+ " raise RuntimeError('__class__ error for bad_type')" "" \
+ "bad_obj = bad_type()" "" \
+ "end" ""
+
+gdb_test_no_output "python color_param.value = gdb.Color('blue')" \
+ "set color parameter to blue"
+
+gdb_test "python color_param.value = bad_obj" \
+ [multi_line \
+ "Python Exception <class 'RuntimeError'>: color argument must be a gdb\\.Color object\\." \
+ "Error occurred in Python: color argument must be a gdb\\.Color object\\."] \
+ "set color parameter to a non-color type"
diff --git a/gdb/testsuite/gdb.python/py-disasm.exp.tcl b/gdb/testsuite/gdb.python/py-disasm.exp.tcl
index 938326d..c5099ba 100644
--- a/gdb/testsuite/gdb.python/py-disasm.exp.tcl
+++ b/gdb/testsuite/gdb.python/py-disasm.exp.tcl
@@ -152,7 +152,10 @@ set test_plans \
"Buffer returned from read_memory is sized $decimal instead of the expected $decimal"]] \
[list "ResultOfWrongType" \
[make_exception_pattern "TypeError" \
- "Result is not a DisassemblerResult."]] \
+ "Result from Disassembler must be gdb.DisassemblerResult, not Blah."]] \
+ [list "ResultOfVeryWrongType" \
+ [make_exception_pattern "TypeError" \
+ "Result from Disassembler must be gdb.DisassemblerResult, not Blah."]] \
[list "ErrorCreatingTextPart_NoArgs" \
[make_exception_pattern "TypeError" \
[missing_arg_pattern "style" 1]]] \
diff --git a/gdb/testsuite/gdb.python/py-disasm.py b/gdb/testsuite/gdb.python/py-disasm.py
index 32d6aa7..9761337 100644
--- a/gdb/testsuite/gdb.python/py-disasm.py
+++ b/gdb/testsuite/gdb.python/py-disasm.py
@@ -294,6 +294,24 @@ class ResultOfWrongType(TestDisassembler):
return self.Blah(1, "ABC")
+class ResultOfVeryWrongType(TestDisassembler):
+ """Return something that is not a DisassemblerResult from disassemble
+ method. The thing returned will raise an exception if used in an
+ isinstance() call, or in PyObject_IsInstance from C++.
+ """
+
+ class Blah:
+ def __init__(self):
+ pass
+
+ @property
+ def __class__(self):
+ raise RuntimeError("error from __class__ in Blah")
+
+ def disassemble(self, info):
+ return self.Blah()
+
+
class TaggingDisassembler(TestDisassembler):
"""A simple disassembler that just tags the output."""
diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp
index 5668807..c1e3e33 100644
--- a/gdb/testsuite/gdb.python/py-frame.exp
+++ b/gdb/testsuite/gdb.python/py-frame.exp
@@ -188,6 +188,21 @@ gdb_test "python print(gdb.selected_frame().read_register(list()))" \
".*Invalid type for register.*" \
"test Frame.read_register with list"
+gdb_test_multiline "setup a bad object" \
+ "python" "" \
+ "class bad_type:" "" \
+ " def __init__ (self):" "" \
+ " pass" "" \
+ " @property" "" \
+ " def __class__(self):" "" \
+ " raise RuntimeError('error from __class in bad_type')" "" \
+ "bad_object = bad_type()" "" \
+ "end" ""
+
+gdb_test "python print(gdb.selected_frame().read_register(bad_object))" \
+ ".*Invalid type for register.*" \
+ "test Frame.read_register with bad_type object"
+
# Compile again without debug info.
gdb_exit
if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {}] } {