summaryrefslogtreecommitdiff
path: root/src/lwp.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2007-12-04 11:42:29 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2007-12-04 11:42:29 +0000
commit1bd9700c82f575a3661e7c2fa06ecb504bd5d0b9 (patch)
treef6cad79367539270ee1b547b6d96afb4d6bebb29 /src/lwp.c
parent37d9aeeaf8901e77a78529b12e5ad088e9d28908 (diff)
Support reading/writing to LWP file.
Diffstat (limited to 'src/lwp.c')
-rw-r--r--src/lwp.c126
1 files changed, 67 insertions, 59 deletions
diff --git a/src/lwp.c b/src/lwp.c
index 12b6a5b..53ded90 100644
--- a/src/lwp.c
+++ b/src/lwp.c
@@ -8,6 +8,7 @@
#include <dlfcn.h>
#include <bfd.h>
#include <unistd.h>
+#include <fcntl.h>
#include <execinfo.h> /* backtrace() */
#include <sys/time.h> /* gettimeofday() */
#include <sys/socket.h>
@@ -113,12 +114,12 @@ _lwp_read_time (void)
}
static gboolean
-_lwp_writen (int sk, gconstpointer _data, gsize len)
+_lwp_writen (int fd, gconstpointer _data, gsize len)
{
const gchar *data = _data;
while (len) {
- int ret = write (sk, data, len);
+ int ret = write (fd, data, len);
if (ret < 0) {
int err = errno;
switch (err) {
@@ -137,25 +138,24 @@ _lwp_writen (int sk, gconstpointer _data, gsize len)
}
static gboolean
-_lwp_write_string (int sk, const char *str, gushort offset)
+_lwp_write_string (int fd, const char *str, gushort offset)
{
gushort len;
if (offset == (gushort) -1) {
len = 0;
- return _lwp_writen (sk, &len, sizeof (len));
+ return _lwp_writen (fd, &len, sizeof (len));
} else {
str += offset;
len = strlen (str);
- return _lwp_writen (sk, &len, sizeof (len)) &&
- _lwp_writen (sk, str, len);
+ return _lwp_writen (fd, &len, sizeof (len)) &&
+ _lwp_writen (fd, str, len);
}
}
static gboolean
_lwp_write_events (const LWP_EventRecord *events, guint n_events)
{
- struct sockaddr_un addr;
- int sk;
+ int fd;
guint32 time;
pid_t pid;
guint n;
@@ -164,38 +164,46 @@ _lwp_write_events (const LWP_EventRecord *events, guint n_events)
LWP_Allocator *A;
gboolean ret = FALSE;
- env = getenv ("LWP_SOCKET");
+ env = getenv ("LWP_PATH");
if (env == NULL)
goto CLEAN_EVENTS;
- sk = socket (PF_UNIX, SOCK_STREAM, 0);
- if (sk <0)
- goto CLEAN_EVENTS;
+ if (strncmp (env, "unix:", 5) == 0) {
+ struct sockaddr_un addr;
+
+ fd = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (fd <0)
+ goto CLEAN_EVENTS;
- memset (&addr, 0, sizeof (addr));
- addr.sun_family = AF_UNIX;
- strcpy (addr.sun_path, env);
- if (connect (sk, &addr, sizeof (addr)) < 0)
- goto CLEAN_SK;
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, env + 5);
+ if (connect (fd, &addr, sizeof (addr)) < 0)
+ goto CLEAN_FD;
+ } else {
+ fd = open (env, O_WRONLY|O_CREAT|O_APPEND|O_LARGEFILE, 0666);
+ if (fd < 0)
+ goto CLEAN_EVENTS;
+ }
- if (! _lwp_writen (sk, "LWP", 4))
- goto CLEAN_SK;
+ if (! _lwp_writen (fd, "LWP", 4))
+ goto CLEAN_FD;
pid = getpid();
- if (! _lwp_writen (sk, &pid, sizeof (pid)))
- goto CLEAN_SK;
+ if (! _lwp_writen (fd, &pid, sizeof (pid)))
+ goto CLEAN_FD;
time = _lwp_read_time ();
- if (! _lwp_writen (sk, &time, sizeof (time)))
- goto CLEAN_SK;
+ if (! _lwp_writen (fd, &time, sizeof (time)))
+ goto CLEAN_FD;
/* send any new symbols */
n = 0;
for (symbol = pending_symbols; symbol != NULL; symbol = symbol->next)
n++;
- if (! _lwp_writen (sk, &n, sizeof (n)))
- goto CLEAN_SK;
+ if (! _lwp_writen (fd, &n, sizeof (n)))
+ goto CLEAN_FD;
/* XXX dlclose */
if (pending_symbols != NULL) {
@@ -206,19 +214,19 @@ _lwp_write_events (const LWP_EventRecord *events, guint n_events)
symbol = pending_symbols;
pending_symbols = symbol->next;
- ok &= _lwp_writen (sk, &symbol->eip, sizeof (symbol->eip));
- ok &= _lwp_write_string (sk, symbol->strings, symbol->function);
- ok &= _lwp_write_string (sk, symbol->strings, symbol->object);
- ok &= _lwp_write_string (sk, symbol->strings, symbol->filename);
- ok &= _lwp_write_string (sk, symbol->strings, symbol->path);
- ok &= _lwp_writen (sk, &symbol->lineno, sizeof (symbol->lineno));
+ ok &= _lwp_writen (fd, &symbol->eip, sizeof (symbol->eip));
+ ok &= _lwp_write_string (fd, symbol->strings, symbol->function);
+ ok &= _lwp_write_string (fd, symbol->strings, symbol->object);
+ ok &= _lwp_write_string (fd, symbol->strings, symbol->filename);
+ ok &= _lwp_write_string (fd, symbol->strings, symbol->path);
+ ok &= _lwp_writen (fd, &symbol->lineno, sizeof (symbol->lineno));
free (symbol->strings);
symbol->next = free_symbols;
free_symbols = symbol;
if (!ok)
- goto CLEAN_SK;
+ goto CLEAN_FD;
}
}
@@ -227,31 +235,31 @@ _lwp_write_events (const LWP_EventRecord *events, guint n_events)
for (A = pending_allocators; A != NULL; A = A->next)
n++;
- if (! _lwp_writen (sk, &n, sizeof (n)))
- goto CLEAN_SK;
+ if (! _lwp_writen (fd, &n, sizeof (n)))
+ goto CLEAN_FD;
for (A = pending_allocators; A != NULL; A = A->next) {
- if (! _lwp_writen (sk, &A->key, sizeof (A->key)) ||
- ! _lwp_writen (sk, &A->n_ips, sizeof (A->n_ips)) ||
- ! _lwp_writen (sk, A->ips, sizeof (A->ips[0]) * A->n_ips))
+ if (! _lwp_writen (fd, &A->key, sizeof (A->key)) ||
+ ! _lwp_writen (fd, &A->n_ips, sizeof (A->n_ips)) ||
+ ! _lwp_writen (fd, A->ips, sizeof (A->ips[0]) * A->n_ips))
{
- goto CLEAN_SK;
+ goto CLEAN_FD;
}
}
/* send all the recent events */
- if (! _lwp_writen (sk, &n_events, sizeof (n_events)))
- goto CLEAN_SK;
+ if (! _lwp_writen (fd, &n_events, sizeof (n_events)))
+ goto CLEAN_FD;
for (n = 0; n < n_events; n++) {
const LWP_Event *ev = &events[n].event;
char c = events[n].type;
- if (! _lwp_writen (sk, &c, 1) ||
- ! _lwp_writen (sk, &events[n].time, sizeof (events[n].time)) ||
- ! _lwp_writen (sk, &events[n].allocator, sizeof (events[n].allocator)))
+ if (! _lwp_writen (fd, &c, 1) ||
+ ! _lwp_writen (fd, &events[n].time, sizeof (events[n].time)) ||
+ ! _lwp_writen (fd, &events[n].allocator, sizeof (events[n].allocator)))
{
- goto CLEAN_SK;
+ goto CLEAN_FD;
}
switch (events[n].type) {
@@ -262,43 +270,43 @@ _lwp_write_events (const LWP_EventRecord *events, guint n_events)
break;
case LWP_MALLOC:
- if (! _lwp_writen (sk, &ev->malloc.size, sizeof (ev->malloc.size)) ||
- ! _lwp_writen (sk, &ev->malloc.addr, sizeof (ev->malloc.addr)))
+ if (! _lwp_writen (fd, &ev->malloc.size, sizeof (ev->malloc.size)) ||
+ ! _lwp_writen (fd, &ev->malloc.addr, sizeof (ev->malloc.addr)))
{
- goto CLEAN_SK;
+ goto CLEAN_FD;
}
break;
case LWP_MEMALIGN:
- if (! _lwp_writen (sk, &ev->memalign.align, sizeof (ev->memalign.align)) ||
- ! _lwp_writen (sk, &ev->memalign.size, sizeof (ev->memalign.size)) ||
- ! _lwp_writen (sk, &ev->memalign.addr, sizeof (ev->memalign.addr)))
+ if (! _lwp_writen (fd, &ev->memalign.align, sizeof (ev->memalign.align)) ||
+ ! _lwp_writen (fd, &ev->memalign.size, sizeof (ev->memalign.size)) ||
+ ! _lwp_writen (fd, &ev->memalign.addr, sizeof (ev->memalign.addr)))
{
- goto CLEAN_SK;
+ goto CLEAN_FD;
}
break;
case LWP_REALLOC:
- if (! _lwp_writen (sk, &ev->realloc.size, sizeof (ev->realloc.size)) ||
- ! _lwp_writen (sk, &ev->realloc.old_addr, sizeof (ev->realloc.old_addr)) ||
- ! _lwp_writen (sk, &ev->realloc.new_addr, sizeof (ev->realloc.new_addr)))
+ if (! _lwp_writen (fd, &ev->realloc.size, sizeof (ev->realloc.size)) ||
+ ! _lwp_writen (fd, &ev->realloc.old_addr, sizeof (ev->realloc.old_addr)) ||
+ ! _lwp_writen (fd, &ev->realloc.new_addr, sizeof (ev->realloc.new_addr)))
{
- goto CLEAN_SK;
+ goto CLEAN_FD;
}
break;
case LWP_FREE:
- if (! _lwp_writen (sk, &ev->free.addr, sizeof (ev->free.addr)))
+ if (! _lwp_writen (fd, &ev->free.addr, sizeof (ev->free.addr)))
{
- goto CLEAN_SK;
+ goto CLEAN_FD;
}
break;
}
}
ret = TRUE;
-CLEAN_SK:
- close (sk);
+CLEAN_FD:
+ close (fd);
CLEAN_EVENTS:
while (pending_symbols != NULL) {