Re: gdbstub initial code, v9

2010-09-10 Thread Oleg Nesterov
On 09/10, Roland McGrath wrote:

   Oleg == Oleg Nesterov o...@redhat.com writes:
 
  Oleg   (gdb) set var 0
 
  You need:  set variable var = 0
  The variable can be abbreviated.

 I've always just used:

   (gdb) set var=0

No, I tried this too, doesn't work.

(gdb) set var=0
A syntax error in expression, near `=0'.

But, it turns out I choosed a bad name for the variable when
I tested the fix in unxex().

(gdb) set xxx=0

This works.

(gdb) set var var=0

This works too. I guess, when gdb sees set var it expects the
full set variable ... command.

Oleg.



Re: gdbstub initial code, v9

2010-09-10 Thread Tom Tromey
 Oleg == Oleg Nesterov o...@redhat.com writes:

 I've always just used:
 (gdb) set var=0

Oleg No, I tried this too, doesn't work.
Oleg   (gdb) set var=0
Oleg   A syntax error in expression, near `=0'.

Yeah, it is ambiguous if the actual variable name conflicts with any gdb
set subcommand.

I typically just use call or print.

Tom



Re: gdbstub initial code, v9

2010-09-09 Thread Jan Kratochvil
Hi Oleg,

kernel-devel-2.6.34.6-54.fc13.x86_64 (real F13) says:

ugdb.c:1988: error: implicit declaration of function ‘hex_to_bin’


Jan



Re: gdbstub initial code, v9

2010-09-09 Thread Oleg Nesterov
On 09/09, Frank Ch. Eigler wrote:

 Oleg Nesterov o...@redhat.com writes:

  [...]
  But, Jan. Implementing the memory writes does not mean breakpoints
  automatically start to work!

 It approximately should though.

  Yes, gdb writes cc, and yes the tracee reports SIGTRAP. But after
  that continue does nothing except $c, and the tracee naturally
  gets SIGILL. I expected that, since ugdb doesn't even know the code
  was changed, gdb should write the original byte back before continue,
  but this doesn't happen.

 In normal all-stop mode,

Currently ugdb only supports non-stop

 gdb does normally replace the old
 instruction, in order to single-step over it with the 's' packet.

Yes, probably single-stepping is needed... I am still trying to
understand how this works with gdbserver, but I see vCont:s packets.

 Perhaps you're testing some buggy non-stop aspect that only works
 with 'Z' breakpoint management packets?

No. Just a trivial test-case which printfs in a loop.

 A fuller packet trace
 would help explain.

Please see below. But the only important part is:

$M4005ba,1:cc   --- set bp
$c  --- resume

of course, this can't work.

Full trace:

