Fix performance regression when inferior opens many libraries (Gary Benson).
This commit is contained in:
parent
5c14ffc194
commit
6d620330a4
119
gdb-dlopen-stap-probe-1of7.patch
Normal file
119
gdb-dlopen-stap-probe-1of7.patch
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
http://sourceware.org/ml/gdb-patches/2013-05/msg00625.html
|
||||||
|
Subject: [RFA 1/7] Probes API convenience patch
|
||||||
|
|
||||||
|
|
||||||
|
--uuKVzAmB+c+zQlhu
|
||||||
|
Content-Type: text/plain; charset=us-ascii
|
||||||
|
Content-Disposition: inline
|
||||||
|
|
||||||
|
This patch exposes part of the probes API in a more convenient
|
||||||
|
way. I've included it for completeness, but it has previously
|
||||||
|
been approved:
|
||||||
|
|
||||||
|
http://www.cygwin.com/ml/gdb-patches/2012-07/msg00340.html
|
||||||
|
|
||||||
|
--uuKVzAmB+c+zQlhu
|
||||||
|
Content-Type: text/plain; charset=us-ascii
|
||||||
|
Content-Disposition: attachment; filename="rtld-probes-1-convenience.patch"
|
||||||
|
|
||||||
|
2013-05-16 Gary Benson <gbenson@redhat.com>
|
||||||
|
|
||||||
|
* probe.h (get_probe_argument_count): New declaration.
|
||||||
|
(evaluate_probe_argument): Likewise.
|
||||||
|
* probe.c (get_probe_argument_count): New function.
|
||||||
|
(evaluate_probe_argument): Likewise.
|
||||||
|
(probe_safe_evaluate_at_pc): Use the above new functions.
|
||||||
|
|
||||||
|
diff --git a/gdb/probe.h b/gdb/probe.h
|
||||||
|
index 8d44ca2..1d29b87 100644
|
||||||
|
--- a/gdb/probe.h
|
||||||
|
+++ b/gdb/probe.h
|
||||||
|
@@ -214,6 +214,16 @@ extern void info_probes_for_ops (char *arg, int from_tty,
|
||||||
|
|
||||||
|
extern struct cmd_list_element **info_probes_cmdlist_get (void);
|
||||||
|
|
||||||
|
+/* Return the argument count of the specified probe. */
|
||||||
|
+
|
||||||
|
+extern unsigned get_probe_argument_count (struct probe *probe);
|
||||||
|
+
|
||||||
|
+/* Evaluate argument N of the specified probe. N must be between 0
|
||||||
|
+ inclusive and get_probe_argument_count exclusive. */
|
||||||
|
+
|
||||||
|
+extern struct value *evaluate_probe_argument (struct probe *probe,
|
||||||
|
+ unsigned n);
|
||||||
|
+
|
||||||
|
/* A convenience function that finds a probe at the PC in FRAME and
|
||||||
|
evaluates argument N, with 0 <= N < number_of_args. If there is no
|
||||||
|
probe at that location, or if the probe does not have enough arguments,
|
||||||
|
diff --git a/gdb/probe.c b/gdb/probe.c
|
||||||
|
index 77f3b13..a61f4ea 100644
|
||||||
|
--- a/gdb/probe.c
|
||||||
|
+++ b/gdb/probe.c
|
||||||
|
@@ -608,28 +608,55 @@ info_probes_command (char *arg, int from_tty)
|
||||||
|
|
||||||
|
/* See comments in probe.h. */
|
||||||
|
|
||||||
|
+unsigned
|
||||||
|
+get_probe_argument_count (struct probe *probe)
|
||||||
|
+{
|
||||||
|
+ const struct sym_probe_fns *probe_fns;
|
||||||
|
+
|
||||||
|
+ gdb_assert (probe->objfile != NULL);
|
||||||
|
+ gdb_assert (probe->objfile->sf != NULL);
|
||||||
|
+
|
||||||
|
+ probe_fns = probe->objfile->sf->sym_probe_fns;
|
||||||
|
+
|
||||||
|
+ gdb_assert (probe_fns != NULL);
|
||||||
|
+
|
||||||
|
+ return probe_fns->sym_get_probe_argument_count (probe);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* See comments in probe.h. */
|
||||||
|
+
|
||||||
|
+struct value *
|
||||||
|
+evaluate_probe_argument (struct probe *probe, unsigned n)
|
||||||
|
+{
|
||||||
|
+ const struct sym_probe_fns *probe_fns;
|
||||||
|
+
|
||||||
|
+ gdb_assert (probe->objfile != NULL);
|
||||||
|
+ gdb_assert (probe->objfile->sf != NULL);
|
||||||
|
+
|
||||||
|
+ probe_fns = probe->objfile->sf->sym_probe_fns;
|
||||||
|
+
|
||||||
|
+ gdb_assert (probe_fns != NULL);
|
||||||
|
+
|
||||||
|
+ return probe_fns->sym_evaluate_probe_argument (probe, n);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* See comments in probe.h. */
|
||||||
|
+
|
||||||
|
struct value *
|
||||||
|
probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
|
||||||
|
{
|
||||||
|
struct probe *probe;
|
||||||
|
- const struct sym_probe_fns *probe_fns;
|
||||||
|
unsigned n_args;
|
||||||
|
|
||||||
|
probe = find_probe_by_pc (get_frame_pc (frame));
|
||||||
|
if (!probe)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- gdb_assert (probe->objfile != NULL);
|
||||||
|
- gdb_assert (probe->objfile->sf != NULL);
|
||||||
|
- gdb_assert (probe->objfile->sf->sym_probe_fns != NULL);
|
||||||
|
-
|
||||||
|
- probe_fns = probe->objfile->sf->sym_probe_fns;
|
||||||
|
- n_args = probe_fns->sym_get_probe_argument_count (probe);
|
||||||
|
-
|
||||||
|
+ n_args = get_probe_argument_count (probe);
|
||||||
|
if (n >= n_args)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- return probe_fns->sym_evaluate_probe_argument (probe, n);
|
||||||
|
+ return evaluate_probe_argument (probe, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See comment in probe.h. */
|
||||||
|
|
||||||
|
--uuKVzAmB+c+zQlhu--
|
||||||
|
|
198
gdb-dlopen-stap-probe-2of7.patch
Normal file
198
gdb-dlopen-stap-probe-2of7.patch
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
http://sourceware.org/ml/gdb-patches/2013-05/msg00627.html
|
||||||
|
Subject: [RFA 2/7] API for inhibiting section map updates
|
||||||
|
|
||||||
|
|
||||||
|
--bPg9NdpM9EETxvqt
|
||||||
|
Content-Type: text/plain; charset=us-ascii
|
||||||
|
Content-Disposition: inline
|
||||||
|
|
||||||
|
This patch adds a couple of functions to allow section map updates
|
||||||
|
to be temporarily inhibited. Without this ability, the calls to
|
||||||
|
evaluate_probe_argument in svr4_handle_solib_event trigger a section
|
||||||
|
map update every time a group of shared objects are mapped, which
|
||||||
|
significantly affects performance. The updates are unnecessary in
|
||||||
|
this case as the sections in question are in the runtime linker and
|
||||||
|
so already in the section map.
|
||||||
|
|
||||||
|
--bPg9NdpM9EETxvqt
|
||||||
|
Content-Type: text/plain; charset=us-ascii
|
||||||
|
Content-Disposition: attachment; filename="rtld-probes-2-inhibit-sm-updates.patch"
|
||||||
|
|
||||||
|
2013-05-16 Gary Benson <gbenson@redhat.com>
|
||||||
|
|
||||||
|
* objfiles.h (inhibit_section_map_updates): New function
|
||||||
|
declaration.
|
||||||
|
(resume_section_map_updates): Likewise.
|
||||||
|
(resume_section_map_updates_cleanup): Likewise.
|
||||||
|
* objfiles.c (objfile_pspace_info): Removed field
|
||||||
|
"objfiles_changed_p". New fields "new_objfiles_available",
|
||||||
|
"section_map_dirty" and "inhibit_updates".
|
||||||
|
(allocate_objfile): Set new_objfiles_available.
|
||||||
|
(free_objfile): Set section_map_dirty.
|
||||||
|
(objfile_relocate1): Likewise.
|
||||||
|
(in_plt_section): Likewise.
|
||||||
|
(find_pc_section): Update the conditions under which the
|
||||||
|
section map will be updated.
|
||||||
|
(inhibit_section_map_updates): New function.
|
||||||
|
(resume_section_map_updates): Likewise.
|
||||||
|
(resume_section_map_updates_cleanup): Likewise.
|
||||||
|
|
||||||
|
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
|
||||||
|
index 93149e2..0b7eea9 100644
|
||||||
|
--- a/gdb/objfiles.h
|
||||||
|
+++ b/gdb/objfiles.h
|
||||||
|
@@ -501,6 +501,22 @@ extern int in_plt_section (CORE_ADDR, char *);
|
||||||
|
modules. */
|
||||||
|
DECLARE_REGISTRY(objfile);
|
||||||
|
|
||||||
|
+/* In normal use, the section map will be rebuilt by FIND_PC_SECTION
|
||||||
|
+ if objfiles have been added, removed or relocated since it was last
|
||||||
|
+ called. Calling INHIBIT_SECTION_MAP_UPDATES will inhibit this
|
||||||
|
+ behavior until RESUME_SECTION_MAP_UPDATES is called. If you call
|
||||||
|
+ INHIBIT_SECTION_MAP_UPDATES you must ensure that every call to
|
||||||
|
+ FIND_PC_SECTION in the inhibited region relates to a section that
|
||||||
|
+ is already in the section map and has not since been removed or
|
||||||
|
+ relocated. */
|
||||||
|
+extern void inhibit_section_map_updates (void);
|
||||||
|
+
|
||||||
|
+/* Resume automatically rebuilding the section map as required. */
|
||||||
|
+extern void resume_section_map_updates (void);
|
||||||
|
+
|
||||||
|
+/* Version of the above suitable for use as a cleanup. */
|
||||||
|
+extern void resume_section_map_updates_cleanup (void *arg);
|
||||||
|
+
|
||||||
|
extern void default_iterate_over_objfiles_in_search_order
|
||||||
|
(struct gdbarch *gdbarch,
|
||||||
|
iterate_over_objfiles_in_search_order_cb_ftype *cb,
|
||||||
|
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
|
||||||
|
index 3e49ea2..3af1064 100644
|
||||||
|
--- a/gdb/objfiles.c
|
||||||
|
+++ b/gdb/objfiles.c
|
||||||
|
@@ -67,9 +67,18 @@ struct objfile *rt_common_objfile; /* For runtime common symbols */
|
||||||
|
|
||||||
|
struct objfile_pspace_info
|
||||||
|
{
|
||||||
|
- int objfiles_changed_p;
|
||||||
|
struct obj_section **sections;
|
||||||
|
int num_sections;
|
||||||
|
+
|
||||||
|
+ /* Nonzero if object files have been added since the section map
|
||||||
|
+ was last updated. */
|
||||||
|
+ int new_objfiles_available;
|
||||||
|
+
|
||||||
|
+ /* Nonzero if the section map MUST be updated before use. */
|
||||||
|
+ int section_map_dirty;
|
||||||
|
+
|
||||||
|
+ /* Nonzero if section map updates should be inhibited if possible. */
|
||||||
|
+ int inhibit_updates;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Per-program-space data key. */
|
||||||
|
@@ -317,7 +326,7 @@ allocate_objfile (bfd *abfd, int flags)
|
||||||
|
objfile->flags |= flags;
|
||||||
|
|
||||||
|
/* Rebuild section map next time we need it. */
|
||||||
|
- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
|
||||||
|
+ get_objfile_pspace_data (objfile->pspace)->new_objfiles_available = 1;
|
||||||
|
|
||||||
|
return objfile;
|
||||||
|
}
|
||||||
|
@@ -646,7 +655,7 @@ free_objfile (struct objfile *objfile)
|
||||||
|
obstack_free (&objfile->objfile_obstack, 0);
|
||||||
|
|
||||||
|
/* Rebuild section map next time we need it. */
|
||||||
|
- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
|
||||||
|
+ get_objfile_pspace_data (objfile->pspace)->section_map_dirty = 1;
|
||||||
|
|
||||||
|
xfree (objfile);
|
||||||
|
}
|
||||||
|
@@ -826,7 +835,7 @@ objfile_relocate1 (struct objfile *objfile,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rebuild section map next time we need it. */
|
||||||
|
- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
|
||||||
|
+ get_objfile_pspace_data (objfile->pspace)->section_map_dirty = 1;
|
||||||
|
|
||||||
|
/* Update the table in exec_ops, used to read memory. */
|
||||||
|
ALL_OBJFILE_OSECTIONS (objfile, s)
|
||||||
|
@@ -1291,11 +1300,14 @@ static void
|
||||||
|
update_section_map (struct program_space *pspace,
|
||||||
|
struct obj_section ***pmap, int *pmap_size)
|
||||||
|
{
|
||||||
|
+ struct objfile_pspace_info *pspace_info;
|
||||||
|
int alloc_size, map_size, i;
|
||||||
|
struct obj_section *s, **map;
|
||||||
|
struct objfile *objfile;
|
||||||
|
|
||||||
|
- gdb_assert (get_objfile_pspace_data (pspace)->objfiles_changed_p != 0);
|
||||||
|
+ pspace_info = get_objfile_pspace_data (current_program_space);
|
||||||
|
+ gdb_assert (pspace_info->section_map_dirty != 0
|
||||||
|
+ || pspace_info->new_objfiles_available != 0);
|
||||||
|
|
||||||
|
map = *pmap;
|
||||||
|
xfree (map);
|
||||||
|
@@ -1365,7 +1377,9 @@ find_pc_section (CORE_ADDR pc)
|
||||||
|
return s;
|
||||||
|
|
||||||
|
pspace_info = get_objfile_pspace_data (current_program_space);
|
||||||
|
- if (pspace_info->objfiles_changed_p != 0)
|
||||||
|
+ if (pspace_info->section_map_dirty
|
||||||
|
+ || (pspace_info->new_objfiles_available
|
||||||
|
+ && !pspace_info->inhibit_updates))
|
||||||
|
{
|
||||||
|
update_section_map (current_program_space,
|
||||||
|
&pspace_info->sections,
|
||||||
|
@@ -1373,7 +1387,8 @@ find_pc_section (CORE_ADDR pc)
|
||||||
|
|
||||||
|
/* Don't need updates to section map until objfiles are added,
|
||||||
|
removed or relocated. */
|
||||||
|
- pspace_info->objfiles_changed_p = 0;
|
||||||
|
+ pspace_info->new_objfiles_available = 0;
|
||||||
|
+ pspace_info->section_map_dirty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The C standard (ISO/IEC 9899:TC2) requires the BASE argument to
|
||||||
|
@@ -1414,14 +1429,38 @@ in_plt_section (CORE_ADDR pc, char *name)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-/* Set objfiles_changed_p so section map will be rebuilt next time it
|
||||||
|
+/* Set section_map_dirty so section map will be rebuilt next time it
|
||||||
|
is used. Called by reread_symbols. */
|
||||||
|
|
||||||
|
void
|
||||||
|
objfiles_changed (void)
|
||||||
|
{
|
||||||
|
/* Rebuild section map next time we need it. */
|
||||||
|
- get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1;
|
||||||
|
+ get_objfile_pspace_data (current_program_space)->section_map_dirty = 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* See comments in objfiles.h. */
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+inhibit_section_map_updates (void)
|
||||||
|
+{
|
||||||
|
+ get_objfile_pspace_data (current_program_space)->inhibit_updates = 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* See comments in objfiles.h. */
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+resume_section_map_updates (void)
|
||||||
|
+{
|
||||||
|
+ get_objfile_pspace_data (current_program_space)->inhibit_updates = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* See comments in objfiles.h. */
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+resume_section_map_updates_cleanup (void *arg)
|
||||||
|
+{
|
||||||
|
+ resume_section_map_updates ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The default implementation for the "iterate_over_objfiles_in_search_order"
|
||||||
|
|
||||||
|
--bPg9NdpM9EETxvqt--
|
||||||
|
|
@ -1,98 +1,314 @@
|
|||||||
2012-07-19 Gary Benson <gbenson@redhat.com>
|
http://sourceware.org/ml/gdb-patches/2013-05/msg00626.html
|
||||||
|
Subject: [RFA 3/7] New gdbserver functionality
|
||||||
|
|
||||||
* probe.h (get_probe_argument_count): New declaration.
|
|
||||||
(evaluate_probe_argument): Likewise.
|
|
||||||
* probe.c (get_probe_argument_count): New function.
|
|
||||||
(evaluate_probe_argument): Likewise.
|
|
||||||
(probe_safe_evaluate_at_pc): Use the above new functions.
|
|
||||||
|
|
||||||
diff --git a/gdb/probe.h b/gdb/probe.h
|
--Kc9HNjpzOXVc7FFU
|
||||||
index 8d44ca2..1d29b87 100644
|
Content-Type: text/plain; charset=us-ascii
|
||||||
--- a/gdb/probe.h
|
Content-Disposition: inline
|
||||||
+++ b/gdb/probe.h
|
|
||||||
@@ -214,6 +214,16 @@ extern void info_probes_for_ops (char *arg, int from_tty,
|
|
||||||
|
|
||||||
extern struct cmd_list_element **info_probes_cmdlist_get (void);
|
This patch updates gdbserver to allow arguments to be passed in the
|
||||||
|
annex of qXfer:libraries-svr4:read to allow that function to transfer
|
||||||
|
partial lists of libraries. The ability of gdbserver to support
|
||||||
|
these arguments is indicated by a qSupported response containing
|
||||||
|
"augmented-libraries-svr4-read+".
|
||||||
|
|
||||||
+/* Return the argument count of the specified probe. */
|
--Kc9HNjpzOXVc7FFU
|
||||||
+
|
Content-Type: text/plain; charset=us-ascii
|
||||||
+extern unsigned get_probe_argument_count (struct probe *probe);
|
Content-Disposition: attachment; filename="rtld-probes-3-gdbserver.patch"
|
||||||
+
|
|
||||||
+/* Evaluate argument N of the specified probe. N must be between 0
|
|
||||||
+ inclusive and get_probe_argument_count exclusive. */
|
|
||||||
+
|
|
||||||
+extern struct value *evaluate_probe_argument (struct probe *probe,
|
|
||||||
+ unsigned n);
|
|
||||||
+
|
|
||||||
/* A convenience function that finds a probe at the PC in FRAME and
|
|
||||||
evaluates argument N, with 0 <= N < number_of_args. If there is no
|
|
||||||
probe at that location, or if the probe does not have enough arguments,
|
|
||||||
diff --git a/gdb/probe.c b/gdb/probe.c
|
|
||||||
index 77f3b13..a61f4ea 100644
|
|
||||||
--- a/gdb/probe.c
|
|
||||||
+++ b/gdb/probe.c
|
|
||||||
@@ -632,28 +632,55 @@ info_probes_command (char *arg, int from_tty)
|
|
||||||
|
|
||||||
/* See comments in probe.h. */
|
2013-05-16 Gary Benson <gbenson@redhat.com>
|
||||||
|
|
||||||
+unsigned
|
* server.c (handle_query): Add "augmented-libraries-svr4-read+"
|
||||||
+get_probe_argument_count (struct probe *probe)
|
to qSupported response when appropriate.
|
||||||
+{
|
(handle_qxfer_libraries_svr4): Allow qXfer:libraries-svr4:read
|
||||||
+ const struct sym_probe_fns *probe_fns;
|
with nonzero-length annex.
|
||||||
+
|
* linux-low.c (linux_qxfer_libraries_svr4): Parse and handle
|
||||||
+ gdb_assert (probe->objfile != NULL);
|
arguments supplied in annex.
|
||||||
+ gdb_assert (probe->objfile->sf != NULL);
|
|
||||||
+
|
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
|
||||||
+ probe_fns = probe->objfile->sf->sym_probe_fns;
|
index 6bb36d8..0a8f68b 100644
|
||||||
+
|
--- a/gdb/gdbserver/server.c
|
||||||
+ gdb_assert (probe_fns != NULL);
|
+++ b/gdb/gdbserver/server.c
|
||||||
+
|
@@ -1115,8 +1115,7 @@ handle_qxfer_libraries_svr4 (const char *annex,
|
||||||
+ return probe_fns->sym_get_probe_argument_count (probe);
|
if (writebuf != NULL)
|
||||||
+}
|
return -2;
|
||||||
+
|
|
||||||
+/* See comments in probe.h. */
|
- if (annex[0] != '\0' || !target_running ()
|
||||||
+
|
- || the_target->qxfer_libraries_svr4 == NULL)
|
||||||
+struct value *
|
+ if (!target_running () || the_target->qxfer_libraries_svr4 == NULL)
|
||||||
+evaluate_probe_argument (struct probe *probe, unsigned n)
|
return -1;
|
||||||
+{
|
|
||||||
+ const struct sym_probe_fns *probe_fns;
|
return the_target->qxfer_libraries_svr4 (annex, readbuf, writebuf, offset, len);
|
||||||
+
|
@@ -1743,7 +1742,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
|
||||||
+ gdb_assert (probe->objfile != NULL);
|
PBUFSIZ - 1);
|
||||||
+ gdb_assert (probe->objfile->sf != NULL);
|
|
||||||
+
|
if (the_target->qxfer_libraries_svr4 != NULL)
|
||||||
+ probe_fns = probe->objfile->sf->sym_probe_fns;
|
- strcat (own_buf, ";qXfer:libraries-svr4:read+");
|
||||||
+
|
+ strcat (own_buf, ";qXfer:libraries-svr4:read+"
|
||||||
+ gdb_assert (probe_fns != NULL);
|
+ ";augmented-libraries-svr4-read+");
|
||||||
+
|
else
|
||||||
+ return probe_fns->sym_evaluate_probe_argument (probe, n);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* See comments in probe.h. */
|
|
||||||
+
|
|
||||||
struct value *
|
|
||||||
probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
|
|
||||||
{
|
{
|
||||||
struct probe *probe;
|
/* We do not have any hook to indicate whether the non-SVR4 target
|
||||||
- const struct sym_probe_fns *probe_fns;
|
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
|
||||||
unsigned n_args;
|
index 72c51e0..beb3b8f 100644
|
||||||
|
--- a/gdb/gdbserver/linux-low.c
|
||||||
|
+++ b/gdb/gdbserver/linux-low.c
|
||||||
|
@@ -5677,6 +5677,12 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
|
||||||
|
};
|
||||||
|
const struct link_map_offsets *lmo;
|
||||||
|
unsigned int machine;
|
||||||
|
+ int ptr_size;
|
||||||
|
+ CORE_ADDR lm_addr = 0, lm_prev = 0;
|
||||||
|
+ int allocated = 1024;
|
||||||
|
+ char *p;
|
||||||
|
+ CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
|
||||||
|
+ int header_done = 0;
|
||||||
|
|
||||||
probe = find_probe_by_pc (get_frame_pc (frame));
|
if (writebuf != NULL)
|
||||||
if (!probe)
|
return -2;
|
||||||
return NULL;
|
@@ -5687,128 +5693,146 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
|
||||||
|
xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
|
||||||
|
is_elf64 = elf_64_file_p (filename, &machine);
|
||||||
|
lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
|
||||||
|
+ ptr_size = is_elf64 ? 8 : 4;
|
||||||
|
|
||||||
- gdb_assert (probe->objfile != NULL);
|
- if (priv->r_debug == 0)
|
||||||
- gdb_assert (probe->objfile->sf != NULL);
|
- priv->r_debug = get_r_debug (pid, is_elf64);
|
||||||
- gdb_assert (probe->objfile->sf->sym_probe_fns != NULL);
|
+ if (annex[0] == '\0')
|
||||||
|
+ {
|
||||||
|
+ int r_version = 0;
|
||||||
|
|
||||||
|
- /* We failed to find DT_DEBUG. Such situation will not change for this
|
||||||
|
- inferior - do not retry it. Report it to GDB as E01, see for the reasons
|
||||||
|
- at the GDB solib-svr4.c side. */
|
||||||
|
- if (priv->r_debug == (CORE_ADDR) -1)
|
||||||
|
- return -1;
|
||||||
|
+ if (priv->r_debug == 0)
|
||||||
|
+ priv->r_debug = get_r_debug (pid, is_elf64);
|
||||||
|
|
||||||
|
- if (priv->r_debug == 0)
|
||||||
|
- {
|
||||||
|
- document = xstrdup ("<library-list-svr4 version=\"1.0\"/>\n");
|
||||||
|
+ /* We failed to find DT_DEBUG. Such situation will not change
|
||||||
|
+ for this inferior - do not retry it. Report it to GDB as
|
||||||
|
+ E01, see for the reasons at the GDB solib-svr4.c side. */
|
||||||
|
+ if (priv->r_debug == (CORE_ADDR) -1)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ if (priv->r_debug != 0)
|
||||||
|
+ {
|
||||||
|
+ if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
|
||||||
|
+ (unsigned char *) &r_version,
|
||||||
|
+ sizeof (r_version)) != 0
|
||||||
|
+ || r_version != 1)
|
||||||
|
+ {
|
||||||
|
+ warning ("unexpected r_debug version %d", r_version);
|
||||||
|
+ }
|
||||||
|
+ else if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
|
||||||
|
+ &lm_addr, ptr_size) != 0)
|
||||||
|
+ {
|
||||||
|
+ warning ("unable to read r_map from 0x%lx",
|
||||||
|
+ (long) priv->r_debug + lmo->r_map_offset);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- int allocated = 1024;
|
||||||
|
- char *p;
|
||||||
|
- const int ptr_size = is_elf64 ? 8 : 4;
|
||||||
|
- CORE_ADDR lm_addr, lm_prev, l_name, l_addr, l_ld, l_next, l_prev;
|
||||||
|
- int r_version, header_done = 0;
|
||||||
-
|
-
|
||||||
- probe_fns = probe->objfile->sf->sym_probe_fns;
|
- document = xmalloc (allocated);
|
||||||
- n_args = probe_fns->sym_get_probe_argument_count (probe);
|
- strcpy (document, "<library-list-svr4 version=\"1.0\"");
|
||||||
|
- p = document + strlen (document);
|
||||||
-
|
-
|
||||||
+ n_args = get_probe_argument_count (probe);
|
- r_version = 0;
|
||||||
if (n >= n_args)
|
- if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
|
||||||
return NULL;
|
- (unsigned char *) &r_version,
|
||||||
|
- sizeof (r_version)) != 0
|
||||||
|
- || r_version != 1)
|
||||||
|
+ while (annex[0] != '\0')
|
||||||
|
{
|
||||||
|
- warning ("unexpected r_debug version %d", r_version);
|
||||||
|
- goto done;
|
||||||
|
+ const char *sep;
|
||||||
|
+ CORE_ADDR *addrp;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ sep = strchr (annex, '=');
|
||||||
|
+ if (!sep)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ len = sep - annex;
|
||||||
|
+ if (len == 5 && !strncmp (annex, "start", 5))
|
||||||
|
+ addrp = &lm_addr;
|
||||||
|
+ else if (len == 4 && !strncmp (annex, "prev", 4))
|
||||||
|
+ addrp = &lm_prev;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ annex = strchr (sep, ';');
|
||||||
|
+ if (!annex)
|
||||||
|
+ break;
|
||||||
|
+ annex++;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ annex = decode_address_to_semicolon (addrp, sep + 1);
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
|
||||||
- return probe_fns->sym_evaluate_probe_argument (probe, n);
|
- if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
|
||||||
+ return evaluate_probe_argument (probe, n);
|
- &lm_addr, ptr_size) != 0)
|
||||||
|
+ document = xmalloc (allocated);
|
||||||
|
+ strcpy (document, "<library-list-svr4 version=\"1.0\"");
|
||||||
|
+ p = document + strlen (document);
|
||||||
|
+
|
||||||
|
+ while (lm_addr
|
||||||
|
+ && read_one_ptr (lm_addr + lmo->l_name_offset,
|
||||||
|
+ &l_name, ptr_size) == 0
|
||||||
|
+ && read_one_ptr (lm_addr + lmo->l_addr_offset,
|
||||||
|
+ &l_addr, ptr_size) == 0
|
||||||
|
+ && read_one_ptr (lm_addr + lmo->l_ld_offset,
|
||||||
|
+ &l_ld, ptr_size) == 0
|
||||||
|
+ && read_one_ptr (lm_addr + lmo->l_prev_offset,
|
||||||
|
+ &l_prev, ptr_size) == 0
|
||||||
|
+ && read_one_ptr (lm_addr + lmo->l_next_offset,
|
||||||
|
+ &l_next, ptr_size) == 0)
|
||||||
|
+ {
|
||||||
|
+ unsigned char libname[PATH_MAX];
|
||||||
|
+
|
||||||
|
+ if (lm_prev != l_prev)
|
||||||
|
{
|
||||||
|
- warning ("unable to read r_map from 0x%lx",
|
||||||
|
- (long) priv->r_debug + lmo->r_map_offset);
|
||||||
|
- goto done;
|
||||||
|
+ warning ("Corrupted shared library list: 0x%lx != 0x%lx",
|
||||||
|
+ (long) lm_prev, (long) l_prev);
|
||||||
|
+ break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See comment in probe.h. */
|
- lm_prev = 0;
|
||||||
|
- while (read_one_ptr (lm_addr + lmo->l_name_offset,
|
||||||
|
- &l_name, ptr_size) == 0
|
||||||
|
- && read_one_ptr (lm_addr + lmo->l_addr_offset,
|
||||||
|
- &l_addr, ptr_size) == 0
|
||||||
|
- && read_one_ptr (lm_addr + lmo->l_ld_offset,
|
||||||
|
- &l_ld, ptr_size) == 0
|
||||||
|
- && read_one_ptr (lm_addr + lmo->l_prev_offset,
|
||||||
|
- &l_prev, ptr_size) == 0
|
||||||
|
- && read_one_ptr (lm_addr + lmo->l_next_offset,
|
||||||
|
- &l_next, ptr_size) == 0)
|
||||||
|
+ /* Not checking for error because reading may stop before
|
||||||
|
+ we've got PATH_MAX worth of characters. */
|
||||||
|
+ libname[0] = '\0';
|
||||||
|
+ linux_read_memory (l_name, libname, sizeof (libname) - 1);
|
||||||
|
+ libname[sizeof (libname) - 1] = '\0';
|
||||||
|
+ if (libname[0] != '\0')
|
||||||
|
{
|
||||||
|
- unsigned char libname[PATH_MAX];
|
||||||
|
+ /* 6x the size for xml_escape_text below. */
|
||||||
|
+ size_t len = 6 * strlen ((char *) libname);
|
||||||
|
+ char *name;
|
||||||
|
|
||||||
|
- if (lm_prev != l_prev)
|
||||||
|
+ if (!header_done)
|
||||||
|
{
|
||||||
|
- warning ("Corrupted shared library list: 0x%lx != 0x%lx",
|
||||||
|
- (long) lm_prev, (long) l_prev);
|
||||||
|
- break;
|
||||||
|
+ /* Terminate `<library-list-svr4'. */
|
||||||
|
+ *p++ = '>';
|
||||||
|
+ header_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Not checking for error because reading may stop before
|
||||||
|
- we've got PATH_MAX worth of characters. */
|
||||||
|
- libname[0] = '\0';
|
||||||
|
- linux_read_memory (l_name, libname, sizeof (libname) - 1);
|
||||||
|
- libname[sizeof (libname) - 1] = '\0';
|
||||||
|
- if (libname[0] != '\0')
|
||||||
|
+ while (allocated < p - document + len + 200)
|
||||||
|
{
|
||||||
|
- /* 6x the size for xml_escape_text below. */
|
||||||
|
- size_t len = 6 * strlen ((char *) libname);
|
||||||
|
- char *name;
|
||||||
|
-
|
||||||
|
- if (!header_done)
|
||||||
|
- {
|
||||||
|
- /* Terminate `<library-list-svr4'. */
|
||||||
|
- *p++ = '>';
|
||||||
|
- header_done = 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- while (allocated < p - document + len + 200)
|
||||||
|
- {
|
||||||
|
- /* Expand to guarantee sufficient storage. */
|
||||||
|
- uintptr_t document_len = p - document;
|
||||||
|
-
|
||||||
|
- document = xrealloc (document, 2 * allocated);
|
||||||
|
- allocated *= 2;
|
||||||
|
- p = document + document_len;
|
||||||
|
- }
|
||||||
|
+ /* Expand to guarantee sufficient storage. */
|
||||||
|
+ uintptr_t document_len = p - document;
|
||||||
|
|
||||||
|
- name = xml_escape_text ((char *) libname);
|
||||||
|
- p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
|
||||||
|
- "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
|
||||||
|
- name, (unsigned long) lm_addr,
|
||||||
|
- (unsigned long) l_addr, (unsigned long) l_ld);
|
||||||
|
- free (name);
|
||||||
|
- }
|
||||||
|
- else if (lm_prev == 0)
|
||||||
|
- {
|
||||||
|
- sprintf (p, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
|
||||||
|
- p = p + strlen (p);
|
||||||
|
+ document = xrealloc (document, 2 * allocated);
|
||||||
|
+ allocated *= 2;
|
||||||
|
+ p = document + document_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (l_next == 0)
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- lm_prev = lm_addr;
|
||||||
|
- lm_addr = l_next;
|
||||||
|
+ name = xml_escape_text ((char *) libname);
|
||||||
|
+ p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
|
||||||
|
+ "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
|
||||||
|
+ name, (unsigned long) lm_addr,
|
||||||
|
+ (unsigned long) l_addr, (unsigned long) l_ld);
|
||||||
|
+ free (name);
|
||||||
|
}
|
||||||
|
- done:
|
||||||
|
- if (!header_done)
|
||||||
|
+ else if (lm_prev == 0)
|
||||||
|
{
|
||||||
|
- /* Empty list; terminate `<library-list-svr4'. */
|
||||||
|
- strcpy (p, "/>");
|
||||||
|
+ sprintf (p, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
|
||||||
|
+ p = p + strlen (p);
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- strcpy (p, "</library-list-svr4>");
|
||||||
|
+
|
||||||
|
+ lm_prev = lm_addr;
|
||||||
|
+ lm_addr = l_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!header_done)
|
||||||
|
+ {
|
||||||
|
+ /* Empty list; terminate `<library-list-svr4'. */
|
||||||
|
+ strcpy (p, "/>");
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ strcpy (p, "</library-list-svr4>");
|
||||||
|
+
|
||||||
|
document_len = strlen (document);
|
||||||
|
if (offset < document_len)
|
||||||
|
document_len -= offset;
|
||||||
|
|
||||||
|
--Kc9HNjpzOXVc7FFU--
|
||||||
|
|
||||||
|
@ -1,131 +1,146 @@
|
|||||||
2012-07-19 Gary Benson <gbenson@redhat.com>
|
http://sourceware.org/ml/gdb-patches/2013-05/msg00628.html
|
||||||
|
Subject: [RFA 4/7] GDB support for new gdbserver functionality
|
||||||
|
|
||||||
* solib-svr4.c (svr4_info): Move earlier.
|
|
||||||
(solib_svr4_pspace_data): Likewise.
|
|
||||||
(svr4_pspace_data_cleanup): Likewise.
|
|
||||||
(get_svr4_info): Likewise.
|
|
||||||
|
|
||||||
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
|
--CaPKgh3XHpq3rEUV
|
||||||
index 307e483..c88b9cb 100644
|
Content-Type: text/plain; charset=us-ascii
|
||||||
--- a/gdb/solib-svr4.c
|
Content-Disposition: inline
|
||||||
+++ b/gdb/solib-svr4.c
|
|
||||||
@@ -106,6 +106,59 @@ static const char * const main_name_list[] =
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
+/* Per pspace SVR4 specific data. */
|
This patch adds client support for the new gdbserver functionality
|
||||||
+
|
provided by patch 3 of this series.
|
||||||
+struct svr4_info
|
|
||||||
+{
|
|
||||||
+ CORE_ADDR debug_base; /* Base of dynamic linker structures. */
|
|
||||||
+
|
|
||||||
+ /* Validity flag for debug_loader_offset. */
|
|
||||||
+ int debug_loader_offset_p;
|
|
||||||
+
|
|
||||||
+ /* Load address for the dynamic linker, inferred. */
|
|
||||||
+ CORE_ADDR debug_loader_offset;
|
|
||||||
+
|
|
||||||
+ /* Name of the dynamic linker, valid if debug_loader_offset_p. */
|
|
||||||
+ char *debug_loader_name;
|
|
||||||
+
|
|
||||||
+ /* Load map address for the main executable. */
|
|
||||||
+ CORE_ADDR main_lm_addr;
|
|
||||||
+
|
|
||||||
+ CORE_ADDR interp_text_sect_low;
|
|
||||||
+ CORE_ADDR interp_text_sect_high;
|
|
||||||
+ CORE_ADDR interp_plt_sect_low;
|
|
||||||
+ CORE_ADDR interp_plt_sect_high;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+/* Per-program-space data key. */
|
|
||||||
+static const struct program_space_data *solib_svr4_pspace_data;
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+svr4_pspace_data_cleanup (struct program_space *pspace, void *arg)
|
|
||||||
+{
|
|
||||||
+ struct svr4_info *info;
|
|
||||||
+
|
|
||||||
+ info = program_space_data (pspace, solib_svr4_pspace_data);
|
|
||||||
+ xfree (info);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* Get the current svr4 data. If none is found yet, add it now. This
|
|
||||||
+ function always returns a valid object. */
|
|
||||||
+
|
|
||||||
+static struct svr4_info *
|
|
||||||
+get_svr4_info (void)
|
|
||||||
+{
|
|
||||||
+ struct svr4_info *info;
|
|
||||||
+
|
|
||||||
+ info = program_space_data (current_program_space, solib_svr4_pspace_data);
|
|
||||||
+ if (info != NULL)
|
|
||||||
+ return info;
|
|
||||||
+
|
|
||||||
+ info = XZALLOC (struct svr4_info);
|
|
||||||
+ set_program_space_data (current_program_space, solib_svr4_pspace_data, info);
|
|
||||||
+ return info;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Return non-zero if GDB_SO_NAME and INFERIOR_SO_NAME represent
|
|
||||||
the same shared library. */
|
|
||||||
|
|
||||||
@@ -291,59 +344,6 @@ lm_addr_check (struct so_list *so, bfd *abfd)
|
--CaPKgh3XHpq3rEUV
|
||||||
return so->lm_info->l_addr;
|
Content-Type: text/plain; charset=us-ascii
|
||||||
|
Content-Disposition: attachment; filename="rtld-probes-4-remote.patch"
|
||||||
|
|
||||||
|
2013-05-16 Gary Benson <gbenson@redhat.com>
|
||||||
|
|
||||||
|
* target.h (target_ops): New field
|
||||||
|
"to_augmented_libraries_svr4_read".
|
||||||
|
(target_augmented_libraries_svr4_read): New macro.
|
||||||
|
* target.c (update_current_target): Handle
|
||||||
|
to_augmented_libraries_svr4_read.
|
||||||
|
* remote.c (remote_state): New field
|
||||||
|
"augmented_libraries_svr4_read".
|
||||||
|
(remote_augmented_libraries_svr4_read_feature): New function.
|
||||||
|
(remote_protocol_features): Add entry for
|
||||||
|
"augmented-libraries-svr4-read".
|
||||||
|
(remote_augmented_libraries_svr4_read): New function.
|
||||||
|
(init_remote_ops): Initialize
|
||||||
|
remote_ops.to_augmented_libraries_svr4_read.
|
||||||
|
|
||||||
|
diff --git a/gdb/target.h b/gdb/target.h
|
||||||
|
index e937d39..a8587e8 100644
|
||||||
|
--- a/gdb/target.h
|
||||||
|
+++ b/gdb/target.h
|
||||||
|
@@ -941,6 +941,10 @@ struct target_ops
|
||||||
|
(inclusive) to function END (exclusive). */
|
||||||
|
void (*to_call_history_range) (ULONGEST begin, ULONGEST end, int flags);
|
||||||
|
|
||||||
|
+ /* Nonzero if TARGET_OBJECT_LIBRARIES_SVR4 may be read with a
|
||||||
|
+ non-empty annex. */
|
||||||
|
+ int (*to_augmented_libraries_svr4_read) (void);
|
||||||
|
+
|
||||||
|
int to_magic;
|
||||||
|
/* Need sub-structure for target machine related rather than comm related?
|
||||||
|
*/
|
||||||
|
@@ -1809,6 +1813,9 @@ extern char *target_fileio_read_stralloc (const char *filename);
|
||||||
|
#define target_can_use_agent() \
|
||||||
|
(*current_target.to_can_use_agent) ()
|
||||||
|
|
||||||
|
+#define target_augmented_libraries_svr4_read() \
|
||||||
|
+ (*current_target.to_augmented_libraries_svr4_read) ()
|
||||||
|
+
|
||||||
|
/* Command logging facility. */
|
||||||
|
|
||||||
|
#define target_log_command(p) \
|
||||||
|
diff --git a/gdb/target.c b/gdb/target.c
|
||||||
|
index 8653dac..519b97f 100644
|
||||||
|
--- a/gdb/target.c
|
||||||
|
+++ b/gdb/target.c
|
||||||
|
@@ -731,6 +731,7 @@ update_current_target (void)
|
||||||
|
INHERIT (to_traceframe_info, t);
|
||||||
|
INHERIT (to_use_agent, t);
|
||||||
|
INHERIT (to_can_use_agent, t);
|
||||||
|
+ INHERIT (to_augmented_libraries_svr4_read, t);
|
||||||
|
INHERIT (to_magic, t);
|
||||||
|
INHERIT (to_supports_evaluation_of_breakpoint_conditions, t);
|
||||||
|
INHERIT (to_can_run_breakpoint_commands, t);
|
||||||
|
@@ -975,6 +976,9 @@ update_current_target (void)
|
||||||
|
de_fault (to_can_use_agent,
|
||||||
|
(int (*) (void))
|
||||||
|
return_zero);
|
||||||
|
+ de_fault (to_augmented_libraries_svr4_read,
|
||||||
|
+ (int (*) (void))
|
||||||
|
+ return_zero);
|
||||||
|
de_fault (to_execution_direction, default_execution_direction);
|
||||||
|
|
||||||
|
#undef de_fault
|
||||||
|
diff --git a/gdb/remote.c b/gdb/remote.c
|
||||||
|
index 51bf025..e1cf8a4 100644
|
||||||
|
--- a/gdb/remote.c
|
||||||
|
+++ b/gdb/remote.c
|
||||||
|
@@ -343,6 +343,10 @@ struct remote_state
|
||||||
|
/* True if the stub can collect strings using tracenz bytecode. */
|
||||||
|
int string_tracing;
|
||||||
|
|
||||||
|
+ /* True if the stub supports qXfer:libraries-svr4:read with a
|
||||||
|
+ non-empty annex. */
|
||||||
|
+ int augmented_libraries_svr4_read;
|
||||||
|
+
|
||||||
|
/* Nonzero if the user has pressed Ctrl-C, but the target hasn't
|
||||||
|
responded to that. */
|
||||||
|
int ctrlc_pending_p;
|
||||||
|
@@ -3931,6 +3935,16 @@ remote_string_tracing_feature (const struct protocol_feature *feature,
|
||||||
|
rs->string_tracing = (support == PACKET_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
-/* Per pspace SVR4 specific data. */
|
+static void
|
||||||
-
|
+remote_augmented_libraries_svr4_read_feature
|
||||||
-struct svr4_info
|
+ (const struct protocol_feature *feature,
|
||||||
-{
|
+ enum packet_support support, const char *value)
|
||||||
- CORE_ADDR debug_base; /* Base of dynamic linker structures. */
|
+{
|
||||||
-
|
+ struct remote_state *rs = get_remote_state ();
|
||||||
- /* Validity flag for debug_loader_offset. */
|
+
|
||||||
- int debug_loader_offset_p;
|
+ rs->augmented_libraries_svr4_read = (support == PACKET_ENABLE);
|
||||||
-
|
+}
|
||||||
- /* Load address for the dynamic linker, inferred. */
|
+
|
||||||
- CORE_ADDR debug_loader_offset;
|
static struct protocol_feature remote_protocol_features[] = {
|
||||||
-
|
{ "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
|
||||||
- /* Name of the dynamic linker, valid if debug_loader_offset_p. */
|
{ "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
|
||||||
- char *debug_loader_name;
|
@@ -3941,6 +3955,8 @@ static struct protocol_feature remote_protocol_features[] = {
|
||||||
-
|
PACKET_qXfer_libraries },
|
||||||
- /* Load map address for the main executable. */
|
{ "qXfer:libraries-svr4:read", PACKET_DISABLE, remote_supported_packet,
|
||||||
- CORE_ADDR main_lm_addr;
|
PACKET_qXfer_libraries_svr4 },
|
||||||
-
|
+ { "augmented-libraries-svr4-read", PACKET_DISABLE,
|
||||||
- CORE_ADDR interp_text_sect_low;
|
+ remote_augmented_libraries_svr4_read_feature, -1 },
|
||||||
- CORE_ADDR interp_text_sect_high;
|
{ "qXfer:memory-map:read", PACKET_DISABLE, remote_supported_packet,
|
||||||
- CORE_ADDR interp_plt_sect_low;
|
PACKET_qXfer_memory_map },
|
||||||
- CORE_ADDR interp_plt_sect_high;
|
{ "qXfer:spu:read", PACKET_DISABLE, remote_supported_packet,
|
||||||
-};
|
@@ -11343,6 +11359,14 @@ remote_read_btrace (struct btrace_target_info *tinfo,
|
||||||
-
|
return btrace;
|
||||||
-/* Per-program-space data key. */
|
}
|
||||||
-static const struct program_space_data *solib_svr4_pspace_data;
|
|
||||||
-
|
+static int
|
||||||
-static void
|
+remote_augmented_libraries_svr4_read (void)
|
||||||
-svr4_pspace_data_cleanup (struct program_space *pspace, void *arg)
|
+{
|
||||||
-{
|
+ struct remote_state *rs = get_remote_state ();
|
||||||
- struct svr4_info *info;
|
+
|
||||||
-
|
+ return rs->augmented_libraries_svr4_read;
|
||||||
- info = program_space_data (pspace, solib_svr4_pspace_data);
|
+}
|
||||||
- xfree (info);
|
+
|
||||||
-}
|
static void
|
||||||
-
|
init_remote_ops (void)
|
||||||
-/* Get the current svr4 data. If none is found yet, add it now. This
|
{
|
||||||
- function always returns a valid object. */
|
@@ -11465,6 +11489,8 @@ Specify the serial device it is connected to\n\
|
||||||
-
|
remote_ops.to_disable_btrace = remote_disable_btrace;
|
||||||
-static struct svr4_info *
|
remote_ops.to_teardown_btrace = remote_teardown_btrace;
|
||||||
-get_svr4_info (void)
|
remote_ops.to_read_btrace = remote_read_btrace;
|
||||||
-{
|
+ remote_ops.to_augmented_libraries_svr4_read =
|
||||||
- struct svr4_info *info;
|
+ remote_augmented_libraries_svr4_read;
|
||||||
-
|
}
|
||||||
- info = program_space_data (current_program_space, solib_svr4_pspace_data);
|
|
||||||
- if (info != NULL)
|
/* Set up the extended remote vector by making a copy of the standard
|
||||||
- return info;
|
|
||||||
-
|
--CaPKgh3XHpq3rEUV--
|
||||||
- info = XZALLOC (struct svr4_info);
|
|
||||||
- set_program_space_data (current_program_space, solib_svr4_pspace_data, info);
|
|
||||||
- return info;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
/* Local function prototypes */
|
|
||||||
|
|
||||||
static int match_main (const char *);
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,147 +1,435 @@
|
|||||||
2012-07-30 Gary Benson <gbenson@redhat.com>
|
http://sourceware.org/ml/gdb-patches/2013-05/msg00630.html
|
||||||
|
Subject: [RFA 7/7] Linker-debugger interface tests
|
||||||
|
|
||||||
* objfiles.h (inhibit_section_map_updates): New function
|
|
||||||
declaration.
|
|
||||||
(resume_section_map_updates): Likewise.
|
|
||||||
(resume_section_map_updates_cleanup): Likewise.
|
|
||||||
* objfiles.c (objfile_pspace_info): New field "inhibit_updates".
|
|
||||||
(find_pc_section): Do not update the section map if
|
|
||||||
inhibit_updates is set.
|
|
||||||
(inhibit_section_map_updates): New function.
|
|
||||||
(resume_section_map_updates): Likewise.
|
|
||||||
(resume_section_map_updates_cleanup): Likewise.
|
|
||||||
* solib-svr4.c (svr4_handle_solib_event): Inhibit section map
|
|
||||||
updates for calls to evaluate_probe_argument.
|
|
||||||
|
|
||||||
Index: gdb-7.5.50.20130118/gdb/objfiles.h
|
--DCA/C9WSnDtl50zu
|
||||||
===================================================================
|
Content-Type: text/plain; charset=us-ascii
|
||||||
--- gdb-7.5.50.20130118.orig/gdb/objfiles.h 2013-01-18 23:18:16.862315673 +0100
|
Content-Disposition: inline
|
||||||
+++ gdb-7.5.50.20130118/gdb/objfiles.h 2013-01-18 23:18:36.702343482 +0100
|
|
||||||
@@ -508,6 +508,22 @@ extern int in_plt_section (CORE_ADDR, ch
|
|
||||||
modules. */
|
|
||||||
DECLARE_REGISTRY(objfile);
|
|
||||||
|
|
||||||
+/* In normal use, the section map will be rebuilt by FIND_PC_SECTION
|
This patch adds some testcases for the linker-debugger interface.
|
||||||
+ if objfiles have been added, removed or relocated since it was last
|
|
||||||
+ called. Calling INHIBIT_SECTION_MAP_UPDATES will inhibit this
|
--DCA/C9WSnDtl50zu
|
||||||
+ behavior until RESUME_SECTION_MAP_UPDATES is called. If you call
|
Content-Type: text/plain; charset=us-ascii
|
||||||
+ INHIBIT_SECTION_MAP_UPDATES you must ensure that every call to
|
Content-Disposition: attachment; filename="rtld-probes-7-tests-gb.patch"
|
||||||
+ FIND_PC_SECTION in the inhibited region relates to a section that
|
|
||||||
+ is already in the section map and has not since been removed or
|
2013-05-16 Gary Benson <gbenson@redhat.com>
|
||||||
+ relocated. */
|
|
||||||
+extern void inhibit_section_map_updates (void);
|
* gdb.base/break-probes.exp: New file.
|
||||||
|
* gdb.base/break-probes.c: Likewise.
|
||||||
|
* gdb.base/break-probes-solib.c: Likewise.
|
||||||
|
* gdb.base/info-shared.exp: New file.
|
||||||
|
* gdb.base/info-shared.c: Likewise.
|
||||||
|
* gdb.base/info-shared-solib1.c: Likewise.
|
||||||
|
* gdb.base/info-shared-solib2.c: Likewise.
|
||||||
|
|
||||||
|
diff --git a/gdb/testsuite/gdb.base/break-probes.exp b/gdb/testsuite/gdb.base/break-probes.exp
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..8372636
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gdb/testsuite/gdb.base/break-probes.exp
|
||||||
|
@@ -0,0 +1,77 @@
|
||||||
|
+# Copyright 2013 Free Software Foundation, Inc.
|
||||||
+
|
+
|
||||||
+/* Resume automatically rebuilding the section map as required. */
|
+# This program is free software; you can redistribute it and/or modify
|
||||||
+extern void resume_section_map_updates (void);
|
+# 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/>.
|
||||||
+
|
+
|
||||||
+/* Version of the above suitable for use as a cleanup. */
|
+if { [skip_shlib_tests] } {
|
||||||
+extern void resume_section_map_updates_cleanup (void *arg);
|
+ return 0
|
||||||
+
|
|
||||||
extern void default_iterate_over_objfiles_in_search_order
|
|
||||||
(struct gdbarch *gdbarch,
|
|
||||||
iterate_over_objfiles_in_search_order_cb_ftype *cb,
|
|
||||||
Index: gdb-7.5.50.20130118/gdb/objfiles.c
|
|
||||||
===================================================================
|
|
||||||
--- gdb-7.5.50.20130118.orig/gdb/objfiles.c 2013-01-18 23:18:13.647311006 +0100
|
|
||||||
+++ gdb-7.5.50.20130118/gdb/objfiles.c 2013-01-18 23:18:16.862315673 +0100
|
|
||||||
@@ -69,6 +69,9 @@ struct objfile_pspace_info
|
|
||||||
int objfiles_changed_p;
|
|
||||||
struct obj_section **sections;
|
|
||||||
int num_sections;
|
|
||||||
+
|
|
||||||
+ /* Nonzero if section map updates should be inhibited. */
|
|
||||||
+ int inhibit_updates;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Per-program-space data key. */
|
|
||||||
@@ -1356,7 +1359,7 @@ find_pc_section (CORE_ADDR pc)
|
|
||||||
return s;
|
|
||||||
|
|
||||||
pspace_info = get_objfile_pspace_data (current_program_space);
|
|
||||||
- if (pspace_info->objfiles_changed_p != 0)
|
|
||||||
+ if (pspace_info->objfiles_changed_p && !pspace_info->inhibit_updates)
|
|
||||||
{
|
|
||||||
update_section_map (current_program_space,
|
|
||||||
&pspace_info->sections,
|
|
||||||
@@ -1415,6 +1418,30 @@ objfiles_changed (void)
|
|
||||||
get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* See comments in objfiles.h. */
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+inhibit_section_map_updates (void)
|
|
||||||
+{
|
|
||||||
+ get_objfile_pspace_data (current_program_space)->inhibit_updates = 1;
|
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+/* See comments in objfiles.h. */
|
+standard_testfile
|
||||||
+
|
+
|
||||||
+void
|
+set libname $testfile-solib
|
||||||
+resume_section_map_updates (void)
|
+set srcfile_lib $srcdir/$subdir/$libname.c
|
||||||
+{
|
+set binfile_lib [standard_output_file $libname.so]
|
||||||
+ get_objfile_pspace_data (current_program_space)->inhibit_updates = 0;
|
+
|
||||||
|
+set normal_bp "_dl_debug_state"
|
||||||
|
+set probes_bp "dl_main"
|
||||||
|
+
|
||||||
|
+if { [gdb_compile_shlib $srcfile_lib $binfile_lib \
|
||||||
|
+ [list additional_flags=-fPIC]] != "" } {
|
||||||
|
+ untested "Could not compile $binfile_lib."
|
||||||
|
+ return -1
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+/* See comments in objfiles.h. */
|
+if { [prepare_for_testing $testfile.exp $testfile $srcfile \
|
||||||
+
|
+ [list additional_flags=-DSHLIB_NAME\=\"$binfile_lib\" libs=-ldl]] } {
|
||||||
+void
|
+ return -1
|
||||||
+resume_section_map_updates_cleanup (void *arg)
|
|
||||||
+{
|
|
||||||
+ resume_section_map_updates ();
|
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
/* The default implementation for the "iterate_over_objfiles_in_search_order"
|
+# Enable stop-on-solib-events
|
||||||
gdbarch method. It is equivalent to use the ALL_OBJFILES macro,
|
+gdb_test_no_output "set stop-on-solib-events 1"
|
||||||
searching the objfiles in the order they are stored internally,
|
|
||||||
Index: gdb-7.5.50.20130118/gdb/solib-svr4.c
|
|
||||||
===================================================================
|
|
||||||
--- gdb-7.5.50.20130118.orig/gdb/solib-svr4.c 2013-01-18 23:18:13.649311010 +0100
|
|
||||||
+++ gdb-7.5.50.20130118/gdb/solib-svr4.c 2013-01-18 23:18:16.863315675 +0100
|
|
||||||
@@ -1849,6 +1849,7 @@ svr4_handle_solib_event (bpstat bs)
|
|
||||||
struct svr4_info *info = get_svr4_info ();
|
|
||||||
struct probe_and_info buf, *pi = &buf;
|
|
||||||
enum probe_action action;
|
|
||||||
+ struct cleanup *cleanups = NULL;
|
|
||||||
struct value *val;
|
|
||||||
LONGEST lmid;
|
|
||||||
CORE_ADDR debug_base, lm = 0;
|
|
||||||
@@ -1872,6 +1873,19 @@ svr4_handle_solib_event (bpstat bs)
|
|
||||||
if (action == NAMESPACE_NO_ACTION)
|
|
||||||
return;
|
|
||||||
|
|
||||||
+ /* EVALUATE_PROBE_ARGUMENT looks up symbols in the dynamic linker
|
|
||||||
+ using FIND_PC_SECTION. FIND_PC_SECTION is accelerated by a cache
|
|
||||||
+ called the section map. The section map is invalidated every
|
|
||||||
+ time a shared library is loaded or unloaded, and if the inferior
|
|
||||||
+ is generating a lot of shared library events then the section map
|
|
||||||
+ will be updated every time SVR4_HANDLE_SOLIB_EVENT is called.
|
|
||||||
+ We called FIND_PC_SECTION in SVR4_CREATE_SOLIB_EVENT_BREAKPOINTS,
|
|
||||||
+ so we can guarantee that the dynamic linker's sections are in the
|
|
||||||
+ section map. We can therefore inhibit section map updates across
|
|
||||||
+ these calls to EVALUATE_PROBE_ARGUMENT and save a lot of time. */
|
|
||||||
+ inhibit_section_map_updates ();
|
|
||||||
+ cleanups = make_cleanup (resume_section_map_updates_cleanup, NULL);
|
|
||||||
+
|
+
|
||||||
val = evaluate_probe_argument (pi->probe, 0);
|
+# Start the inferior and run to the first stop
|
||||||
if (val == NULL)
|
+gdb_run_cmd
|
||||||
goto error;
|
+gdb_test "" ".*Stopped due to shared library event.*"
|
||||||
@@ -1903,6 +1917,9 @@ svr4_handle_solib_event (bpstat bs)
|
|
||||||
action = NAMESPACE_RELOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ do_cleanups (cleanups);
|
|
||||||
+ cleanups = NULL;
|
|
||||||
+
|
+
|
||||||
if (action == NAMESPACE_UPDATE_OR_RELOAD)
|
+# XFAIL if we are not using probes
|
||||||
{
|
+set test "ensure using probes"
|
||||||
if (namespace_update_incremental (info, lmid, lm, is_initial_ns))
|
+set using_probes 0
|
||||||
@@ -1925,6 +1942,8 @@ svr4_handle_solib_event (bpstat bs)
|
+gdb_test_multiple "bt" $test {
|
||||||
warning (_("Probes-based dynamic linker interface failed.\n"
|
+ -re "#0 +\[^\r\n\]*\\m(__GI_)?$normal_bp\\M.*$gdb_prompt $" {
|
||||||
"Reverting to original interface.\n"));
|
+ xfail $test
|
||||||
|
+ }
|
||||||
|
+ -re "#0 +\[^\r\n\]*\\m(__GI_)?$probes_bp\\M.*$gdb_prompt $" {
|
||||||
|
+ pass $test
|
||||||
|
+ set using_probes 1
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+if { $using_probes } {
|
||||||
|
+ # Run til it loads our library
|
||||||
|
+ set test "run til our library loads"
|
||||||
|
+ set loaded_library 0
|
||||||
|
+ while { !$loaded_library } {
|
||||||
|
+ gdb_test_multiple "c" $test {
|
||||||
|
+ -re "Inferior loaded $binfile_lib\\M.*$gdb_prompt $" {
|
||||||
|
+ pass $test
|
||||||
|
+ set loaded_library 1
|
||||||
|
+ }
|
||||||
|
+ -re "Stopped due to shared library event\\M.*$gdb_prompt $" {
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ # Call something to ensure that relocation occurred
|
||||||
|
+ gdb_test "call foo(23)" "\\\$.* = 31.*\\\M.*"
|
||||||
|
+}
|
||||||
|
diff --git a/gdb/testsuite/gdb.base/break-probes.c b/gdb/testsuite/gdb.base/break-probes.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..a778099
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gdb/testsuite/gdb.base/break-probes.c
|
||||||
|
@@ -0,0 +1,26 @@
|
||||||
|
+/* Copyright 2013 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/>. */
|
||||||
|
+
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+main ()
|
||||||
|
+{
|
||||||
|
+ void *handle = dlopen (SHLIB_NAME, RTLD_LAZY);
|
||||||
|
+
|
||||||
|
+ dlclose (handle);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/gdb/testsuite/gdb.base/break-probes-solib.c b/gdb/testsuite/gdb.base/break-probes-solib.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..bdde2db
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gdb/testsuite/gdb.base/break-probes-solib.c
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+/* Copyright 2013 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/>. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+foo (int n)
|
||||||
|
+{
|
||||||
|
+ return n * n / 17;
|
||||||
|
+}
|
||||||
|
diff --git a/gdb/testsuite/gdb.base/info-shared.exp b/gdb/testsuite/gdb.base/info-shared.exp
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..1dabb9f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gdb/testsuite/gdb.base/info-shared.exp
|
||||||
|
@@ -0,0 +1,145 @@
|
||||||
|
+# Copyright 2013 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/>.
|
||||||
|
+
|
||||||
|
+if { [skip_shlib_tests] } {
|
||||||
|
+ return 0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+standard_testfile
|
||||||
|
+
|
||||||
|
+set lib1name $testfile-solib1
|
||||||
|
+set srcfile_lib1 $srcdir/$subdir/$lib1name.c
|
||||||
|
+set binfile_lib1 [standard_output_file $lib1name.so]
|
||||||
|
+set define1 -DSHLIB1_NAME\=\"$binfile_lib1\"
|
||||||
|
+
|
||||||
|
+set lib2name $testfile-solib2
|
||||||
|
+set srcfile_lib2 $srcdir/$subdir/$lib2name.c
|
||||||
|
+set binfile_lib2 [standard_output_file $lib2name.so]
|
||||||
|
+set define2 -DSHLIB2_NAME\=\"$binfile_lib2\"
|
||||||
|
+
|
||||||
|
+if { [gdb_compile_shlib $srcfile_lib1 $binfile_lib1 \
|
||||||
|
+ [list additional_flags=-fPIC]] != "" } {
|
||||||
|
+ untested "Could not compile $binfile_lib1."
|
||||||
|
+ return -1
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+if { [gdb_compile_shlib $srcfile_lib2 $binfile_lib2 \
|
||||||
|
+ [list additional_flags=-fPIC]] != "" } {
|
||||||
|
+ untested "Could not compile $binfile_lib2."
|
||||||
|
+ return -1
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+set cflags "$define1 $define2"
|
||||||
|
+if { [prepare_for_testing $testfile.exp $testfile $srcfile \
|
||||||
|
+ [list additional_flags=$cflags libs=-ldl]] } {
|
||||||
|
+ return -1
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# Run "info sharedlibrary" and check for the presence or absence of
|
||||||
|
+# our libraries.
|
||||||
|
+proc check_info_shared { test expect1 expect2 } {
|
||||||
|
+ global lib1name
|
||||||
|
+ global lib2name
|
||||||
|
+ global gdb_prompt
|
||||||
|
+
|
||||||
|
+ set actual1 0
|
||||||
|
+ set actual2 0
|
||||||
|
+
|
||||||
|
+ gdb_test_multiple "info sharedlibrary" $test {
|
||||||
|
+ -re $lib1name {
|
||||||
|
+ set actual1 1
|
||||||
|
+ exp_continue
|
||||||
|
+ }
|
||||||
|
+ -re $lib2name {
|
||||||
|
+ set actual2 1
|
||||||
|
+ exp_continue
|
||||||
|
+ }
|
||||||
|
+ -re "\r\n$gdb_prompt $" {
|
||||||
|
+ if { $actual1 == $expect1 && $actual2 == $expect2 } {
|
||||||
|
+ pass $test
|
||||||
|
+ } else {
|
||||||
|
+ fail $test
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# Start the inferior, and check neither of the libraries are loaded at
|
||||||
|
+# the start.
|
||||||
|
+runto_main
|
||||||
|
+check_info_shared "info sharedlibrary #1" 0 0
|
||||||
|
+
|
||||||
|
+# Set up breakpoints.
|
||||||
|
+gdb_test "break stop" {Breakpoint [0-9]+ at .*}
|
||||||
|
+gdb_test_no_output "set breakpoint pending on"
|
||||||
|
+gdb_test "break foo" {Breakpoint [0-9]+ \(foo\) pending\.}
|
||||||
|
+gdb_test "break bar" {Breakpoint [0-9]+ \(bar\) pending\.}
|
||||||
|
+
|
||||||
|
+# Run to the first stop and check that only the first library is loaded.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)}
|
||||||
|
+check_info_shared "info sharedlibrary #2" 1 0
|
||||||
|
+
|
||||||
|
+# Run to the second stop and check that both libraries are loaded.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)}
|
||||||
|
+check_info_shared "info sharedlibrary #3" 1 1
|
||||||
|
+
|
||||||
|
+# Check that the next stop is in foo.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*}
|
||||||
|
+
|
||||||
|
+# Check that the next stop is in bar.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in bar \(\) from .*}
|
||||||
|
+
|
||||||
|
+# Restart the inferior and make sure there are no breakpoint reset
|
||||||
|
+# errors. These can happen with the probes-based runtime linker
|
||||||
|
+# interface if the cache is not cleared correctly.
|
||||||
|
+set test "restart"
|
||||||
|
+gdb_run_cmd
|
||||||
|
+gdb_test_multiple "" $test {
|
||||||
|
+ -re {Start it from the beginning\? \(y or n\) } {
|
||||||
|
+ send_gdb "y\n"
|
||||||
|
+ exp_continue
|
||||||
|
+ }
|
||||||
|
+ -re {Error in re-setting breakpoint} {
|
||||||
|
+ fail $test
|
||||||
|
+ }
|
||||||
|
+ -re "\r\n$gdb_prompt $" {
|
||||||
|
+ pass $test
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# Check that neither library is loaded.
|
||||||
|
+check_info_shared "info sharedlibrary #4" 0 0
|
||||||
|
+
|
||||||
|
+# Run to the first stop and check that only the first library is loaded.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)}
|
||||||
|
+check_info_shared "info sharedlibrary #5" 1 0
|
||||||
|
+
|
||||||
|
+# Run to the second stop and check that both libraries are loaded.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)}
|
||||||
|
+check_info_shared "info sharedlibrary #6" 1 1
|
||||||
|
+
|
||||||
|
+# Check that the next stop is in foo.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in foo \(\) from .*}
|
||||||
|
+
|
||||||
|
+# Check that the next stop is in bar.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in bar \(\) from .*}
|
||||||
|
+
|
||||||
|
+# Run to the next stop and check that the first library has been unloaded.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)}
|
||||||
|
+check_info_shared "info sharedlibrary #7" 0 1
|
||||||
|
+
|
||||||
|
+# Run to the last stop and check that both libraries are gone.
|
||||||
|
+gdb_test "c" {Breakpoint [0-9]+, .* in stop \(\)}
|
||||||
|
+check_info_shared "info sharedlibrary #8" 0 0
|
||||||
|
diff --git a/gdb/testsuite/gdb.base/info-shared.c b/gdb/testsuite/gdb.base/info-shared.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..d699a11
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gdb/testsuite/gdb.base/info-shared.c
|
||||||
|
@@ -0,0 +1,48 @@
|
||||||
|
+/* Copyright 2013 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/>. */
|
||||||
|
+
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+stop ()
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+main ()
|
||||||
|
+{
|
||||||
|
+ void *handle1, *handle2;
|
||||||
|
+ void (*func)(int);
|
||||||
|
+
|
||||||
|
+ handle1 = dlopen (SHLIB1_NAME, RTLD_LAZY);
|
||||||
|
+ stop ();
|
||||||
|
+
|
||||||
|
+ handle2 = dlopen (SHLIB2_NAME, RTLD_LAZY);
|
||||||
|
+ stop ();
|
||||||
|
+
|
||||||
|
+ func = (void (*)(int)) dlsym (handle1, "foo");
|
||||||
|
+ func (1);
|
||||||
|
+
|
||||||
|
+ func = (void (*)(int)) dlsym (handle2, "bar");
|
||||||
|
+ func (2);
|
||||||
|
+
|
||||||
|
+ dlclose (handle1);
|
||||||
|
+ stop ();
|
||||||
|
+
|
||||||
|
+ dlclose (handle2);
|
||||||
|
+ stop ();
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/gdb/testsuite/gdb.base/info-shared-solib1.c b/gdb/testsuite/gdb.base/info-shared-solib1.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..9979ee7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gdb/testsuite/gdb.base/info-shared-solib1.c
|
||||||
|
@@ -0,0 +1,24 @@
|
||||||
|
+/* Copyright 2013 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/>. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+foo (int n)
|
||||||
|
+{
|
||||||
|
+ printf ("foo %d\n", n);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/gdb/testsuite/gdb.base/info-shared-solib2.c b/gdb/testsuite/gdb.base/info-shared-solib2.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..d4ed1e6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gdb/testsuite/gdb.base/info-shared-solib2.c
|
||||||
|
@@ -0,0 +1,24 @@
|
||||||
|
+/* Copyright 2013 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/>. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+bar (int n)
|
||||||
|
+{
|
||||||
|
+ printf ("bar %d\n", n);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
|
||||||
|
--DCA/C9WSnDtl50zu--
|
||||||
|
|
||||||
+ if (cleanups != NULL)
|
|
||||||
+ do_cleanups (cleanups);
|
|
||||||
free_namespace_table (info);
|
|
||||||
free_probes (info);
|
|
||||||
info->using_probes = 0;
|
|
||||||
|
62
gdb-dlopen-stap-probe-fixup.patch
Normal file
62
gdb-dlopen-stap-probe-fixup.patch
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
--- gdb-7.6-x/gdb/solib-svr4.c 2013-05-19 16:04:36.838874595 +0200
|
||||||
|
+++ gdb-7.6/gdb/solib-svr4.c 2013-05-19 16:12:35.112514978 +0200
|
||||||
|
@@ -1078,7 +1078,6 @@ svr4_free_library_list (void *p_list)
|
||||||
|
static struct so_list *
|
||||||
|
svr4_copy_library_list (struct so_list *src)
|
||||||
|
{
|
||||||
|
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
|
||||||
|
struct so_list *dst = NULL;
|
||||||
|
struct so_list **link = &dst;
|
||||||
|
|
||||||
|
@@ -1090,8 +1089,8 @@ svr4_copy_library_list (struct so_list *
|
||||||
|
|
||||||
|
memcpy (new, src, sizeof (struct so_list));
|
||||||
|
|
||||||
|
- new->lm_info = xmalloc (lmo->link_map_size);
|
||||||
|
- memcpy (new->lm_info, src->lm_info, lmo->link_map_size);
|
||||||
|
+ new->lm_info = xmalloc (sizeof (*new->lm_info));
|
||||||
|
+ memcpy (new->lm_info, src->lm_info, sizeof (*new->lm_info));
|
||||||
|
|
||||||
|
new->next = NULL;
|
||||||
|
*link = new;
|
||||||
|
@@ -1747,7 +1746,7 @@ solist_update_incremental (struct svr4_i
|
||||||
|
struct svr4_library_list library_list;
|
||||||
|
char annex[64];
|
||||||
|
|
||||||
|
- xsnprintf (annex, sizeof (annex), "start=%lx;prev=%lx", lm, prev_lm);
|
||||||
|
+ xsnprintf (annex, sizeof (annex), "start=%lx;prev=%lx", (unsigned long) lm, (unsigned long) prev_lm);
|
||||||
|
if (!svr4_current_sos_via_xfer_libraries (&library_list, annex))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
@@ -1813,7 +1812,10 @@ svr4_handle_solib_event (void)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (action == DO_NOTHING)
|
||||||
|
+{
|
||||||
|
+do_cleanups (old_chain);
|
||||||
|
return;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* EVALUATE_PROBE_ARGUMENT looks up symbols in the dynamic linker
|
||||||
|
using FIND_PC_SECTION. FIND_PC_SECTION is accelerated by a cache
|
||||||
|
--- gdb-7.6-x/gdb/testsuite/gdb.base/break-probes.exp 2013-05-19 16:06:19.452818090 +0200
|
||||||
|
+++ gdb-7.6/gdb/testsuite/gdb.base/break-probes.exp 2013-05-19 16:07:49.730770135 +0200
|
||||||
|
@@ -60,14 +60,15 @@ gdb_test_multiple "bt" $test {
|
||||||
|
if { $using_probes } {
|
||||||
|
# Run til it loads our library
|
||||||
|
set test "run til our library loads"
|
||||||
|
- set loaded_library 0
|
||||||
|
- while { !$loaded_library } {
|
||||||
|
+ set not_loaded_library 1
|
||||||
|
+ while { $not_loaded_library } {
|
||||||
|
+ set not_loaded_library 0
|
||||||
|
gdb_test_multiple "c" $test {
|
||||||
|
-re "Inferior loaded $binfile_lib\\M.*$gdb_prompt $" {
|
||||||
|
pass $test
|
||||||
|
- set loaded_library 1
|
||||||
|
}
|
||||||
|
-re "Stopped due to shared library event\\M.*$gdb_prompt $" {
|
||||||
|
+ set not_loaded_library 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,60 +0,0 @@
|
|||||||
https://bugzilla.redhat.com/show_bug.cgi?id=911712
|
|
||||||
|
|
||||||
--- ./gdb/objfiles.c-orig 2013-03-21 18:51:00.141957331 +0100
|
|
||||||
+++ ./gdb/objfiles.c 2013-03-21 19:20:25.615519748 +0100
|
|
||||||
@@ -615,6 +615,7 @@ free_objfile (struct objfile *objfile)
|
|
||||||
obstack_free (&objfile->objfile_obstack, 0);
|
|
||||||
|
|
||||||
/* Rebuild section map next time we need it. */
|
|
||||||
+ gdb_assert (!get_objfile_pspace_data (objfile->pspace)->inhibit_updates);
|
|
||||||
get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
|
|
||||||
|
|
||||||
xfree (objfile);
|
|
||||||
@@ -1284,6 +1285,21 @@ bsearch_cmp (const void *key, const void
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+update_space_info_sections (struct objfile_pspace_info *pspace_info)
|
|
||||||
+{
|
|
||||||
+ if (pspace_info->objfiles_changed_p && !pspace_info->inhibit_updates)
|
|
||||||
+ {
|
|
||||||
+ update_section_map (current_program_space,
|
|
||||||
+ &pspace_info->sections,
|
|
||||||
+ &pspace_info->num_sections);
|
|
||||||
+
|
|
||||||
+ /* Don't need updates to section map until objfiles are added,
|
|
||||||
+ removed or relocated. */
|
|
||||||
+ pspace_info->objfiles_changed_p = 0;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Returns a section whose range includes PC or NULL if none found. */
|
|
||||||
|
|
||||||
struct obj_section *
|
|
||||||
@@ -1298,16 +1314,7 @@ find_pc_section (CORE_ADDR pc)
|
|
||||||
return s;
|
|
||||||
|
|
||||||
pspace_info = get_objfile_pspace_data (current_program_space);
|
|
||||||
- if (pspace_info->objfiles_changed_p && !pspace_info->inhibit_updates)
|
|
||||||
- {
|
|
||||||
- update_section_map (current_program_space,
|
|
||||||
- &pspace_info->sections,
|
|
||||||
- &pspace_info->num_sections);
|
|
||||||
-
|
|
||||||
- /* Don't need updates to section map until objfiles are added,
|
|
||||||
- removed or relocated. */
|
|
||||||
- pspace_info->objfiles_changed_p = 0;
|
|
||||||
- }
|
|
||||||
+ update_space_info_sections (pspace_info);
|
|
||||||
|
|
||||||
/* The C standard (ISO/IEC 9899:TC2) requires the BASE argument to
|
|
||||||
bsearch be non-NULL. */
|
|
||||||
@@ -1471,6 +1478,7 @@ objfiles_changed (void)
|
|
||||||
void
|
|
||||||
inhibit_section_map_updates (void)
|
|
||||||
{
|
|
||||||
+ update_space_info_sections (get_objfile_pspace_data (current_program_space));
|
|
||||||
get_objfile_pspace_data (current_program_space)->inhibit_updates = 1;
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
commit 21fd080d18f280c19fdc5489726dcd6c66eb5fbf
|
|
||||||
Author: Gary Benson <gbenson@redhat.com>
|
|
||||||
Date: Tue Jan 8 12:12:14 2013 +0000
|
|
||||||
|
|
||||||
Also stop on "map_failed" where appropriate
|
|
||||||
|
|
||||||
Removed a comment patch hunk.
|
|
||||||
|
|
||||||
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
|
|
||||||
index 5eb84ba..a46fd74 100644
|
|
||||||
--- a/gdb/solib-svr4.c
|
|
||||||
+++ b/gdb/solib-svr4.c
|
|
||||||
@@ -160,6 +160,7 @@ static const struct probe_info probe_info[] =
|
|
||||||
{ "init_start", NAMESPACE_NO_ACTION },
|
|
||||||
{ "init_complete", NAMESPACE_RELOAD },
|
|
||||||
{ "map_start", NAMESPACE_NO_ACTION },
|
|
||||||
+ { "map_failed", NAMESPACE_NO_ACTION },
|
|
||||||
{ "reloc_complete", NAMESPACE_UPDATE_OR_RELOAD },
|
|
||||||
{ "unmap_start", NAMESPACE_NO_ACTION },
|
|
||||||
{ "unmap_complete", NAMESPACE_RELOAD },
|
|
||||||
@@ -2056,6 +2058,9 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
|
|
||||||
info->probes[i] = find_probes_in_objfile (os->objfile, "rtld",
|
|
||||||
name);
|
|
||||||
|
|
||||||
+ if (!strcmp (name, "rtld_map_failed"))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
if (!VEC_length (probe_p, info->probes[i]))
|
|
||||||
{
|
|
||||||
free_probes (info);
|
|
@ -1,307 +0,0 @@
|
|||||||
commit 5bfdc32cd3bf373c3b02e1fd864ed8ceab0292b2
|
|
||||||
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
||||||
Date: Mon Aug 8 12:08:53 2011 +0200
|
|
||||||
|
|
||||||
+testcase
|
|
||||||
|
|
||||||
Index: gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread-lib.c
|
|
||||||
===================================================================
|
|
||||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
||||||
+++ gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread-lib.c 2012-07-15 08:51:38.238701282 +0200
|
|
||||||
@@ -0,0 +1,40 @@
|
|
||||||
+/* This testcase is part of GDB, the GNU debugger.
|
|
||||||
+
|
|
||||||
+ Copyright 2011 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/>. */
|
|
||||||
+
|
|
||||||
+#include <pthread.h>
|
|
||||||
+#include <assert.h>
|
|
||||||
+
|
|
||||||
+static void *
|
|
||||||
+tfunc (void *arg)
|
|
||||||
+{
|
|
||||||
+ void (*notifyp) (void) = arg;
|
|
||||||
+
|
|
||||||
+ notifyp ();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+f (void (*notifyp) (void))
|
|
||||||
+{
|
|
||||||
+ pthread_t t;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ i = pthread_create (&t, NULL, tfunc, notifyp);
|
|
||||||
+ assert (i == 0);
|
|
||||||
+
|
|
||||||
+ i = pthread_join (t, NULL);
|
|
||||||
+ assert (i == 0);
|
|
||||||
+}
|
|
||||||
Index: gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread.c
|
|
||||||
===================================================================
|
|
||||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
||||||
+++ gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread.c 2012-07-15 08:51:38.239701277 +0200
|
|
||||||
@@ -0,0 +1,46 @@
|
|
||||||
+/* This testcase is part of GDB, the GNU debugger.
|
|
||||||
+
|
|
||||||
+ Copyright 2011 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/>. */
|
|
||||||
+
|
|
||||||
+#include <dlfcn.h>
|
|
||||||
+#include <stddef.h>
|
|
||||||
+#include <assert.h>
|
|
||||||
+
|
|
||||||
+static const char *volatile filename;
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+notify (void)
|
|
||||||
+{
|
|
||||||
+ filename = NULL; /* notify-here */
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int
|
|
||||||
+main (void)
|
|
||||||
+{
|
|
||||||
+ void *h;
|
|
||||||
+ void (*fp) (void (*) (void));
|
|
||||||
+
|
|
||||||
+ assert (filename != NULL);
|
|
||||||
+ h = dlopen (filename, RTLD_LAZY);
|
|
||||||
+ assert (h != NULL);
|
|
||||||
+
|
|
||||||
+ fp = dlsym (h, "f");
|
|
||||||
+ assert (fp != NULL);
|
|
||||||
+
|
|
||||||
+ fp (notify);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
Index: gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread.exp
|
|
||||||
===================================================================
|
|
||||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
||||||
+++ gdb-7.4.50.20120714/gdb/testsuite/gdb.threads/dlopen-libpthread.exp 2012-07-15 09:08:01.760258588 +0200
|
|
||||||
@@ -0,0 +1,74 @@
|
|
||||||
+# Copyright 2011 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/>.
|
|
||||||
+
|
|
||||||
+if {![istarget *-linux*] || [skip_shlib_tests]} {
|
|
||||||
+ return 0
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+load_lib prelink-support.exp
|
|
||||||
+
|
|
||||||
+set testfile "dlopen-libpthread"
|
|
||||||
+set srcmainfile ${testfile}.c
|
|
||||||
+set srclibfile ${testfile}-lib.c
|
|
||||||
+set executable ${testfile}
|
|
||||||
+set binfile_lib ${objdir}/${subdir}/${executable}.so
|
|
||||||
+set binfile ${objdir}/${subdir}/${executable}
|
|
||||||
+set lib_dlopen [shlib_target_file ${executable}.so]
|
|
||||||
+
|
|
||||||
+# Use build_executable_own_libs as prelinked libpthread.so can produce false
|
|
||||||
+# PASS - it is OK if GDB processes it still before relocation.
|
|
||||||
+
|
|
||||||
+set relink_args [build_executable_own_libs ${testfile}.exp ${executable}.so $srclibfile {debug shlib_pthreads} no]
|
|
||||||
+if {$relink_args == "" || ![prelink_no $relink_args]
|
|
||||||
+ || [prepare_for_testing ${testfile}.exp ${executable} ${srcmainfile} {debug shlib_load}] } {
|
|
||||||
+ return -1
|
|
||||||
+}
|
|
||||||
+gdb_load_shlibs $binfile_lib
|
|
||||||
+
|
|
||||||
+if { ![runto_main] } {
|
|
||||||
+ return -1
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+set test "info probes all rtld rtld_map_complete"
|
|
||||||
+gdb_test_multiple $test $test {
|
|
||||||
+ -re "\[ \t\]rtld_map_complete\[ \t\]+0x\[0-9a-f\]+.*\r\n$gdb_prompt $" {
|
|
||||||
+ pass $test
|
|
||||||
+ }
|
|
||||||
+ -re "No probes matched\\.\r\n$gdb_prompt $" {
|
|
||||||
+ xfail $test
|
|
||||||
+ untested ${testfile}.exp
|
|
||||||
+ return
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+set test "libpthread.so not found"
|
|
||||||
+gdb_test_multiple "info sharedlibrary" $test {
|
|
||||||
+ -re "/libpthread\\.so.*\r\n$gdb_prompt $" {
|
|
||||||
+ fail $test
|
|
||||||
+ }
|
|
||||||
+ -re "/libc\\.so.*\r\n$gdb_prompt $" {
|
|
||||||
+ pass $test
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+gdb_test "set variable filename=\"$lib_dlopen\""
|
|
||||||
+
|
|
||||||
+gdb_breakpoint "notify"
|
|
||||||
+
|
|
||||||
+# The error was:
|
|
||||||
+# Cannot find new threads: generic error
|
|
||||||
+gdb_continue_to_breakpoint "notify" ".* notify-here .*"
|
|
||||||
+
|
|
||||||
+gdb_test "info sharedlibrary" {/libpthread\.so.*} "libpthread.so found"
|
|
||||||
Index: gdb-7.4.50.20120714/gdb/testsuite/lib/gdb.exp
|
|
||||||
===================================================================
|
|
||||||
--- gdb-7.4.50.20120714.orig/gdb/testsuite/lib/gdb.exp 2012-07-15 08:51:36.803709222 +0200
|
|
||||||
+++ gdb-7.4.50.20120714/gdb/testsuite/lib/gdb.exp 2012-07-15 09:02:41.983028197 +0200
|
|
||||||
@@ -3774,22 +3774,6 @@ proc build_executable_from_specs {testna
|
|
||||||
|
|
||||||
set binfile [standard_output_file $executable]
|
|
||||||
|
|
||||||
- set objects {}
|
|
||||||
- set i 0
|
|
||||||
- foreach {s local_options} $args {
|
|
||||||
- if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $local_options] != "" } {
|
|
||||||
- untested $testname
|
|
||||||
- return -1
|
|
||||||
- }
|
|
||||||
- lappend objects "${binfile}${i}.o"
|
|
||||||
- incr i
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if { [gdb_compile $objects "${binfile}" executable $options] != "" } {
|
|
||||||
- untested $testname
|
|
||||||
- return -1
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
set info_options ""
|
|
||||||
if { [lsearch -exact $options "c++"] >= 0 } {
|
|
||||||
set info_options "c++"
|
|
||||||
@@ -3797,6 +3781,42 @@ proc build_executable_from_specs {testna
|
|
||||||
if [get_compiler_info ${info_options}] {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ set binfile [standard_output_file $executable]
|
|
||||||
+
|
|
||||||
+ set func gdb_compile
|
|
||||||
+ set func_index [lsearch -regexp $options {^(pthreads|shlib|shlib_pthreads)$}]
|
|
||||||
+ if {$func_index != -1} {
|
|
||||||
+ set func "${func}_[lindex $options $func_index]"
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ # gdb_compile_shlib and gdb_compile_shlib_pthreads do not use the 3rd
|
|
||||||
+ # parameter. They also requires $sources while gdb_compile and
|
|
||||||
+ # gdb_compile_pthreads require $objects. Moreover they ignore any options.
|
|
||||||
+ if [string match gdb_compile_shlib* $func] {
|
|
||||||
+ set sources_path {}
|
|
||||||
+ foreach {s local_options} $args {
|
|
||||||
+ lappend sources_path "${srcdir}/${subdir}/${s}"
|
|
||||||
+ }
|
|
||||||
+ set ret [$func $sources_path "${binfile}" $options]
|
|
||||||
+ } else {
|
|
||||||
+ set objects {}
|
|
||||||
+ set i 0
|
|
||||||
+ foreach {s local_options} $args {
|
|
||||||
+ if { [gdb_compile "${srcdir}/${subdir}/${s}" "${binfile}${i}.o" object $local_options] != "" } {
|
|
||||||
+ untested $testname
|
|
||||||
+ return -1
|
|
||||||
+ }
|
|
||||||
+ lappend objects "${binfile}${i}.o"
|
|
||||||
+ incr i
|
|
||||||
+ }
|
|
||||||
+ set ret [$func $objects "${binfile}" executable $options]
|
|
||||||
+ }
|
|
||||||
+ if { $ret != "" } {
|
|
||||||
+ untested $testname
|
|
||||||
+ return -1
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Index: gdb-7.4.50.20120714/gdb/testsuite/lib/prelink-support.exp
|
|
||||||
===================================================================
|
|
||||||
--- gdb-7.4.50.20120714.orig/gdb/testsuite/lib/prelink-support.exp 2012-01-04 09:27:56.000000000 +0100
|
|
||||||
+++ gdb-7.4.50.20120714/gdb/testsuite/lib/prelink-support.exp 2012-07-15 08:51:38.243701254 +0200
|
|
||||||
@@ -95,8 +95,9 @@ proc file_copy {src dest} {
|
|
||||||
# Wrap function build_executable so that the resulting executable is fully
|
|
||||||
# self-sufficient (without dependencies on system libraries). Parameter
|
|
||||||
# INTERP may be used to specify a loader (ld.so) to be used that is
|
|
||||||
-# different from the default system one. Libraries on which the executable
|
|
||||||
-# depends are copied into directory DIR. Default DIR value to
|
|
||||||
+# different from the default system one. INTERP can be set to "no" if no ld.so
|
|
||||||
+# copy should be made. Libraries on which the executable depends are copied
|
|
||||||
+# into directory DIR. Default DIR value to
|
|
||||||
# `${objdir}/${subdir}/${EXECUTABLE}.d'.
|
|
||||||
#
|
|
||||||
# In case of success, return a string containing the arguments to be used
|
|
||||||
@@ -151,8 +152,15 @@ proc build_executable_own_libs {testname
|
|
||||||
|
|
||||||
if {$interp == ""} {
|
|
||||||
set interp_system [section_get $binfile .interp]
|
|
||||||
- set interp ${dir}/[file tail $interp_system]
|
|
||||||
- file_copy $interp_system $interp
|
|
||||||
+ if {$interp_system == ""} {
|
|
||||||
+ fail "$test could not find .interp"
|
|
||||||
+ } else {
|
|
||||||
+ set interp ${dir}/[file tail $interp_system]
|
|
||||||
+ file_copy $interp_system $interp
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if {$interp == "no"} {
|
|
||||||
+ set interp ""
|
|
||||||
}
|
|
||||||
|
|
||||||
set dests {}
|
|
||||||
@@ -164,13 +172,19 @@ proc build_executable_own_libs {testname
|
|
||||||
|
|
||||||
# Do not lappend it so that "-rpath $dir" overrides any possible "-rpath"s
|
|
||||||
# specified by the caller to be able to link it for ldd" above.
|
|
||||||
- set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp,-rpath,$dir"]
|
|
||||||
+ set options [linsert $options 0 "ldflags=-Wl,-rpath,$dir"]
|
|
||||||
+ if {$interp != ""} {
|
|
||||||
+ set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp"]
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if {[build_executable $testname $executable $sources $options] == -1} {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
- set prelink_args "--dynamic-linker=$interp --ld-library-path=$dir $binfile $interp [concat $dests]"
|
|
||||||
+ set prelink_args "--ld-library-path=$dir $binfile [concat $dests]"
|
|
||||||
+ if {$interp != ""} {
|
|
||||||
+ set prelink_args "--dynamic-linker=$interp $prelink_args $interp"
|
|
||||||
+ }
|
|
||||||
return $prelink_args
|
|
||||||
}
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
http://sourceware.org/ml/gdb-patches/2012-08/msg00500.html
|
|
||||||
Subject: [patch] testsuite: Make solib-corrupted.exp untested for probes [Re: [RFA 0/4 take 2] Improved linker-debugger interface]
|
|
||||||
|
|
||||||
On Fri, 17 Aug 2012 22:53:53 +0200, Jan Kratochvil wrote:
|
|
||||||
> It regresses with glibc-debuginfo installed:
|
|
||||||
>
|
|
||||||
> info sharedlibrary^M
|
|
||||||
> From To Syms Read Shared Object Library^M
|
|
||||||
> 0x00007ffff7ddcb20 0x00007ffff7df63d9 Yes /lib64/ld-linux-x86-64.so.2^M
|
|
||||||
> 0x00007ffff7ae05b0 0x00007ffff7b4ad78 Yes /lib64/libm.so.6^M
|
|
||||||
> 0x00007ffff77431a0 0x00007ffff7883cf0 Yes /lib64/libc.so.6^M
|
|
||||||
> (gdb) FAIL: gdb.base/solib-corrupted.exp: corrupted list
|
|
||||||
>
|
|
||||||
> But I guess there is no longer a way to test it with probes so it should just
|
|
||||||
> run some 'info probes' and make this test UNTESTED if rtld probes are
|
|
||||||
> available.
|
|
||||||
|
|
||||||
I had to implement it for Fedora already anyway.
|
|
||||||
|
|
||||||
|
|
||||||
Regards,
|
|
||||||
Jan
|
|
||||||
|
|
||||||
|
|
||||||
gdb/testsuite/
|
|
||||||
2012-08-18 Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
||||||
|
|
||||||
* gdb.base/solib-corrupted.exp: New variable probes.
|
|
||||||
(info probes): New test.
|
|
||||||
|
|
||||||
diff --git a/gdb/testsuite/gdb.base/solib-corrupted.exp b/gdb/testsuite/gdb.base/solib-corrupted.exp
|
|
||||||
index 84b3b0c..c9f55d6 100644
|
|
||||||
--- a/gdb/testsuite/gdb.base/solib-corrupted.exp
|
|
||||||
+++ b/gdb/testsuite/gdb.base/solib-corrupted.exp
|
|
||||||
@@ -36,6 +36,33 @@ if ![runto_main] {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
+# With probes interface GDB no longer scans the inferior library list so its
|
|
||||||
+# corruption cannot be tested. There is no way to disable the probes
|
|
||||||
+# interface.
|
|
||||||
+
|
|
||||||
+set probes { init_start init_complete map_start reloc_complete unmap_start
|
|
||||||
+ unmap_complete }
|
|
||||||
+set test "info probes"
|
|
||||||
+gdb_test_multiple $test $test {
|
|
||||||
+ -re "^rtld\[ \t\]+(?:rtld_)?(\[a-z_\]+)\[ \t\]" {
|
|
||||||
+ set idx [lsearch -exact $probes $expect_out(1,string)]
|
|
||||||
+ if { $idx >= 0 } {
|
|
||||||
+ set probes [lreplace $probes $idx $idx]
|
|
||||||
+ }
|
|
||||||
+ exp_continue
|
|
||||||
+ }
|
|
||||||
+ -re "^\[^\r\n\]*\r\n" {
|
|
||||||
+ exp_continue
|
|
||||||
+ }
|
|
||||||
+ -re "^$gdb_prompt $" {
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+if { [llength $probes] == 0 } {
|
|
||||||
+ xfail $test
|
|
||||||
+ untested "GDB is using probes"
|
|
||||||
+ return
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
gdb_test "info sharedlibrary" "From * To .*" "normal list"
|
|
||||||
|
|
||||||
# GDB checks there for matching L_PREV.
|
|
||||||
|
|
24
gdb.spec
24
gdb.spec
@ -36,7 +36,7 @@ Version: 7.6
|
|||||||
|
|
||||||
# The release always contains a leading reserved number, start it at 1.
|
# The release always contains a leading reserved number, start it at 1.
|
||||||
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
|
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
|
||||||
Release: 28%{?dist}
|
Release: 29%{?dist}
|
||||||
|
|
||||||
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
|
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
|
||||||
Group: Development/Debuggers
|
Group: Development/Debuggers
|
||||||
@ -504,16 +504,16 @@ Patch579: gdb-7.2.50-sparc-add-workaround-to-broken-debug-files.patch
|
|||||||
|
|
||||||
# Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432).
|
# Fix dlopen of libpthread.so, patched glibc required (Gary Benson, BZ 669432).
|
||||||
# Fix crash regression from the dlopen of libpthread.so fix (BZ 911712).
|
# Fix crash regression from the dlopen of libpthread.so fix (BZ 911712).
|
||||||
|
# Fix performance regression when inferior opens many libraries (Gary Benson).
|
||||||
#=push
|
#=push
|
||||||
Patch718: gdb-dlopen-stap-probe-3of7.patch
|
Patch718: gdb-dlopen-stap-probe-1of7.patch
|
||||||
Patch719: gdb-dlopen-stap-probe-4of7.patch
|
Patch719: gdb-dlopen-stap-probe-2of7.patch
|
||||||
Patch720: gdb-dlopen-stap-probe-5of7.patch
|
Patch720: gdb-dlopen-stap-probe-3of7.patch
|
||||||
Patch721: gdb-dlopen-stap-probe-6of7.patch
|
Patch721: gdb-dlopen-stap-probe-4of7.patch
|
||||||
Patch722: gdb-dlopen-stap-probe-7of7.patch
|
Patch722: gdb-dlopen-stap-probe-5of7.patch
|
||||||
Patch619: gdb-dlopen-stap-probe-test.patch
|
Patch723: gdb-dlopen-stap-probe-6of7.patch
|
||||||
Patch723: gdb-dlopen-stap-probe-test2.patch
|
Patch822: gdb-dlopen-stap-probe-7of7.patch
|
||||||
Patch822: gdb-dlopen-stap-probe-mapfailed.patch
|
Patch827: gdb-dlopen-stap-probe-fixup.patch
|
||||||
Patch827: gdb-dlopen-stap-probe-inhibit.patch
|
|
||||||
|
|
||||||
# Work around PR libc/13097 "linux-vdso.so.1" warning message.
|
# Work around PR libc/13097 "linux-vdso.so.1" warning message.
|
||||||
#=push
|
#=push
|
||||||
@ -876,7 +876,6 @@ find -name "*.info*"|xargs rm -f
|
|||||||
%patch723 -p1
|
%patch723 -p1
|
||||||
%patch822 -p1
|
%patch822 -p1
|
||||||
%patch827 -p1
|
%patch827 -p1
|
||||||
%patch619 -p1
|
|
||||||
%patch627 -p1
|
%patch627 -p1
|
||||||
%patch634 -p1
|
%patch634 -p1
|
||||||
%patch653 -p1
|
%patch653 -p1
|
||||||
@ -1398,6 +1397,9 @@ fi
|
|||||||
%endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
|
%endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sun May 19 2013 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6-29.fc19
|
||||||
|
- Fix performance regression when inferior opens many libraries (Gary Benson).
|
||||||
|
|
||||||
* Thu May 9 2013 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6-28.fc19
|
* Thu May 9 2013 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.6-28.fc19
|
||||||
- Fix needless expansion of non-gdbindex symtabs (Doug Evans).
|
- Fix needless expansion of non-gdbindex symtabs (Doug Evans).
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user