* 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.

gdb/gdbserver:

	* 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.
This commit is contained in:
Yao Qi 2012-03-03 03:08:36 +00:00
parent 9fc0568578
commit 2fa291aca4
12 changed files with 445 additions and 233 deletions

View File

@ -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

302
gdb/common/agent.c Normal file
View File

@ -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;
}

37
gdb/common/agent.h Normal file
View File

@ -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;

View File

@ -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

2
gdb/configure vendored
View File

@ -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"

View File

@ -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>

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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 */
static int
run_inferior_command (char *cmd)
{
return -1;
}
#endif /* HAVE_UST */
#else /* !IN_PROCESS_AGENT */
#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
/* 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 */