= qSupported:multiprocess+
= PacketSize=400;QStartNoAckMode+;QNonStop+;multiprocess+;QPassS...
= QStartNoAckMode
= OK
= !
= OK
= Hgp0.0
= E01
= QNonStop:1
= OK
= qfThreadInfo
= E01
= ?
= OK
= qSymbol::
=
= vAttach;95b
= OK
= qfThreadInfo
= mp95b.95b
= qsThreadInfo
= l
= Hgp95b.95b
= OK
= vCont?
= vCont;t
= vCont;t:p95b.-1
= OK
= %Stop:T00thread:p95b.95b;
= vStopped
= OK
= g
= fcfd90ad5329ff7f00...
= m600880,8
= 403c6d7d007f
= m7f007d6d3c48,8
= 00106d7d007f
= m7f007d6d1000,28
= f6e04c7d007fe807600080156d7d007f00...
= m7f007d6d1580,28
= 00f0ef29ff7ff6e04c7d007f50f45f29ff7f00c06c7d007f00...
= m7f007d4ce0f4,4
= 090a0069
= m7f007d6cc000,28
= 0030167d007f781f6d7d007f400b4b7d007fe8346d7d007f00...
= m7f007d6d1f78,4
= 2f6c6962
= m7f007d6d1f7c,4
= 2f6c6962
= m7f007d6d1f80,4
= 632e736f
= m7f007d6d1f84,4
= 2e36
= m7f007d6d34e8,28
= 00704b7d007f0002482e6d7d007f00...
= m400200,4
= 2f6c6962
= m400204,4
= 2f6c642d
= m400208,4
= 6c696e75
= m40020c,4
= 782d7838
= m400210,4
= 362d3634
= m400214,4
= 2e736f2e
= m400218,4
= 3200
= m7f007d6d3c40,4
= 0100
= m7f007d6d3c48,8
= 00106d7d007f
= m7f007d6d3c50,8
= c04e4c7d007f
= Z0,7f007d4c4ec0,1
=
= m7f007d4c4ec0,1
= f3
= X7f007d4c4ec0,0:
=
= M7f007d4c4ec0,1:cc
= OK
= m600880,8
= 403c6d7d007f
= m7f007d6d3c48,8
= 00106d7d007f
= m7f007d6d1000,28
= f6e04c7d007fe807600080156d7d007f00...
= m7f007d6d1580,28
= 00f0ef29ff7ff6e04c7d007f50f45f29ff7f00c06c7d007f00...
= m7f007d4ce0f4,4
= 090a0069
= m7f007d6cc000,28
= 0030167d007f781f6d7d007f400b4b7d007fe8346d7d007f00...
= m7f007d6d1f78,4
= 2f6c6962
= m7f007d6d1f7c,4
= 2f6c6962
= m7f007d6d1f80,4
= 632e736f
= m7f007d6d1f84,4
= 2e36
= m7f007d6d34e8,28
= 00704b7d007f0002482e6d7d007f00...
= m400200,4
= 2f6c6962
= m400204,4
= 2f6c642d
= m400208,4
= 6c696e75
= m40020c,4
= 782d7838
= m400210,4
= 362d3634
= m400214,4
= 2e736f2e
= m400218,4
= 3200
= m7f007d6d3c40,4
= 0100
= vCont;t:p95b.-1
= OK
= m7f007d201f40,1
= 48
= m7f007d201f40,1
= 48
= g
= fcfd90ad5329ff7f00...
= m7f007d201f40,1
= 48
= m7f007d201f40,1
= 48
= m40056c,12
= 554889e5e8e3fe89c6ba0700bfdc
= m40056c,1
= 55
= m40056d,3
= 4889e5
= m40056c,12
= 554889e5e8e3fe89c6ba0700bfdc
= m40056c,1
= 55
= m40056d,3
= 4889e5
= m4005ba,1
= e8
= m4005ba,1
= e8

(gdb) b BP.c:13
Breakpoint 1 at 0x4005ba: file BP.c, 

Re: gdbstub initial code, v9

2010-09-09 Thread Oleg Nesterov
On 09/09, Oleg Nesterov wrote:

 the tracee hits this bp and reports SIGTRAP

   = vStopped
   = OK
   = g
   = 00064000401f207d007f00...
   = P10=ba054000
   =
   = G00064000401f207d007f0...
   =

May be this can explain...

Probably I need to implement G/P first, otherwise gdb can't change ip.

Still, I'd appreciate if someone can explain me what gdb needs/expects
to handle breakpoints before I start to read the sources.

Oleg.



Re: gdbstub initial code, v9

2010-09-09 Thread Frank Ch. Eigler
Hi -

On Thu, Sep 09, 2010 at 05:50:47PM +0200, Oleg Nesterov wrote:

 Probably I need to implement G/P first, otherwise gdb can't change ip.

Perhaps.

 Still, I'd appreciate if someone can explain me what gdb needs/expects
 to handle breakpoints before I start to read the sources.

It'd be simpler if the normal all-stop mode was what you first focused
on.  That mode works fine with Z/z and with M/m based breakpoint
insertion/removal and c/s continue/singlestep.  (This stuff was all
working in the earlier gdbstub code.)

Re. non-stop mode, see
http://www.codesourcery.com/publications/non_stop_multi_threaded_debugging_in_gdb.pdf

- FChE



Re: gdbstub initial code, v9

2010-09-09 Thread Jan Kratochvil
On Thu, 09 Sep 2010 18:30:31 +0200, Oleg Nesterov wrote:
 OOPS! indeed, unhex() confuses lo and hi.

It works for 0xcc, though.

 Cough... could you tell me how can I change the variable done
 without printing it?

(gdb) help set variable 
Evaluate expression EXP and assign result to variable VAR, using assignment
syntax appropriate for the current language (VAR = EXP or VAR := EXP for
example).  VAR may be a debugger convenience variable (names starting
with $), a register (a few standard names starting with $), or an actual
variable in the program being debugged.  EXP is any valid expression.
This may usually be abbreviated to simply set.


Regards,
Jan



Re: gdbstub initial code, v9

2010-09-09 Thread Tom Tromey
 Oleg == Oleg Nesterov o...@redhat.com writes:

Oleg   (gdb) set var 0

You need:  set variable var = 0
The variable can be abbreviated.

