From a06660f79997c37a351afbce6ce75bd0c3de1276 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 13 Jul 2005 15:02:49 +0000 Subject: [PATCH] * inferiors.c (struct thread_info): Add gdb_id. (add_thread): Add gdb_id argument. (thread_id_to_gdb_id, thread_to_gdb_id, gdb_id_to_thread_id): New. * linux-low.c (linux_create_inferior, linux_attach_lwp): Update calls to add_thread. * remote-utils.c (prepare_resume_reply: Use thread_to_gdb_id. * server.c (handle_query): Use thread_to_gdb_id. (handle_v_cont, main): Use gdb_id_to_thread_id. * server.h (add_thread): Update prototype. (thread_id_to_gdb_id, thread_to_gdb_id, gdb_id_to_thread_id): New prototypes. --- gdb/gdbserver/ChangeLog | 14 +++++++ gdb/gdbserver/inferiors.c | 42 ++++++++++++++++++++- gdb/gdbserver/linux-low.c | 4 +- gdb/gdbserver/remote-utils.c | 4 +- gdb/gdbserver/server.c | 73 +++++++++++++++++++++++++----------- gdb/gdbserver/server.h | 5 ++- 6 files changed, 115 insertions(+), 27 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 19d5e52875..1646cc2fcb 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,17 @@ +2005-07-13 Daniel Jacobowitz + + * inferiors.c (struct thread_info): Add gdb_id. + (add_thread): Add gdb_id argument. + (thread_id_to_gdb_id, thread_to_gdb_id, gdb_id_to_thread_id): New. + * linux-low.c (linux_create_inferior, linux_attach_lwp): Update + calls to add_thread. + * remote-utils.c (prepare_resume_reply: Use thread_to_gdb_id. + * server.c (handle_query): Use thread_to_gdb_id. + (handle_v_cont, main): Use gdb_id_to_thread_id. + * server.h (add_thread): Update prototype. + (thread_id_to_gdb_id, thread_to_gdb_id, gdb_id_to_thread_id): New + prototypes. + 2005-07-13 Daniel Jacobowitz * linux-low.c (fetch_register, usr_store_inferior_registers): Handle diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c index 65e5a82654..cbfede75aa 100644 --- a/gdb/gdbserver/inferiors.c +++ b/gdb/gdbserver/inferiors.c @@ -30,6 +30,7 @@ struct thread_info struct inferior_list_entry entry; void *target_data; void *regcache_data; + unsigned int gdb_id; }; struct inferior_list all_threads; @@ -102,7 +103,7 @@ remove_inferior (struct inferior_list *list, } void -add_thread (unsigned long thread_id, void *target_data) +add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id) { struct thread_info *new_thread = (struct thread_info *) malloc (sizeof (*new_thread)); @@ -118,6 +119,45 @@ add_thread (unsigned long thread_id, void *target_data) new_thread->target_data = target_data; set_inferior_regcache_data (new_thread, new_register_cache ()); + new_thread->gdb_id = gdb_id; +} + +unsigned int +thread_id_to_gdb_id (unsigned long thread_id) +{ + struct inferior_list_entry *inf = all_threads.head; + + while (inf != NULL) + { + struct thread_info *thread = get_thread (inf); + if (inf->id == thread_id) + return thread->gdb_id; + inf = inf->next; + } + + return 0; +} + +unsigned int +thread_to_gdb_id (struct thread_info *thread) +{ + return thread->gdb_id; +} + +unsigned long +gdb_id_to_thread_id (unsigned int gdb_id) +{ + struct inferior_list_entry *inf = all_threads.head; + + while (inf != NULL) + { + struct thread_info *thread = get_thread (inf); + if (thread->gdb_id == gdb_id) + return inf->id; + inf = inf->next; + } + + return 0; } static void diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 904ff6b90b..aefec5e4bf 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -160,7 +160,7 @@ linux_create_inferior (char *program, char **allargs) } new_process = add_process (pid); - add_thread (pid, new_process); + add_thread (pid, new_process, pid); return pid; } @@ -185,7 +185,7 @@ linux_attach_lwp (unsigned long pid, unsigned long tid) } new_process = (struct process_info *) add_process (pid); - add_thread (tid, new_process); + add_thread (tid, new_process, pid); /* The next time we wait for this LWP we'll see a SIGSTOP as PTRACE_ATTACH brings it to a halt. We should ignore that SIGSTOP and resume the process diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index 79792a502f..f85d26210f 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -683,6 +683,8 @@ prepare_resume_reply (char *buf, char status, unsigned char signo) { /* FIXME right place to set this? */ thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id; + unsigned int gdb_id_from_wait = thread_to_gdb_id (current_inferior); + if (debug_threads) fprintf (stderr, "Writing resume reply for %ld\n\n", thread_from_wait); /* This if (1) ought to be unnecessary. But remote_wait in GDB @@ -692,7 +694,7 @@ prepare_resume_reply (char *buf, char status, unsigned char signo) if (1 || old_thread_from_wait != thread_from_wait) { general_thread = thread_from_wait; - sprintf (buf, "thread:%lx;", thread_from_wait); + sprintf (buf, "thread:%x;", gdb_id_from_wait); buf += strlen (buf); old_thread_from_wait = thread_from_wait; } diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index b5295bbabf..dfefe2b52a 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -103,7 +103,7 @@ handle_query (char *own_buf) if (strcmp ("qfThreadInfo", own_buf) == 0) { thread_ptr = all_threads.head; - sprintf (own_buf, "m%lx", thread_ptr->id); + sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); thread_ptr = thread_ptr->next; return; } @@ -112,7 +112,7 @@ handle_query (char *own_buf) { if (thread_ptr != NULL) { - sprintf (own_buf, "m%lx", thread_ptr->id); + sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); thread_ptr = thread_ptr->next; return; } @@ -218,13 +218,21 @@ handle_v_cont (char *own_buf, char *status, int *signal) } else if (p[0] == ':') { - resume_info[i].thread = strtoul (p + 1, &q, 16); + unsigned int gdb_id = strtoul (p + 1, &q, 16); + unsigned long thread_id; + if (p == q) goto err; p = q; if (p[0] != ';' && p[0] != 0) goto err; + thread_id = gdb_id_to_thread_id (gdb_id); + if (thread_id) + resume_info[i].thread = thread_id; + else + goto err; + i++; } } @@ -431,26 +439,35 @@ main (int argc, char *argv[]) prepare_resume_reply (own_buf, status, signal); break; case 'H': - switch (own_buf[1]) + if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's') { - case 'g': - general_thread = strtoul (&own_buf[2], NULL, 16); + unsigned long gdb_id, thread_id; + + gdb_id = strtoul (&own_buf[2], NULL, 16); + thread_id = gdb_id_to_thread_id (gdb_id); + if (thread_id == 0) + { + write_enn (own_buf); + break; + } + + if (own_buf[1] == 'g') + { + general_thread = thread_id; + set_desired_inferior (1); + } + else if (own_buf[1] == 'c') + cont_thread = thread_id; + else if (own_buf[1] == 's') + step_thread = thread_id; + write_ok (own_buf); - set_desired_inferior (1); - break; - case 'c': - cont_thread = strtoul (&own_buf[2], NULL, 16); - write_ok (own_buf); - break; - case 's': - step_thread = strtoul (&own_buf[2], NULL, 16); - write_ok (own_buf); - break; - default: + } + else + { /* Silently ignore it so that gdb can extend the protocol without compatibility headaches. */ own_buf[0] = '\0'; - break; } break; case 'g': @@ -592,10 +609,22 @@ main (int argc, char *argv[]) break; } case 'T': - if (mythread_alive (strtoul (&own_buf[1], NULL, 16))) - write_ok (own_buf); - else - write_enn (own_buf); + { + unsigned long gdb_id, thread_id; + + gdb_id = strtoul (&own_buf[1], NULL, 16); + thread_id = gdb_id_to_thread_id (gdb_id); + if (thread_id == 0) + { + write_enn (own_buf); + break; + } + + if (mythread_alive (thread_id)) + write_ok (own_buf); + else + write_enn (own_buf); + } break; case 'R': /* Restarting the inferior is only supported in the diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 4b146a1cb1..0840de184b 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -97,7 +97,10 @@ extern struct thread_info *current_inferior; void remove_inferior (struct inferior_list *list, struct inferior_list_entry *entry); void remove_thread (struct thread_info *thread); -void add_thread (unsigned long thread_id, void *target_data); +void add_thread (unsigned long thread_id, void *target_data, unsigned int); +unsigned int thread_id_to_gdb_id (unsigned long); +unsigned int thread_to_gdb_id (struct thread_info *); +unsigned long gdb_id_to_thread_id (unsigned int); void clear_inferiors (void); struct inferior_list_entry *find_inferior (struct inferior_list *,