Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 107365
b: refs/heads/master
c: 25fc999
h: refs/heads/master
i:
  107363: 45adcbb
v: v3
  • Loading branch information
Jason Wessel committed Aug 1, 2008
1 parent 727d778 commit 6846958
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a9b60bf4c29e07a5a2f26a6f74937972fee9b58b
refs/heads/master: 25fc999913839a45cbb48ac7872e67f7521e7ed9
68 changes: 50 additions & 18 deletions trunk/kernel/kgdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@

static int kgdb_break_asap;

#define KGDB_MAX_THREAD_QUERY 17
struct kgdb_state {
int ex_vector;
int signo;
int err_code;
int cpu;
int pass_exception;
unsigned long thr_query;
unsigned long threadid;
long kgdb_usethreadid;
struct pt_regs *linux_regs;
Expand Down Expand Up @@ -445,9 +447,14 @@ int kgdb_hex2long(char **ptr, unsigned long *long_val)
{
int hex_val;
int num = 0;
int negate = 0;

*long_val = 0;

if (**ptr == '-') {
negate = 1;
(*ptr)++;
}
while (**ptr) {
hex_val = hex(**ptr);
if (hex_val < 0)
Expand All @@ -458,6 +465,9 @@ int kgdb_hex2long(char **ptr, unsigned long *long_val)
(*ptr)++;
}

if (negate)
*long_val = -*long_val;

return num;
}

Expand Down Expand Up @@ -527,10 +537,16 @@ static void int_to_threadref(unsigned char *id, int value)
static struct task_struct *getthread(struct pt_regs *regs, int tid)
{
/*
* Non-positive TIDs are remapped idle tasks:
* Non-positive TIDs are remapped to the cpu shadow information
*/
if (tid <= 0)
return idle_task(-tid);
if (tid == 0 || tid == -1)
tid = -atomic_read(&kgdb_active) - 2;
if (tid < 0) {
if (kgdb_info[-tid - 2].task)
return kgdb_info[-tid - 2].task;
else
return idle_task(-tid - 2);
}

/*
* find_task_by_pid_ns() does not take the tasklist lock anymore
Expand Down Expand Up @@ -737,14 +753,15 @@ static int remove_all_break(void)
}

/*
* Remap normal tasks to their real PID, idle tasks to -1 ... -NR_CPUs:
* Remap normal tasks to their real PID,
* CPU shadow threads are mapped to -CPU - 2
*/
static inline int shadow_pid(int realpid)
{
if (realpid)
return realpid;

return -1-raw_smp_processor_id();
return -raw_smp_processor_id() - 2;
}

static char gdbmsgbuf[BUFMAX + 1];
Expand Down Expand Up @@ -838,7 +855,7 @@ static void gdb_cmd_getregs(struct kgdb_state *ks)
local_debuggerinfo = kgdb_info[ks->cpu].debuggerinfo;
} else {
local_debuggerinfo = NULL;
for (i = 0; i < NR_CPUS; i++) {
for_each_online_cpu(i) {
/*
* Try to find the task on some other
* or possibly this node if we do not
Expand Down Expand Up @@ -972,10 +989,13 @@ static int gdb_cmd_reboot(struct kgdb_state *ks)
/* Handle the 'q' query packets */
static void gdb_cmd_query(struct kgdb_state *ks)
{
struct task_struct *thread;
struct task_struct *g;
struct task_struct *p;
unsigned char thref[8];
char *ptr;
int i;
int cpu;
int finished = 0;

switch (remcom_in_buffer[1]) {
case 's':
Expand All @@ -985,22 +1005,34 @@ static void gdb_cmd_query(struct kgdb_state *ks)
break;
}

if (remcom_in_buffer[1] == 'f')
ks->threadid = 1;

i = 0;
remcom_out_buffer[0] = 'm';
ptr = remcom_out_buffer + 1;

for (i = 0; i < 17; ks->threadid++) {
thread = getthread(ks->linux_regs, ks->threadid);
if (thread) {
int_to_threadref(thref, ks->threadid);
if (remcom_in_buffer[1] == 'f') {
/* Each cpu is a shadow thread */
for_each_online_cpu(cpu) {
ks->thr_query = 0;
int_to_threadref(thref, -cpu - 2);
pack_threadid(ptr, thref);
ptr += BUF_THREAD_ID_SIZE;
*(ptr++) = ',';
i++;
}
}

do_each_thread(g, p) {
if (i >= ks->thr_query && !finished) {
int_to_threadref(thref, p->pid);
pack_threadid(ptr, thref);
ptr += BUF_THREAD_ID_SIZE;
*(ptr++) = ',';
ks->thr_query++;
if (ks->thr_query % KGDB_MAX_THREAD_QUERY == 0)
finished = 1;
}
i++;
} while_each_thread(g, p);

*(--ptr) = '\0';
break;

Expand All @@ -1023,15 +1055,15 @@ static void gdb_cmd_query(struct kgdb_state *ks)
error_packet(remcom_out_buffer, -EINVAL);
break;
}
if (ks->threadid > 0) {
if ((int)ks->threadid > 0) {
kgdb_mem2hex(getthread(ks->linux_regs,
ks->threadid)->comm,
remcom_out_buffer, 16);
} else {
static char tmpstr[23 + BUF_THREAD_ID_SIZE];

sprintf(tmpstr, "Shadow task %d for pid 0",
(int)(-ks->threadid-1));
sprintf(tmpstr, "shadowCPU%d",
(int)(-ks->threadid - 2));
kgdb_mem2hex(tmpstr, remcom_out_buffer, strlen(tmpstr));
}
break;
Expand Down

0 comments on commit 6846958

Please sign in to comment.