FWIW, print, set variable, and call are basically aliases.
print just happens to print the result of the expression.

Tom



gdbstub initial code, v9

2010-09-08 Thread Oleg Nesterov
Changes:

- partly fix the multitracing problems.

  ugdb still can't work with ptrace, ptrace-utrace.c needs
  changes. But at least multiple udgb tracers can coexist,
  more or less.

  But of course they can confuse each other anyway, no matter
  what ugdb does.

- implement memory writes ($M).

- refactor memory reads to avoid the Too late to report the
  error case.

But, Jan. Implementing the memory writes does not mean breakpoints
automatically start to work!

Yes, gdb writes cc, and yes the tracee reports SIGTRAP. But after
that continue does nothing except $c, and the tracee naturally
gets SIGILL. I expected that, since ugdb doesn't even know the code
was changed, gdb should write the original byte back before continue,
but this doesn't happen.

Tried to understand how this works with gdbserver, but failed so far.
Will continue, but any hint is very much appreciated ;)

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

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

#define BUFFER_SIZE 1024
#define PACKET_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;
}

enum {
U_STOP_IDLE = 0,
U_STOP_PENDING,
U_STOP_SENT,
};

struct ugdb {
struct list_headu_processes;
struct list_headu_stopped;

int u_stop_state;

struct mutexu_mutex;
spinlock_t  u_slock;

struct ugdb_thread
*u_cur_tinfo,
*u_cur_hg,
*u_cur_hc;

wait_queue_head_t   u_wait;

int u_err;

struct pbuf u_pbuf;
charu_cbuf[PACKET_SIZE];
int u_clen;

sigset_tu_sig_ign;

unsigned int
u_no_ack:1,
u_allstop:1;
};

static inline void ugdb_ck_stopped(struct ugdb *ugdb)
{
spin_lock(ugdb-u_slock);
WARN_ON(!list_empty(ugdb-u_stopped) 
ugdb-u_stop_state == U_STOP_IDLE);
WARN_ON(list_empty(ugdb-u_stopped) 
ugdb-u_stop_state == U_STOP_PENDING);
spin_unlock(ugdb-u_slock);
}

static struct ugdb *ugdb_create(void)
{
struct ugdb *ugdb;
int err;

err = -ENODEV;
// XXX: ugly. proc_reg_open() should take care.
if (!try_module_get(THIS_MODULE))
goto out;

err = -ENOMEM;
ugdb = kzalloc(sizeof(*ugdb), GFP_KERNEL);
if (!ugdb)
goto put_module;

INIT_LIST_HEAD(ugdb-u_processes);
INIT_LIST_HEAD(ugdb-u_stopped);

mutex_init(ugdb-u_mutex);
spin_lock_init(ugdb-u_slock);

init_waitqueue_head(ugdb-u_wait);

pb_init(ugdb-u_pbuf);

return ugdb;

put_module:
module_put(THIS_MODULE);
out:
return ERR_PTR(err);
}

#define P_DETACHING (1  1)
#define P_ZOMBIE(1  2)

struct ugdb_process {
int p_pid;
int p_state;

struct list_headp_threads;

struct ugdb *p_ugdb;
struct list_headp_processes;
};

static inline bool process_alive(struct ugdb_process *process)
{
return !(process-p_state  P_ZOMBIE);
}

static inline void mark_process_dead(struct ugdb_process *process)
{
process-p_state |= P_ZOMBIE;
}

static struct ugdb_process *ugdb_create_process(struct ugdb *ugdb, int pid_nr)
{
struct ugdb_process *process;

process = kzalloc(sizeof(*process), GFP_KERNEL);
if (!process)
return NULL;

process-p_pid = pid_nr;
process-p_ugdb = ugdb;
INIT_LIST_HEAD(process-p_threads);
list_add_tail(process-p_processes, ugdb-u_processes);

return process;
}

#define T_STOP_RUN  0
#define T_STOP_REQ  (1  0)/* requested by gdb */
#define T_STOP_ALL  (1  1)/* vCont;c:pX.-1, for report_clone */
#define T_STOP_ACK  (1  2)/* visible to vStopped */
#define T_STOP_STOPPED  (1  3)/* reported as stopped to gdb */
/* TASK_TRACED + deactivated ? */

#define T_EV_NONE   0
#define T_EV_EXIT   (1  24)
#define T_EV_SIGN   (2  24)

#define T_EV_TYPE(event)((0xff  24)  (event))
#define T_EV_DATA(event)(~(0xff  24)  (event))

struct ugdb_thread {
int t_tid;
int