diff options
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/common/agent.c | 302 | ||||
-rw-r--r-- | gdb/common/agent.h | 37 | ||||
-rw-r--r-- | gdb/config.in | 6 | ||||
-rwxr-xr-x | gdb/configure | 2 | ||||
-rw-r--r-- | gdb/configure.ac | 2 | ||||
-rw-r--r-- | gdb/gdbserver/ChangeLog | 21 | ||||
-rw-r--r-- | gdb/gdbserver/Makefile.in | 8 | ||||
-rw-r--r-- | gdb/gdbserver/config.in | 3 | ||||
-rwxr-xr-x | gdb/gdbserver/configure | 2 | ||||
-rw-r--r-- | gdb/gdbserver/configure.ac | 2 | ||||
-rw-r--r-- | gdb/gdbserver/tracepoint.c | 281 |
12 files changed, 443 insertions, 231 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6cf9ab4..23ba558 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2012-03-03 Yao Qi <yao@codesourcery.com> + + * common/agent.c: New. + * common/agent.h: New. + * configure.ac: Add `sys/socket.h' and `sys/un.h' to + AC_CHECK_HEADERS. + * configure, configh.in: Regenerated. + 2012-03-02 Kevin Buettner <kevinb@redhat.com> * sh-tdep.c (sh_frame_cache): Don't fetch the FPSCR register diff --git a/gdb/common/agent.c b/gdb/common/agent.c new file mode 100644 index 0000000..7553835 --- /dev/null +++ b/gdb/common/agent.c @@ -0,0 +1,302 @@ +/* Shared utility routines for GDB to interact with agent. + + Copyright (C) 2009-2012 Free Software Foundation, Inc. + + This file is part of GDB. + + 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/>. */ + +#ifdef GDBSERVER +#include "server.h" +#else +#include "defs.h" +#include "target.h" +#include "inferior.h" /* for non_stop */ +#endif + +#include <string.h> +#include <unistd.h> +#include "agent.h" + +int debug_agent = 0; + +#ifdef GDBSERVER +#define DEBUG_AGENT(fmt, args...) \ + if (debug_agent) \ + fprintf (stderr, fmt, ##args); +#else +#define DEBUG_AGENT(fmt, args...) \ + if (debug_agent) \ + fprintf_unfiltered (gdb_stdlog, fmt, ##args); +#endif + +/* Addresses of in-process agent's symbols both GDB and GDBserver cares + about. */ + +struct ipa_sym_addresses +{ + CORE_ADDR addr_helper_thread_id; + CORE_ADDR addr_cmd_buf; +}; + +/* Cache of the helper thread id. FIXME: this global should be made + per-process. */ +static unsigned int helper_thread_id = 0; + +static struct +{ + const char *name; + int offset; + int required; +} symbol_list[] = { + IPA_SYM(helper_thread_id), + IPA_SYM(cmd_buf), +}; + +static struct ipa_sym_addresses ipa_sym_addrs; + +/* Look up all symbols needed by agent. Return 0 if all the symbols are + found, return non-zero otherwise. */ + +int +agent_look_up_symbols (void) +{ + int i; + + for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++) + { + CORE_ADDR *addrp = + (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset); +#ifdef GDBSERVER + + if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0) +#else + struct minimal_symbol *sym = lookup_minimal_symbol (symbol_list[i].name, + NULL, NULL); + + if (sym != NULL) + *addrp = SYMBOL_VALUE_ADDRESS (sym); + else +#endif + { + DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name); + return -1; + } + } + + return 0; +} + +static unsigned int +agent_get_helper_thread_id (void) +{ + if (helper_thread_id == 0) + { +#ifdef GDBSERVER + if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id, + (unsigned char *) &helper_thread_id, + sizeof helper_thread_id)) +#else + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); + gdb_byte buf[4]; + + if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id, + buf, sizeof buf) == 0) + helper_thread_id = extract_unsigned_integer (buf, sizeof buf, + byte_order); + else +#endif + { + warning ("Error reading helper thread's id in lib"); + } + } + + return helper_thread_id; +} + +#ifdef HAVE_SYS_UN_H +#include <sys/socket.h> +#include <sys/un.h> +#define SOCK_DIR P_tmpdir + +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path) +#endif + +#endif + +/* Connects to synchronization socket. PID is the pid of inferior, which is + used to set up the connection socket. */ + +static int +gdb_connect_sync_socket (int pid) +{ +#ifdef HAVE_SYS_UN_H + struct sockaddr_un addr; + int res, fd; + char path[UNIX_PATH_MAX]; + + res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid); + if (res >= UNIX_PATH_MAX) + return -1; + + res = fd = socket (PF_UNIX, SOCK_STREAM, 0); + if (res == -1) + { + warning ("error opening sync socket: %s\n", strerror (errno)); + return -1; + } + + addr.sun_family = AF_UNIX; + + res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path); + if (res >= UNIX_PATH_MAX) + { + warning ("string overflow allocating socket name\n"); + close (fd); + return -1; + } + + res = connect (fd, (struct sockaddr *) &addr, sizeof (addr)); + if (res == -1) + { + warning ("error connecting sync socket (%s): %s. " + "Make sure the directory exists and that it is writable.", + path, strerror (errno)); + close (fd); + return -1; + } + + return fd; +#else + return -1; +#endif +} + +/* Execute an agent command in the inferior. PID is the value of pid of the + inferior. CMD is the buffer for command. GDB or GDBserver will store the + command into it and fetch the return result from CMD. The interaction + between GDB/GDBserver and the agent is synchronized by a synchronization + socket. Return zero if success, otherwise return non-zero. */ + +int +agent_run_command (int pid, const char *cmd) +{ + int fd; + int tid = agent_get_helper_thread_id (); + ptid_t ptid = ptid_build (pid, tid, 0); + int len = strlen (cmd) + 1; + +#ifdef GDBSERVER + int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf, + (const unsigned char *) cmd, len); +#else + int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, cmd, len); +#endif + + if (ret != 0) + { + warning ("unable to write"); + return -1; + } + + DEBUG_AGENT ("agent: resumed helper thread\n"); + + /* Resume helper thread. */ +#ifdef GDBSERVER +{ + struct thread_resume resume_info; + + resume_info.thread = ptid; + resume_info.kind = resume_continue; + resume_info.sig = TARGET_SIGNAL_0; + (*the_target->resume) (&resume_info, 1); +} +#else + target_resume (ptid, 0, TARGET_SIGNAL_0); +#endif + + fd = gdb_connect_sync_socket (pid); + if (fd >= 0) + { + char buf[1] = ""; + int ret; + + DEBUG_AGENT ("agent: signalling helper thread\n"); + + do + { + ret = write (fd, buf, 1); + } while (ret == -1 && errno == EINTR); + + DEBUG_AGENT ("agent: waiting for helper thread's response\n"); + + do + { + ret = read (fd, buf, 1); + } while (ret == -1 && errno == EINTR); + + close (fd); + + DEBUG_AGENT ("agent: helper thread's response received\n"); + } + else + return -1; + + /* Need to read response with the inferior stopped. */ + if (!ptid_equal (ptid, null_ptid)) + { + struct target_waitstatus status; + int was_non_stop = non_stop; + /* Stop thread PTID. */ + DEBUG_AGENT ("agent: stop helper thread\n"); +#ifdef GDBSERVER + { + struct thread_resume resume_info; + + resume_info.thread = ptid; + resume_info.kind = resume_stop; + resume_info.sig = TARGET_SIGNAL_0; + (*the_target->resume) (&resume_info, 1); + } + + non_stop = 1; + mywait (ptid, &status, 0, 0); +#else + non_stop = 1; + target_stop (ptid); + + memset (&status, 0, sizeof (status)); + target_wait (ptid, &status, 0); +#endif + non_stop = was_non_stop; + } + + if (fd >= 0) + { +#ifdef GDBSERVER + if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf, + (unsigned char *) cmd, IPA_CMD_BUF_SIZE)) +#else + if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd, + IPA_CMD_BUF_SIZE)) +#endif + { + warning ("Error reading command response"); + return -1; + } + } + + return 0; +} diff --git a/gdb/common/agent.h b/gdb/common/agent.h new file mode 100644 index 0000000..31c46d9 --- /dev/null +++ b/gdb/common/agent.h @@ -0,0 +1,37 @@ +/* Shared utility routines for GDB to interact with agent. + + Copyright (C) 2009-2012 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +int agent_run_command (int pid, const char *cmd); + +int agent_look_up_symbols (void); + +#define STRINGIZE_1(STR) #STR +#define STRINGIZE(STR) STRINGIZE_1(STR) +#define IPA_SYM(SYM) \ + { \ + STRINGIZE (gdb_agent_ ## SYM), \ + offsetof (struct ipa_sym_addresses, addr_ ## SYM) \ + } + +/* The size in bytes of the buffer used to talk to the IPA helper + thread. */ +#define IPA_CMD_BUF_SIZE 1024 + +extern int debug_agent; + diff --git a/gdb/config.in b/gdb/config.in index 194cc7d..2df15bb 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -641,6 +641,9 @@ /* Define to 1 if you have the <sys/select.h> header file. */ #undef HAVE_SYS_SELECT_H +/* Define to 1 if you have the <sys/socket.h> header file. */ +#undef HAVE_SYS_SOCKET_H + /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H @@ -650,6 +653,9 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the <sys/un.h> header file. */ +#undef HAVE_SYS_UN_H + /* Define to 1 if you have the <sys/user.h> header file. */ #undef HAVE_SYS_USER_H diff --git a/gdb/configure b/gdb/configure index 22343f5..eeb2696 100755 --- a/gdb/configure +++ b/gdb/configure @@ -11629,7 +11629,7 @@ for ac_header in nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \ sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \ sys/types.h sys/wait.h wait.h termios.h termio.h \ sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \ - dlfcn.h + dlfcn.h sys/socket.h sys/un.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/gdb/configure.ac b/gdb/configure.ac index e8de55c..6bb7cf4 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -974,7 +974,7 @@ AC_CHECK_HEADERS([nlist.h machine/reg.h poll.h sys/poll.h proc_service.h \ sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \ sys/types.h sys/wait.h wait.h termios.h termio.h \ sgtty.h unistd.h elf_hp.h ctype.h time.h locale.h \ - dlfcn.h]) + dlfcn.h sys/socket.h sys/un.h]) AC_CHECK_HEADERS(link.h, [], [], [#if HAVE_SYS_TYPES_H # include <sys/types.h> diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index c1baa9f..6cb8789 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,24 @@ +2012-03-03 Yao Qi <yao@codesourcery.com> + + * Makefile.in (OBS): Add agent.o. + Add new rule for agent.o. + Track dependence of tracepoint.c on agent.h. + * tracepoint.c (run_inferior_command_1): + (run_inferior_command): Call agent_run_command. + (gdb_ust_connect_sync_socket): Deleted. Move it to + common/agent.c. + (resume_thread, stop_thread): Likewise. + (gdb_ust_socket_init): Renamed to ... + (gdb_agent_socket_init): ... New. + (gdb_ust_thread): Renamed to ... + (gdb_agent_helper_thread): ... New. + (gdb_ust_init): Move some code to ... + (gdb_agent_init): ... here. New. + [HAVE_UST]: Call gdb_ust_init. + (initialize_tracepoint_ftlib): Call gdb_agent_init. + * configure.ac: Add `sys/un.h' to AC_CHECK_HEADERS. + * config.in, configure: Regenerated. + 2012-03-02 Pedro Alves <palves@redhat.com> * inferiors.c (add_pid_to_list, pull_pid_from_list): Delete. diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 551a8f1..439fd20 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -134,7 +134,7 @@ LIBOBJS = @LIBOBJS@ SOURCES = $(SFILES) TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS} -OBS = ax.o inferiors.o regcache.o remote-utils.o server.o signals.o target.o \ +OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o target.o \ utils.o version.o \ mem-break.o hostio.o event-loop.o tracepoint.o \ xml-utils.o common-utils.o ptid.o buffer.o \ @@ -337,6 +337,7 @@ signals_def = $(srcdir)/../../include/gdb/signals.def signals_h = $(srcdir)/../../include/gdb/signals.h $(signals_def) ptid_h = $(srcdir)/../common/ptid.h ax_h = $(srcdir)/ax.h +agent_h = $(srcdir)/../common/agent.h linux_osdata_h = $(srcdir)/../common/linux-osdata.h server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \ $(srcdir)/mem-break.h $(srcdir)/../common/gdb_signals.h \ @@ -403,7 +404,7 @@ server.o: server.c $(server_h) target.o: target.c $(server_h) thread-db.o: thread-db.c $(server_h) $(linux_low_h) $(gdb_proc_service_h) \ $(gdb_thread_db_h) -tracepoint.o: tracepoint.c $(server_h) $(ax_h) +tracepoint.o: tracepoint.c $(server_h) $(ax_h) $(agent_h) utils.o: utils.c $(server_h) gdbreplay.o: gdbreplay.c config.h dll.o: dll.c $(server_h) @@ -429,6 +430,9 @@ ptid.o: ../common/ptid.c $(ptid_h) buffer.o: ../common/buffer.c $(server_h) $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER +agent.o: ../common/agent.c $(server_h) $(agent_h) + $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER + # We build memmem.c without -Werror because this file is not under # our control. On LynxOS, the compiler generates some warnings # because str-two-way.h uses a constant (MAX_SIZE) whose definition diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in index 7fa3b5b..1d61c13 100644 --- a/gdb/gdbserver/config.in +++ b/gdb/gdbserver/config.in @@ -184,6 +184,9 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the <sys/un.h> header file. */ +#undef HAVE_SYS_UN_H + /* Define to 1 if you have the <sys/wait.h> header file. */ #undef HAVE_SYS_WAIT_H diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure index e251844..2b0aeb8 100755 --- a/gdb/gdbserver/configure +++ b/gdb/gdbserver/configure @@ -4149,7 +4149,7 @@ _ACEOF fi -for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h +for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac index 7c86cd4..d2f22bd 100644 --- a/gdb/gdbserver/configure.ac +++ b/gdb/gdbserver/configure.ac @@ -42,7 +42,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl stdlib.h unistd.h dnl errno.h fcntl.h signal.h sys/file.h malloc.h dnl sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl - netinet/tcp.h arpa/inet.h sys/wait.h) + netinet/tcp.h arpa/inet.h sys/wait.h sys/un.h) AC_CHECK_FUNCS(pread pwrite pread64 readlink) AC_REPLACE_FUNCS(memmem vasprintf vsnprintf) diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index 7167876..f5f506a 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -17,6 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "server.h" +#include "agent.h" + #include <ctype.h> #include <fcntl.h> #include <unistd.h> @@ -178,18 +180,8 @@ struct ipa_sym_addresses CORE_ADDR addr_get_trace_state_variable_value; CORE_ADDR addr_set_trace_state_variable_value; CORE_ADDR addr_ust_loaded; - CORE_ADDR addr_helper_thread_id; - CORE_ADDR addr_cmd_buf; }; -#define STRINGIZE_1(STR) #STR -#define STRINGIZE(STR) STRINGIZE_1(STR) -#define IPA_SYM(SYM) \ - { \ - STRINGIZE (gdb_agent_ ## SYM), \ - offsetof (struct ipa_sym_addresses, addr_ ## SYM) \ - } - static struct { const char *name; @@ -225,11 +217,9 @@ static struct IPA_SYM(get_trace_state_variable_value), IPA_SYM(set_trace_state_variable_value), IPA_SYM(ust_loaded), - IPA_SYM(helper_thread_id), - IPA_SYM(cmd_buf), }; -struct ipa_sym_addresses ipa_sym_addrs; +static struct ipa_sym_addresses ipa_sym_addrs; int all_tracepoint_symbols_looked_up; @@ -348,6 +338,9 @@ tracepoint_look_up_symbols (void) } } + if (agent_look_up_symbols () != 0) + return; + all_tracepoint_symbols_looked_up = 1; } @@ -1242,10 +1235,6 @@ static LONGEST get_timestamp (void); #define cmpxchg(mem, oldval, newval) \ __sync_val_compare_and_swap (mem, oldval, newval) -/* The size in bytes of the buffer used to talk to the IPA helper - thread. */ -#define CMD_BUF_SIZE 1024 - /* Record that an error occurred during expression evaluation. */ static void @@ -2217,7 +2206,7 @@ cmd_qtinit (char *packet) static void unprobe_marker_at (CORE_ADDR address) { - char cmd[CMD_BUF_SIZE]; + char cmd[IPA_CMD_BUF_SIZE]; sprintf (cmd, "unprobe_marker_at:%s", paddress (address)); run_inferior_command (cmd); @@ -2791,7 +2780,7 @@ have_fast_tracepoint_trampoline_buffer (char *buf) static int probe_marker_at (CORE_ADDR address, char *errout) { - char cmd[CMD_BUF_SIZE]; + char cmd[IPA_CMD_BUF_SIZE]; int err; sprintf (cmd, "probe_marker_at:%s", paddress (address)); @@ -6144,7 +6133,7 @@ upload_fast_traceframes (void) #ifdef IN_PROCESS_AGENT IP_AGENT_EXPORT int ust_loaded; -IP_AGENT_EXPORT char cmd_buf[CMD_BUF_SIZE]; +IP_AGENT_EXPORT char cmd_buf[IPA_CMD_BUF_SIZE]; #ifdef HAVE_UST @@ -6393,94 +6382,8 @@ static struct ltt_available_probe gdb_ust_probe = #endif /* HAVE_UST */ #endif /* IN_PROCESS_AGENT */ -#ifdef HAVE_UST - -#include <sys/socket.h> -#include <sys/un.h> - -#ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path) -#endif - -/* Where we put the socked used for synchronization. */ -#define SOCK_DIR P_tmpdir - -#endif /* HAVE_UST */ - #ifndef IN_PROCESS_AGENT -#ifdef HAVE_UST - -static int -gdb_ust_connect_sync_socket (int pid) -{ - struct sockaddr_un addr; - int res, fd; - char path[UNIX_PATH_MAX]; - - res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", SOCK_DIR, pid); - if (res >= UNIX_PATH_MAX) - { - trace_debug ("string overflow allocating socket name"); - return -1; - } - - res = fd = socket (PF_UNIX, SOCK_STREAM, 0); - if (res == -1) - { - warning ("error opening sync socket: %s\n", strerror (errno)); - return -1; - } - - addr.sun_family = AF_UNIX; - - res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path); - if (res >= UNIX_PATH_MAX) - { - warning ("string overflow allocating socket name\n"); - close (fd); - return -1; - } - - res = connect (fd, (struct sockaddr *) &addr, sizeof (addr)); - if (res == -1) - { - warning ("error connecting sync socket (%s): %s. " - "Make sure the directory exists and that it is writable.", - path, strerror (errno)); - close (fd); - return -1; - } - - return fd; -} - -/* Resume thread PTID. */ - -static void -resume_thread (ptid_t ptid) -{ - struct thread_resume resume_info; - - resume_info.thread = ptid; - resume_info.kind = resume_continue; - resume_info.sig = TARGET_SIGNAL_0; - (*the_target->resume) (&resume_info, 1); -} - -/* Stop thread PTID. */ - -static void -stop_thread (ptid_t ptid) -{ - struct thread_resume resume_info; - - resume_info.thread = ptid; - resume_info.kind = resume_stop; - resume_info.sig = TARGET_SIGNAL_0; - (*the_target->resume) (&resume_info, 1); -} - /* Ask the in-process agent to run a command. Since we don't want to have to handle the IPA hitting breakpoints while running the command, we pause all threads, remove all breakpoints, and then set @@ -6492,91 +6395,14 @@ static int run_inferior_command (char *cmd) { int err = -1; - int fd = -1; int pid = ptid_get_pid (current_inferior->entry.id); - int tid; - ptid_t ptid = null_ptid; trace_debug ("run_inferior_command: running: %s", cmd); pause_all (0); uninsert_all_breakpoints (); - if (read_inferior_integer (ipa_sym_addrs.addr_helper_thread_id, &tid)) - { - warning ("Error reading helper thread's id in lib"); - goto out; - } - - if (tid == 0) - { - warning ("helper thread not initialized yet"); - goto out; - } - - if (write_inferior_memory (ipa_sym_addrs.addr_cmd_buf, - (unsigned char *) cmd, strlen (cmd) + 1)) - { - warning ("Error writing command"); - goto out; - } - - ptid = ptid_build (pid, tid, 0); - - resume_thread (ptid); - - fd = gdb_ust_connect_sync_socket (pid); - if (fd >= 0) - { - char buf[1] = ""; - int ret; - - trace_debug ("signalling helper thread"); - - do - { - ret = write (fd, buf, 1); - } while (ret == -1 && errno == EINTR); - - trace_debug ("waiting for helper thread's response"); - - do - { - ret = read (fd, buf, 1); - } while (ret == -1 && errno == EINTR); - - close (fd); - - trace_debug ("helper thread's response received"); - } - - out: - - /* Need to read response with the inferior stopped. */ - if (!ptid_equal (ptid, null_ptid)) - { - int was_non_stop = non_stop; - struct target_waitstatus status; - - stop_thread (ptid); - non_stop = 1; - mywait (ptid, &status, 0, 0); - non_stop = was_non_stop; - } - - if (fd >= 0) - { - if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf, - (unsigned char *) cmd, CMD_BUF_SIZE)) - { - warning ("Error reading command response"); - } - else - { - err = 0; - trace_debug ("run_inferior_command: response: %s", cmd); - } - } + err = agent_run_command (pid, (const char *) cmd); reinsert_all_breakpoints (); unpause_all (0); @@ -6584,24 +6410,22 @@ run_inferior_command (char *cmd) return err; } -#else /* HAVE_UST */ +#else /* !IN_PROCESS_AGENT */ -static int -run_inferior_command (char *cmd) -{ - return -1; -} +#include <sys/socket.h> +#include <sys/un.h> -#endif /* HAVE_UST */ +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path) +#endif -#else /* !IN_PROCESS_AGENT */ +/* Where we put the socked used for synchronization. */ +#define SOCK_DIR P_tmpdir /* Thread ID of the helper thread. GDBserver reads this to know which is the help thread. This is an LWP id on Linux. */ int helper_thread_id; -#ifdef HAVE_UST - static int init_named_socket (const char *name) { @@ -6654,7 +6478,7 @@ init_named_socket (const char *name) } static int -gdb_ust_socket_init (void) +gdb_agent_socket_init (void) { int result, fd; char name[UNIX_PATH_MAX]; @@ -6676,17 +6500,7 @@ gdb_ust_socket_init (void) return fd; } -/* Return an hexstr version of the STR C string, fit for sending to - GDB. */ - -static char * -cstr_to_hexstr (const char *str) -{ - int len = strlen (str); - char *hexstr = xmalloc (len * 2 + 1); - convert_int_to_ascii ((gdb_byte *) str, hexstr, len); - return hexstr; -} +#ifdef HAVE_UST /* The next marker to be returned on a qTsSTM command. */ static const struct marker *next_st; @@ -6726,6 +6540,18 @@ next_marker (const struct marker *m) return NULL; } +/* Return an hexstr version of the STR C string, fit for sending to + GDB. */ + +static char * +cstr_to_hexstr (const char *str) +{ + int len = strlen (str); + char *hexstr = xmalloc (len * 2 + 1); + convert_int_to_ascii ((gdb_byte *) str, hexstr, len); + return hexstr; +} + /* Compose packet that is the response to the qTsSTM/qTfSTM/qTSTMat packets. */ @@ -6886,16 +6712,29 @@ cmd_qtstmat (char *packet) return -1; } +static void +gdb_ust_init (void) +{ + if (!dlsym_ust ()) + return; + + USTF(ltt_probe_register) (&gdb_ust_probe); +} + +#endif /* HAVE_UST */ + #include <sys/syscall.h> +/* Helper thread of agent. */ + static void * -gdb_ust_thread (void *arg) +gdb_agent_helper_thread (void *arg) { int listen_fd; while (1) { - listen_fd = gdb_ust_socket_init (); + listen_fd = gdb_agent_socket_init (); if (helper_thread_id == 0) helper_thread_id = syscall (SYS_gettid); @@ -6945,6 +6784,7 @@ gdb_ust_thread (void *arg) if (cmd_buf[0]) { +#ifdef HAVE_UST if (strcmp ("qTfSTM", cmd_buf) == 0) { cmd_qtfstm (cmd_buf); @@ -6971,12 +6811,7 @@ gdb_ust_thread (void *arg) { cmd_qtstmat (cmd_buf); } - else if (strcmp (cmd_buf, "help") == 0) - { - strcpy (cmd_buf, "for help, press F1\n"); - } - else - strcpy (cmd_buf, ""); +#endif /* HAVE_UST */ } /* Fix compiler's warning: ignoring return value of 'write'. */ @@ -6989,18 +6824,16 @@ gdb_ust_thread (void *arg) } #include <signal.h> +#include <pthread.h> static void -gdb_ust_init (void) +gdb_agent_init (void) { int res; pthread_t thread; sigset_t new_mask; sigset_t orig_mask; - if (!dlsym_ust ()) - return; - /* We want the helper thread to be as transparent as possible, so have it inherit an all-signals-blocked mask. */ @@ -7011,7 +6844,7 @@ gdb_ust_init (void) res = pthread_create (&thread, NULL, - gdb_ust_thread, + gdb_agent_helper_thread, NULL); res = pthread_sigmask (SIG_SETMASK, &orig_mask, NULL); @@ -7021,11 +6854,11 @@ gdb_ust_init (void) while (helper_thread_id == 0) usleep (1); - USTF(ltt_probe_register) (&gdb_ust_probe); +#ifdef HAVE_UST + gdb_ust_init (); +#endif } -#endif /* HAVE_UST */ - #include <sys/mman.h> #include <fcntl.h> @@ -7056,9 +6889,7 @@ initialize_tracepoint_ftlib (void) { initialize_tracepoint (); -#ifdef HAVE_UST - gdb_ust_init (); -#endif + gdb_agent_init (); } #endif /* IN_PROCESS_AGENT */ |