Re: gdbstub initial code

2010-07-16 Thread Roland McGrath
 Note that currently I am not even trying to do something meaningful
 with utrace. My only goal for now is to implement the very basic things
 like attach/detach/stop/cont/exit correctly from the remote protocol
 pov. And I want to do this rightly, then we will discuss utrace
 issues.

Ok.  I think you might need select to work on the pseudofile for gdb to be
happy.  I'm not sure on the situation about that.


Thanks,
Roland



Re: gdbstub initial code

2010-07-16 Thread Oleg Nesterov
On 07/16, Roland McGrath wrote:

  Note that currently I am not even trying to do something meaningful
  with utrace. My only goal for now is to implement the very basic things
  like attach/detach/stop/cont/exit correctly from the remote protocol
  pov. And I want to do this rightly, then we will discuss utrace
  issues.

 Ok.  I think you might need select to work on the pseudofile for gdb to be
 happy.  I'm not sure on the situation about that.

Ah, it is easy to implement ugdb_f_ops-poll(). I think. The only problem
is that gdb doesn't try to use select. Perhaps it sees S_IFREG, I didn't
check.

But, it turns out, the multithreading is not trivial, and nasty. Because,
unless I missed something a) remote protocol is very stupid, and b) gdb
is buggy.

I was going to add the threading support today, but I guess I have to
really ask the questions before I can do this. So I am attaching the
yesterday's version.

Changes:

- cleanups/fixes to make cont/^C really work

- handle tracee's exit

Oleg.
#include linux/module.h
#include linux/proc_fs.h
#include linux/utrace.h
#include linux/regset.h
#include linux/mm.h
#include asm/uaccess.h

static int d_echo;
module_param_named(echo, d_echo, bool, 0);

#define PACKET_SIZE 1024
#define BUFFER_SIZE 1024

struct pbuf {
char*cur, *pkt;
charbuf[BUFFER_SIZE];
};

static inline void pb_init(struct pbuf *pb)
{
pb-cur = pb-buf;
pb-pkt = NULL;
}

static inline int pb_size(struct pbuf *pb)
{
return pb-cur - pb-buf;
}

static inline int pb_room(struct pbuf *pb)
{
return pb-buf + BUFFER_SIZE - pb-cur;
}

static inline void pb_putc(struct pbuf *pb, char c)
{
if (WARN_ON(pb-cur = pb-buf + BUFFER_SIZE-1))
return;
*pb-cur++ = c;
}

static void pb_memcpy(struct pbuf *pb, const void *data, int size)
{
if (WARN_ON(size  pb_room(pb)))
return;
memcpy(pb-cur, data, size);
pb-cur += size;
}

static inline void pb_puts(struct pbuf *pb, const char *s)
{
pb_memcpy(pb, s, strlen(s));
}

static inline void pb_putb(struct pbuf *pb, unsigned char val)
{
static char hex[] = 0123456789abcdef;
pb_putc(pb, hex[(val  0xf0)  4]);
pb_putc(pb, hex[(val  0x0f)  0]);
}

static void pb_putbs(struct pbuf *pb, const char *data, int size)
{
while (size--)
pb_putb(pb, *data++);
}

static inline void pb_start(struct pbuf *pb)
{
WARN_ON(pb-pkt);
pb_putc(pb, '$');
pb-pkt = pb-cur;
}

static inline void pb_cancel(struct pbuf *pb)
{
if (WARN_ON(!pb-pkt))
return;

pb-cur = pb-pkt - 1;
pb-pkt = NULL;
}

static void pb_end(struct pbuf *pb)
{
unsigned char csm = 0;
char *pkt = pb-pkt;

pb-pkt = NULL;
if (WARN_ON(!pkt))
return;

while (pkt  pb-cur) {
WARN_ON(*pkt == '$' || *pkt == '#');
csm += (unsigned char)*pkt++;
}

pb_putc(pb, '#');
pb_putb(pb, csm);
}

static inline void pb_packs(struct pbuf *pb, const char *s)
{
pb_start(pb);
pb_puts(pb, s);
pb_end(pb);
}

static void __attribute__ ((format(printf, 3, 4)))
__pb_format(struct pbuf *pb, bool whole_pkt, const char *fmt, ...)
{
int room = pb_room(pb), size;
va_list args;

if (whole_pkt)
pb_start(pb);

va_start(args, fmt);
size = vsnprintf(pb-cur, room, fmt, args);
va_end(args);

if (WARN_ON(size  room))
return;

pb-cur += size;

if (whole_pkt)
pb_end(pb);
}

#define pb_printf(pb, args...)  __pb_format((pb), false, args)
#define pb_packf(pb, args...)   __pb_format((pb), true,  args)

static inline void *pb_alloc_bs(struct pbuf *pb, int size)
{
if (unlikely(pb_room(pb)  2 * size + 4))
return NULL;
return pb-cur + size;
}

static inline void *pb_alloc_tmp(struct pbuf *pb, int size)
{
if (unlikely(pb_room(pb)  size))
return NULL;
return pb-cur + BUFFER_SIZE - size;
}

static inline void pb_flush(struct pbuf *pb, int size)
{
int keep = pb_size(pb) - size;
if (keep)
memmove(pb-buf, pb-buf + size, keep);
pb-cur -= size;
}

static int pb_copy_to_user(struct pbuf *pb, char __user *ubuf, int size)
{
int copy = min(size, pb_size(pb));

if (d_echo)
printk(KERN_INFO = %.*s\n, copy, pb-buf);

if (copy_to_user(ubuf, pb-buf, copy))
return -EFAULT;

pb_flush(pb, copy);
return copy;
}

// 
// XXX: TODO: gdb is single-thread, no locking currently.
// 
#define T printk(KERN_INFO TRACE: %s:%d\n, __FUNCTION__, __LINE__)

enum {
STOP_RUN,
STOP_REQ,

Confirmação de pedido para entrar no grupo de_amigo_para_amigo

2010-07-16 Thread Yahoo! Grupos

Olá utrace-devel@redhat.com,

Recebemos sua solicitação para entrar no grupo de_amigo_para_amigo 
do Yahoo! Grupos, um serviço de comunidades online gratuito e 
super fácil de usar.

Este pedido expirará em 7 dias.

PARA ENTRAR NESTE GRUPO: 

1) Vá para o site do Yahoo! Grupos clicando neste link:

   
http://br.groups.yahoo.com/i?i=a5bdxpdjp4nszc54h4eqqwjfpv0tvhcse=utrace-devel%40redhat%2Ecom
 

  (Se não funcionar, use os comandos para cortar e colar o link acima na
   barra de endereço do seu navegador.)

-OU-

2) RESPONDA a este e-mail clicando em Responder e depois em Enviar,
   no seu programa de e-mail.

Se você não fez esta solicitação ou se não tem interesse em entrar no grupo
de_amigo_para_amigo, por favor, ignore esta mensagem.

Saudações,

Atendimento ao usuário do Yahoo! Grupos 


O uso que você faz do Yahoo! Grupos está sujeito aos 
http://br.yahoo.com/info/utos.html