Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 298631
b: refs/heads/master
c: 486c598
h: refs/heads/master
i:
  298629: c133b24
  298627: 9672f1e
  298623: 64bbf91
v: v3
  • Loading branch information
Jason Wessel committed Mar 29, 2012
1 parent 97e8b42 commit 5532ad0
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 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: 456ca7ff24841bf2d2a2dfd690fe7d42ef70d932
refs/heads/master: 486c5987a00a89d56c2c04c506417ef8f823ca2e
54 changes: 43 additions & 11 deletions trunk/drivers/misc/kgdbts.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ static int force_hwbrks;
static int hwbreaks_ok;
static int hw_break_val;
static int hw_break_val2;
static int cont_instead_of_sstep;
static unsigned long cont_thread_id;
static unsigned long sstep_thread_id;
#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC)
static int arch_needs_sstep_emulation = 1;
#else
Expand Down Expand Up @@ -211,7 +214,7 @@ static unsigned long lookup_addr(char *arg)
if (!strcmp(arg, "kgdbts_break_test"))
addr = (unsigned long)kgdbts_break_test;
else if (!strcmp(arg, "sys_open"))
addr = (unsigned long)sys_open;
addr = (unsigned long)do_sys_open;
else if (!strcmp(arg, "do_fork"))
addr = (unsigned long)do_fork;
else if (!strcmp(arg, "hw_break_val"))
Expand Down Expand Up @@ -283,6 +286,16 @@ static void hw_break_val_write(void)
hw_break_val++;
}

static int get_thread_id_continue(char *put_str, char *arg)
{
char *ptr = &put_str[11];

if (put_str[1] != 'T' || put_str[2] != '0')
return 1;
kgdb_hex2long(&ptr, &cont_thread_id);
return 0;
}

static int check_and_rewind_pc(char *put_str, char *arg)
{
unsigned long addr = lookup_addr(arg);
Expand Down Expand Up @@ -324,6 +337,18 @@ static int check_single_step(char *put_str, char *arg)
gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
v2printk("Singlestep stopped at IP: %lx\n",
instruction_pointer(&kgdbts_regs));

if (sstep_thread_id != cont_thread_id && !arch_needs_sstep_emulation) {
/*
* Ensure we stopped in the same thread id as before, else the
* debugger should continue until the original thread that was
* single stepped is scheduled again, emulating gdb's behavior.
*/
v2printk("ThrID does not match: %lx\n", cont_thread_id);
cont_instead_of_sstep = 1;
ts.idx -= 4;
return 0;
}
if (instruction_pointer(&kgdbts_regs) == addr) {
eprintk("kgdbts: SingleStep failed at %lx\n",
instruction_pointer(&kgdbts_regs));
Expand Down Expand Up @@ -368,7 +393,12 @@ static int got_break(char *put_str, char *arg)
static void emul_sstep_get(char *arg)
{
if (!arch_needs_sstep_emulation) {
fill_get_buf(arg);
if (cont_instead_of_sstep) {
cont_instead_of_sstep = 0;
fill_get_buf("c");
} else {
fill_get_buf(arg);
}
return;
}
switch (sstep_state) {
Expand Down Expand Up @@ -398,9 +428,11 @@ static void emul_sstep_get(char *arg)
static int emul_sstep_put(char *put_str, char *arg)
{
if (!arch_needs_sstep_emulation) {
if (!strncmp(put_str+1, arg, 2))
return 0;
return 1;
char *ptr = &put_str[11];
if (put_str[1] != 'T' || put_str[2] != '0')
return 1;
kgdb_hex2long(&ptr, &sstep_thread_id);
return 0;
}
switch (sstep_state) {
case 1:
Expand Down Expand Up @@ -502,10 +534,10 @@ static struct test_struct bad_read_test[] = {
static struct test_struct singlestep_break_test[] = {
{ "?", "S0*" }, /* Clear break points */
{ "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
{ "c", "T0*", }, /* Continue */
{ "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
{ "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
{ "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
{ "write", "OK", write_regs }, /* Write registers */
{ "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
{ "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
{ "g", "kgdbts_break_test", NULL, check_single_step },
{ "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
Expand All @@ -523,10 +555,10 @@ static struct test_struct singlestep_break_test[] = {
static struct test_struct do_fork_test[] = {
{ "?", "S0*" }, /* Clear break points */
{ "do_fork", "OK", sw_break, }, /* set sw breakpoint */
{ "c", "T0*", }, /* Continue */
{ "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
{ "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
{ "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */
{ "write", "OK", write_regs }, /* Write registers */
{ "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
{ "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
{ "g", "do_fork", NULL, check_single_step },
{ "do_fork", "OK", sw_break, }, /* set sw breakpoint */
Expand All @@ -541,10 +573,10 @@ static struct test_struct do_fork_test[] = {
static struct test_struct sys_open_test[] = {
{ "?", "S0*" }, /* Clear break points */
{ "sys_open", "OK", sw_break, }, /* set sw breakpoint */
{ "c", "T0*", }, /* Continue */
{ "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
{ "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
{ "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */
{ "write", "OK", write_regs }, /* Write registers */
{ "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
{ "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
{ "g", "sys_open", NULL, check_single_step },
{ "sys_open", "OK", sw_break, }, /* set sw breakpoint */
Expand Down

0 comments on commit 5532ad0

Please sign in to comment.