X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fremote.c;h=fd89f2c0840afd4a661e69472ab849db6a7d6cb8;hb=bd920864f3dc2cad376989a642ab774aef6b2fce;hp=5db406e045c171abda255a38a654c864aeb21ca2;hpb=0743fc83c03da263953dfc393a66744a08770365;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote.c b/gdb/remote.c index 5db406e045..fd89f2c084 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -2493,8 +2493,9 @@ remote_target::remote_notice_new_inferior (ptid_t currthread, int executing) thread_change_ptid (this, inferior_ptid, currthread); else { - remote_add_thread (currthread, running, executing); - inferior_ptid = currthread; + thread_info *thr + = remote_add_thread (currthread, running, executing); + switch_to_thread (thr); } return; } @@ -2615,8 +2616,7 @@ remote_target::pass_signals (gdb::array_view pass_signals) putpkt (pass_packet); getpkt (&rs->buf, 0); packet_ok (rs->buf, &remote_protocol_packets[PACKET_QPassSignals]); - if (rs->last_pass_packet) - xfree (rs->last_pass_packet); + xfree (rs->last_pass_packet); rs->last_pass_packet = pass_packet; } else @@ -3785,6 +3785,18 @@ remote_target::remote_get_threads_with_qthreadinfo (threads_listing_context *con return 0; } +/* Return true if INF only has one non-exited thread. */ + +static bool +has_single_non_exited_thread (inferior *inf) +{ + int count = 0; + for (thread_info *tp ATTRIBUTE_UNUSED : inf->non_exited_threads ()) + if (++count > 1) + break; + return count == 1; +} + /* Implement the to_update_thread_list function for the remote targets. */ @@ -3824,6 +3836,14 @@ remote_target::update_thread_list () if (!context.contains_thread (tp->ptid)) { + /* Do not remove the thread if it is the last thread in + the inferior. This situation happens when we have a + pending exit process status to process. Otherwise we + may end up with a seemingly live inferior (i.e. pid + != 0) that has no threads. */ + if (has_single_non_exited_thread (tp->inf)) + continue; + /* Not found. */ delete_thread (tp); } @@ -4085,7 +4105,6 @@ remote_target::get_offsets () char *ptr; int lose, num_segments = 0, do_sections, do_segments; CORE_ADDR text_addr, data_addr, bss_addr, segments[2]; - struct symfile_segment_data *data; if (symfile_objfile == NULL) return; @@ -4165,7 +4184,8 @@ remote_target::get_offsets () section_offsets offs = symfile_objfile->section_offsets; - data = get_symfile_segment_data (symfile_objfile->obfd); + symfile_segment_data_up data + = get_symfile_segment_data (symfile_objfile->obfd); do_segments = (data != NULL); do_sections = num_segments == 0; @@ -4178,10 +4198,10 @@ remote_target::get_offsets () by assuming that the .text and .data offsets apply to the whole text and data segments. Convert the offsets given in the packet to base addresses for symfile_map_offsets_to_segments. */ - else if (data && data->num_segments == 2) + else if (data != nullptr && data->segments.size () == 2) { - segments[0] = data->segment_bases[0] + text_addr; - segments[1] = data->segment_bases[1] + data_addr; + segments[0] = data->segments[0].base + text_addr; + segments[1] = data->segments[1].base + data_addr; num_segments = 2; } /* If the object file has only one segment, assume that it is text @@ -4189,9 +4209,9 @@ remote_target::get_offsets () but programs with no code are useless. Of course the code might have ended up in the data segment... to detect that we would need the permissions here. */ - else if (data && data->num_segments == 1) + else if (data && data->segments.size () == 1) { - segments[0] = data->segment_bases[0] + text_addr; + segments[0] = data->segments[0].base + text_addr; num_segments = 1; } /* There's no way to relocate by segment. */ @@ -4200,8 +4220,9 @@ remote_target::get_offsets () if (do_segments) { - int ret = symfile_map_offsets_to_segments (symfile_objfile->obfd, data, - offs, num_segments, segments); + int ret = symfile_map_offsets_to_segments (symfile_objfile->obfd, + data.get (), offs, + num_segments, segments); if (ret == 0 && !do_sections) error (_("Can not handle qOffsets TextSeg " @@ -4211,9 +4232,6 @@ remote_target::get_offsets () do_sections = 0; } - if (data) - free_symfile_segment_data (data); - if (do_sections) { offs[SECT_OFF_TEXT (symfile_objfile)] = text_addr; @@ -4329,9 +4347,10 @@ remote_target::add_current_inferior_and_thread (char *wait_status) struct remote_state *rs = get_remote_state (); bool fake_pid_p = false; - inferior_ptid = null_ptid; + switch_to_no_thread (); - /* Now, if we have thread information, update inferior_ptid. */ + /* Now, if we have thread information, update the current thread's + ptid. */ ptid_t curr_ptid = get_current_thread (wait_status); if (curr_ptid != null_ptid) @@ -5743,7 +5762,7 @@ remote_target::remote_detach_1 (inferior *inf, int from_tty) } else { - inferior_ptid = null_ptid; + switch_to_no_thread (); detach_inferior (current_inferior ()); } } @@ -5889,33 +5908,33 @@ extended_remote_target::attach (const char *args, int from_tty) target_pid_to_str (ptid_t (pid)).c_str ()); } - set_current_inferior (remote_add_inferior (false, pid, 1, 0)); + switch_to_inferior_no_thread (remote_add_inferior (false, pid, 1, 0)); inferior_ptid = ptid_t (pid); if (target_is_non_stop_p ()) { - struct thread_info *thread; - /* Get list of threads. */ update_thread_list (); - thread = first_thread_of_inferior (current_inferior ()); - if (thread) - inferior_ptid = thread->ptid; - else - inferior_ptid = ptid_t (pid); + thread_info *thread = first_thread_of_inferior (current_inferior ()); + if (thread != nullptr) + switch_to_thread (thread); /* Invalidate our notion of the remote current thread. */ record_currthread (rs, minus_one_ptid); } else { - /* Now, if we have thread information, update inferior_ptid. */ - inferior_ptid = remote_current_thread (inferior_ptid); + /* Now, if we have thread information, update the main thread's + ptid. */ + ptid_t curr_ptid = remote_current_thread (ptid_t (pid)); /* Add the main thread to the thread list. */ - thread_info *thr = add_thread_silent (this, inferior_ptid); + thread_info *thr = add_thread_silent (this, curr_ptid); + + switch_to_thread (thr); + /* Don't consider the thread stopped until we've processed the saved stop reply. */ set_executing (this, thr->ptid, true); @@ -14856,5 +14875,5 @@ Specify \"unlimited\" to display all the characters."), &setdebuglist, &showdebuglist); /* Eventually initialize fileio. See fileio.c */ - initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist); + initialize_remote_fileio (&remote_set_cmdlist, &remote_show_cmdlist); }