server.c revision 130803
119370Spst/* Main code for remote server for GDB. 2130803Smarcel Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004 398944Sobrien Free Software Foundation, Inc. 419370Spst 598944Sobrien This file is part of GDB. 619370Spst 798944Sobrien This program is free software; you can redistribute it and/or modify 898944Sobrien it under the terms of the GNU General Public License as published by 998944Sobrien the Free Software Foundation; either version 2 of the License, or 1098944Sobrien (at your option) any later version. 1119370Spst 1298944Sobrien This program is distributed in the hope that it will be useful, 1398944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1498944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598944Sobrien GNU General Public License for more details. 1619370Spst 1798944Sobrien You should have received a copy of the GNU General Public License 1898944Sobrien along with this program; if not, write to the Free Software 1998944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2098944Sobrien Boston, MA 02111-1307, USA. */ 2119370Spst 2219370Spst#include "server.h" 2319370Spst 24130803Smarcel#include <unistd.h> 25130803Smarcel#include <signal.h> 26130803Smarcel#include <sys/wait.h> 27130803Smarcel 2819370Spstint cont_thread; 2919370Spstint general_thread; 30130803Smarcelint step_thread; 3119370Spstint thread_from_wait; 3219370Spstint old_thread_from_wait; 3319370Spstint extended_protocol; 34130803Smarcelint server_waiting; 35130803Smarcel 3646283Sdfrjmp_buf toplevel; 3719370Spst 38130803Smarcel/* The PID of the originally created or attached inferior. Used to 39130803Smarcel send signals to the process when GDB sends us an asynchronous interrupt 40130803Smarcel (user hitting Control-C in the client), and to wait for the child to exit 41130803Smarcel when no longer debugging it. */ 42130803Smarcel 43130803Smarcelint signal_pid; 44130803Smarcel 4546283Sdfrstatic unsigned char 4698944Sobrienstart_inferior (char *argv[], char *statusptr) 4746283Sdfr{ 48130803Smarcel signal (SIGTTOU, SIG_DFL); 49130803Smarcel signal (SIGTTIN, SIG_DFL); 5046283Sdfr 51130803Smarcel signal_pid = create_inferior (argv[0], argv); 52130803Smarcel 53130803Smarcel fprintf (stderr, "Process %s created; pid = %d\n", argv[0], 54130803Smarcel signal_pid); 55130803Smarcel 56130803Smarcel signal (SIGTTOU, SIG_IGN); 57130803Smarcel signal (SIGTTIN, SIG_IGN); 58130803Smarcel tcsetpgrp (fileno (stderr), signal_pid); 59130803Smarcel 6046283Sdfr /* Wait till we are at 1st instruction in program, return signal number. */ 61130803Smarcel return mywait (statusptr, 0); 6246283Sdfr} 6346283Sdfr 6498944Sobrienstatic int 6598944Sobrienattach_inferior (int pid, char *statusptr, unsigned char *sigptr) 6698944Sobrien{ 6798944Sobrien /* myattach should return -1 if attaching is unsupported, 6898944Sobrien 0 if it succeeded, and call error() otherwise. */ 69130803Smarcel 7098944Sobrien if (myattach (pid) != 0) 7198944Sobrien return -1; 7298944Sobrien 73130803Smarcel fprintf (stderr, "Attached; pid = %d\n", pid); 7498944Sobrien 75130803Smarcel /* FIXME - It may be that we should get the SIGNAL_PID from the 76130803Smarcel attach function, so that it can be the main thread instead of 77130803Smarcel whichever we were told to attach to. */ 78130803Smarcel signal_pid = pid; 7998944Sobrien 80130803Smarcel *sigptr = mywait (statusptr, 0); 81130803Smarcel 8298944Sobrien return 0; 8398944Sobrien} 8498944Sobrien 8546283Sdfrextern int remote_debug; 8646283Sdfr 87130803Smarcel/* Handle all of the extended 'q' packets. */ 88130803Smarcelvoid 89130803Smarcelhandle_query (char *own_buf) 90130803Smarcel{ 91130803Smarcel static struct inferior_list_entry *thread_ptr; 92130803Smarcel 93130803Smarcel if (strcmp ("qSymbol::", own_buf) == 0) 94130803Smarcel { 95130803Smarcel if (the_target->look_up_symbols != NULL) 96130803Smarcel (*the_target->look_up_symbols) (); 97130803Smarcel 98130803Smarcel strcpy (own_buf, "OK"); 99130803Smarcel return; 100130803Smarcel } 101130803Smarcel 102130803Smarcel if (strcmp ("qfThreadInfo", own_buf) == 0) 103130803Smarcel { 104130803Smarcel thread_ptr = all_threads.head; 105130803Smarcel sprintf (own_buf, "m%x", thread_ptr->id); 106130803Smarcel thread_ptr = thread_ptr->next; 107130803Smarcel return; 108130803Smarcel } 109130803Smarcel 110130803Smarcel if (strcmp ("qsThreadInfo", own_buf) == 0) 111130803Smarcel { 112130803Smarcel if (thread_ptr != NULL) 113130803Smarcel { 114130803Smarcel sprintf (own_buf, "m%x", thread_ptr->id); 115130803Smarcel thread_ptr = thread_ptr->next; 116130803Smarcel return; 117130803Smarcel } 118130803Smarcel else 119130803Smarcel { 120130803Smarcel sprintf (own_buf, "l"); 121130803Smarcel return; 122130803Smarcel } 123130803Smarcel } 124130803Smarcel 125130803Smarcel if (the_target->read_auxv != NULL 126130803Smarcel && strncmp ("qPart:auxv:read::", own_buf, 17) == 0) 127130803Smarcel { 128130803Smarcel char data[(PBUFSIZ - 1) / 2]; 129130803Smarcel CORE_ADDR ofs; 130130803Smarcel unsigned int len; 131130803Smarcel int n; 132130803Smarcel decode_m_packet (&own_buf[17], &ofs, &len); /* "OFS,LEN" */ 133130803Smarcel if (len > sizeof data) 134130803Smarcel len = sizeof data; 135130803Smarcel n = (*the_target->read_auxv) (ofs, data, len); 136130803Smarcel if (n == 0) 137130803Smarcel write_ok (own_buf); 138130803Smarcel else if (n < 0) 139130803Smarcel write_enn (own_buf); 140130803Smarcel else 141130803Smarcel convert_int_to_ascii (data, own_buf, n); 142130803Smarcel return; 143130803Smarcel } 144130803Smarcel 145130803Smarcel /* Otherwise we didn't know what packet it was. Say we didn't 146130803Smarcel understand it. */ 147130803Smarcel own_buf[0] = 0; 148130803Smarcel} 149130803Smarcel 150130803Smarcel/* Parse vCont packets. */ 151130803Smarcelvoid 152130803Smarcelhandle_v_cont (char *own_buf, char *status, unsigned char *signal) 153130803Smarcel{ 154130803Smarcel char *p, *q; 155130803Smarcel int n = 0, i = 0; 156130803Smarcel struct thread_resume *resume_info, default_action; 157130803Smarcel 158130803Smarcel /* Count the number of semicolons in the packet. There should be one 159130803Smarcel for every action. */ 160130803Smarcel p = &own_buf[5]; 161130803Smarcel while (p) 162130803Smarcel { 163130803Smarcel n++; 164130803Smarcel p++; 165130803Smarcel p = strchr (p, ';'); 166130803Smarcel } 167130803Smarcel /* Allocate room for one extra action, for the default remain-stopped 168130803Smarcel behavior; if no default action is in the list, we'll need the extra 169130803Smarcel slot. */ 170130803Smarcel resume_info = malloc ((n + 1) * sizeof (resume_info[0])); 171130803Smarcel 172130803Smarcel default_action.thread = -1; 173130803Smarcel default_action.leave_stopped = 1; 174130803Smarcel default_action.step = 0; 175130803Smarcel default_action.sig = 0; 176130803Smarcel 177130803Smarcel p = &own_buf[5]; 178130803Smarcel i = 0; 179130803Smarcel while (*p) 180130803Smarcel { 181130803Smarcel p++; 182130803Smarcel 183130803Smarcel resume_info[i].leave_stopped = 0; 184130803Smarcel 185130803Smarcel if (p[0] == 's' || p[0] == 'S') 186130803Smarcel resume_info[i].step = 1; 187130803Smarcel else if (p[0] == 'c' || p[0] == 'C') 188130803Smarcel resume_info[i].step = 0; 189130803Smarcel else 190130803Smarcel goto err; 191130803Smarcel 192130803Smarcel if (p[0] == 'S' || p[0] == 'C') 193130803Smarcel { 194130803Smarcel int sig; 195130803Smarcel sig = strtol (p + 1, &q, 16); 196130803Smarcel if (p == q) 197130803Smarcel goto err; 198130803Smarcel p = q; 199130803Smarcel 200130803Smarcel if (!target_signal_to_host_p (sig)) 201130803Smarcel goto err; 202130803Smarcel resume_info[i].sig = target_signal_to_host (sig); 203130803Smarcel } 204130803Smarcel else 205130803Smarcel { 206130803Smarcel resume_info[i].sig = 0; 207130803Smarcel p = p + 1; 208130803Smarcel } 209130803Smarcel 210130803Smarcel if (p[0] == 0) 211130803Smarcel { 212130803Smarcel resume_info[i].thread = -1; 213130803Smarcel default_action = resume_info[i]; 214130803Smarcel 215130803Smarcel /* Note: we don't increment i here, we'll overwrite this entry 216130803Smarcel the next time through. */ 217130803Smarcel } 218130803Smarcel else if (p[0] == ':') 219130803Smarcel { 220130803Smarcel resume_info[i].thread = strtol (p + 1, &q, 16); 221130803Smarcel if (p == q) 222130803Smarcel goto err; 223130803Smarcel p = q; 224130803Smarcel if (p[0] != ';' && p[0] != 0) 225130803Smarcel goto err; 226130803Smarcel 227130803Smarcel i++; 228130803Smarcel } 229130803Smarcel } 230130803Smarcel 231130803Smarcel resume_info[i] = default_action; 232130803Smarcel 233130803Smarcel /* Still used in occasional places in the backend. */ 234130803Smarcel if (n == 1 && resume_info[0].thread != -1) 235130803Smarcel cont_thread = resume_info[0].thread; 236130803Smarcel else 237130803Smarcel cont_thread = -1; 238130803Smarcel set_desired_inferior (0); 239130803Smarcel 240130803Smarcel (*the_target->resume) (resume_info); 241130803Smarcel 242130803Smarcel free (resume_info); 243130803Smarcel 244130803Smarcel *signal = mywait (status, 1); 245130803Smarcel prepare_resume_reply (own_buf, *status, *signal); 246130803Smarcel return; 247130803Smarcel 248130803Smarcelerr: 249130803Smarcel /* No other way to report an error... */ 250130803Smarcel strcpy (own_buf, ""); 251130803Smarcel free (resume_info); 252130803Smarcel return; 253130803Smarcel} 254130803Smarcel 255130803Smarcel/* Handle all of the extended 'v' packets. */ 256130803Smarcelvoid 257130803Smarcelhandle_v_requests (char *own_buf, char *status, unsigned char *signal) 258130803Smarcel{ 259130803Smarcel if (strncmp (own_buf, "vCont;", 6) == 0) 260130803Smarcel { 261130803Smarcel handle_v_cont (own_buf, status, signal); 262130803Smarcel return; 263130803Smarcel } 264130803Smarcel 265130803Smarcel if (strncmp (own_buf, "vCont?", 6) == 0) 266130803Smarcel { 267130803Smarcel strcpy (own_buf, "vCont;c;C;s;S"); 268130803Smarcel return; 269130803Smarcel } 270130803Smarcel 271130803Smarcel /* Otherwise we didn't know what packet it was. Say we didn't 272130803Smarcel understand it. */ 273130803Smarcel own_buf[0] = 0; 274130803Smarcel return; 275130803Smarcel} 276130803Smarcel 277130803Smarcelvoid 278130803Smarcelmyresume (int step, int sig) 279130803Smarcel{ 280130803Smarcel struct thread_resume resume_info[2]; 281130803Smarcel int n = 0; 282130803Smarcel 283130803Smarcel if (step || sig || cont_thread > 0) 284130803Smarcel { 285130803Smarcel resume_info[0].thread 286130803Smarcel = ((struct inferior_list_entry *) current_inferior)->id; 287130803Smarcel resume_info[0].step = step; 288130803Smarcel resume_info[0].sig = sig; 289130803Smarcel resume_info[0].leave_stopped = 0; 290130803Smarcel n++; 291130803Smarcel } 292130803Smarcel resume_info[n].thread = -1; 293130803Smarcel resume_info[n].step = 0; 294130803Smarcel resume_info[n].sig = 0; 295130803Smarcel resume_info[n].leave_stopped = (cont_thread > 0); 296130803Smarcel 297130803Smarcel (*the_target->resume) (resume_info); 298130803Smarcel} 299130803Smarcel 300130803Smarcelstatic int attached; 301130803Smarcel 302130803Smarcelstatic void 303130803Smarcelgdbserver_usage (void) 304130803Smarcel{ 305130803Smarcel error ("Usage:\tgdbserver COMM PROG [ARGS ...]\n" 306130803Smarcel "\tgdbserver COMM --attach PID\n" 307130803Smarcel "\n" 308130803Smarcel "COMM may either be a tty device (for serial debugging), or \n" 309130803Smarcel "HOST:PORT to listen for a TCP connection.\n"); 310130803Smarcel} 311130803Smarcel 31219370Spstint 31398944Sobrienmain (int argc, char *argv[]) 31419370Spst{ 31598944Sobrien char ch, status, *own_buf, mem_buf[2000]; 31619370Spst int i = 0; 31719370Spst unsigned char signal; 31846283Sdfr unsigned int len; 31946283Sdfr CORE_ADDR mem_addr; 320130803Smarcel int bad_attach; 321130803Smarcel int pid; 32298944Sobrien char *arg_end; 32319370Spst 32498944Sobrien if (setjmp (toplevel)) 32519370Spst { 32698944Sobrien fprintf (stderr, "Exiting\n"); 32798944Sobrien exit (1); 32819370Spst } 32919370Spst 330130803Smarcel bad_attach = 0; 331130803Smarcel pid = 0; 332130803Smarcel attached = 0; 33398944Sobrien if (argc >= 3 && strcmp (argv[2], "--attach") == 0) 33498944Sobrien { 33598944Sobrien if (argc == 4 33698944Sobrien && argv[3] != '\0' 33798944Sobrien && (pid = strtoul (argv[3], &arg_end, 10)) != 0 33898944Sobrien && *arg_end == '\0') 33998944Sobrien { 34098944Sobrien ; 34198944Sobrien } 34298944Sobrien else 34398944Sobrien bad_attach = 1; 34498944Sobrien } 34519370Spst 34698944Sobrien if (argc < 3 || bad_attach) 347130803Smarcel gdbserver_usage(); 34819370Spst 34998944Sobrien initialize_low (); 35019370Spst 35198944Sobrien own_buf = malloc (PBUFSIZ); 35298944Sobrien 35398944Sobrien if (pid == 0) 35498944Sobrien { 35598944Sobrien /* Wait till we are at first instruction in program. */ 35698944Sobrien signal = start_inferior (&argv[2], &status); 35798944Sobrien 35898944Sobrien /* We are now stopped at the first instruction of the target process */ 35998944Sobrien } 36098944Sobrien else 36198944Sobrien { 36298944Sobrien switch (attach_inferior (pid, &status, &signal)) 36398944Sobrien { 36498944Sobrien case -1: 36598944Sobrien error ("Attaching not supported on this target"); 36698944Sobrien break; 36798944Sobrien default: 36898944Sobrien attached = 1; 36998944Sobrien break; 37098944Sobrien } 37198944Sobrien } 37298944Sobrien 37319370Spst while (1) 37419370Spst { 37519370Spst remote_open (argv[1]); 37619370Spst 37798944Sobrien restart: 37898944Sobrien setjmp (toplevel); 37919370Spst while (getpkt (own_buf) > 0) 38019370Spst { 38119370Spst unsigned char sig; 38219370Spst i = 0; 38319370Spst ch = own_buf[i++]; 38419370Spst switch (ch) 38519370Spst { 386130803Smarcel case 'q': 387130803Smarcel handle_query (own_buf); 388130803Smarcel break; 38946283Sdfr case 'd': 39046283Sdfr remote_debug = !remote_debug; 39146283Sdfr break; 392130803Smarcel case 'D': 393130803Smarcel fprintf (stderr, "Detaching from inferior\n"); 394130803Smarcel detach_inferior (); 395130803Smarcel write_ok (own_buf); 396130803Smarcel putpkt (own_buf); 397130803Smarcel remote_close (); 398130803Smarcel 399130803Smarcel /* If we are attached, then we can exit. Otherwise, we need to 400130803Smarcel hang around doing nothing, until the child is gone. */ 401130803Smarcel if (!attached) 402130803Smarcel { 403130803Smarcel int status, ret; 404130803Smarcel 405130803Smarcel do { 406130803Smarcel ret = waitpid (signal_pid, &status, 0); 407130803Smarcel if (WIFEXITED (status) || WIFSIGNALED (status)) 408130803Smarcel break; 409130803Smarcel } while (ret != -1 || errno != ECHILD); 410130803Smarcel } 411130803Smarcel 412130803Smarcel exit (0); 413130803Smarcel 41419370Spst case '!': 41598944Sobrien if (attached == 0) 41698944Sobrien { 41798944Sobrien extended_protocol = 1; 41898944Sobrien prepare_resume_reply (own_buf, status, signal); 41998944Sobrien } 42098944Sobrien else 42198944Sobrien { 42298944Sobrien /* We can not use the extended protocol if we are 42398944Sobrien attached, because we can not restart the running 42498944Sobrien program. So return unrecognized. */ 42598944Sobrien own_buf[0] = '\0'; 42698944Sobrien } 42719370Spst break; 42819370Spst case '?': 42919370Spst prepare_resume_reply (own_buf, status, signal); 43019370Spst break; 43119370Spst case 'H': 43219370Spst switch (own_buf[1]) 43319370Spst { 43419370Spst case 'g': 43519370Spst general_thread = strtol (&own_buf[2], NULL, 16); 43619370Spst write_ok (own_buf); 437130803Smarcel set_desired_inferior (1); 43819370Spst break; 43919370Spst case 'c': 44019370Spst cont_thread = strtol (&own_buf[2], NULL, 16); 44119370Spst write_ok (own_buf); 44219370Spst break; 443130803Smarcel case 's': 444130803Smarcel step_thread = strtol (&own_buf[2], NULL, 16); 445130803Smarcel write_ok (own_buf); 446130803Smarcel break; 44719370Spst default: 44819370Spst /* Silently ignore it so that gdb can extend the protocol 44919370Spst without compatibility headaches. */ 45019370Spst own_buf[0] = '\0'; 45119370Spst break; 45219370Spst } 45319370Spst break; 45419370Spst case 'g': 455130803Smarcel set_desired_inferior (1); 45698944Sobrien registers_to_string (own_buf); 45719370Spst break; 45819370Spst case 'G': 459130803Smarcel set_desired_inferior (1); 46098944Sobrien registers_from_string (&own_buf[1]); 46119370Spst write_ok (own_buf); 46219370Spst break; 46319370Spst case 'm': 46419370Spst decode_m_packet (&own_buf[1], &mem_addr, &len); 465130803Smarcel if (read_inferior_memory (mem_addr, mem_buf, len) == 0) 466130803Smarcel convert_int_to_ascii (mem_buf, own_buf, len); 467130803Smarcel else 468130803Smarcel write_enn (own_buf); 46919370Spst break; 47019370Spst case 'M': 47119370Spst decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf); 47219370Spst if (write_inferior_memory (mem_addr, mem_buf, len) == 0) 47319370Spst write_ok (own_buf); 47419370Spst else 47519370Spst write_enn (own_buf); 47619370Spst break; 47719370Spst case 'C': 47819370Spst convert_ascii_to_int (own_buf + 1, &sig, 1); 47998944Sobrien if (target_signal_to_host_p (sig)) 48098944Sobrien signal = target_signal_to_host (sig); 48198944Sobrien else 48298944Sobrien signal = 0; 483130803Smarcel set_desired_inferior (0); 48498944Sobrien myresume (0, signal); 485130803Smarcel signal = mywait (&status, 1); 48619370Spst prepare_resume_reply (own_buf, status, signal); 48719370Spst break; 48819370Spst case 'S': 48919370Spst convert_ascii_to_int (own_buf + 1, &sig, 1); 49098944Sobrien if (target_signal_to_host_p (sig)) 49198944Sobrien signal = target_signal_to_host (sig); 49298944Sobrien else 49398944Sobrien signal = 0; 494130803Smarcel set_desired_inferior (0); 49598944Sobrien myresume (1, signal); 496130803Smarcel signal = mywait (&status, 1); 49719370Spst prepare_resume_reply (own_buf, status, signal); 49819370Spst break; 49919370Spst case 'c': 500130803Smarcel set_desired_inferior (0); 50119370Spst myresume (0, 0); 502130803Smarcel signal = mywait (&status, 1); 50319370Spst prepare_resume_reply (own_buf, status, signal); 50419370Spst break; 50519370Spst case 's': 506130803Smarcel set_desired_inferior (0); 50719370Spst myresume (1, 0); 508130803Smarcel signal = mywait (&status, 1); 50919370Spst prepare_resume_reply (own_buf, status, signal); 51019370Spst break; 51119370Spst case 'k': 51219370Spst fprintf (stderr, "Killing inferior\n"); 51319370Spst kill_inferior (); 51419370Spst /* When using the extended protocol, we start up a new 51598944Sobrien debugging session. The traditional protocol will 51619370Spst exit instead. */ 51719370Spst if (extended_protocol) 51819370Spst { 51919370Spst write_ok (own_buf); 52019370Spst fprintf (stderr, "GDBserver restarting\n"); 52119370Spst 52219370Spst /* Wait till we are at 1st instruction in prog. */ 52346283Sdfr signal = start_inferior (&argv[2], &status); 52419370Spst goto restart; 52519370Spst break; 52619370Spst } 52719370Spst else 52819370Spst { 52919370Spst exit (0); 53019370Spst break; 53119370Spst } 53219370Spst case 'T': 53319370Spst if (mythread_alive (strtol (&own_buf[1], NULL, 16))) 53419370Spst write_ok (own_buf); 53519370Spst else 53619370Spst write_enn (own_buf); 53719370Spst break; 53819370Spst case 'R': 53919370Spst /* Restarting the inferior is only supported in the 54098944Sobrien extended protocol. */ 54119370Spst if (extended_protocol) 54219370Spst { 54319370Spst kill_inferior (); 54419370Spst write_ok (own_buf); 54519370Spst fprintf (stderr, "GDBserver restarting\n"); 54619370Spst 54719370Spst /* Wait till we are at 1st instruction in prog. */ 54846283Sdfr signal = start_inferior (&argv[2], &status); 54919370Spst goto restart; 55019370Spst break; 55119370Spst } 55219370Spst else 55319370Spst { 55419370Spst /* It is a request we don't understand. Respond with an 55519370Spst empty packet so that gdb knows that we don't support this 55619370Spst request. */ 55719370Spst own_buf[0] = '\0'; 55819370Spst break; 55919370Spst } 560130803Smarcel case 'v': 561130803Smarcel /* Extended (long) request. */ 562130803Smarcel handle_v_requests (own_buf, &status, &signal); 563130803Smarcel break; 56419370Spst default: 56519370Spst /* It is a request we don't understand. Respond with an 56698944Sobrien empty packet so that gdb knows that we don't support this 56798944Sobrien request. */ 56819370Spst own_buf[0] = '\0'; 56919370Spst break; 57019370Spst } 57119370Spst 57219370Spst putpkt (own_buf); 57319370Spst 57419370Spst if (status == 'W') 57519370Spst fprintf (stderr, 576130803Smarcel "\nChild exited with status %d\n", signal); 57719370Spst if (status == 'X') 578130803Smarcel fprintf (stderr, "\nChild terminated with signal = 0x%x\n", 579130803Smarcel signal); 58019370Spst if (status == 'W' || status == 'X') 58119370Spst { 58219370Spst if (extended_protocol) 58319370Spst { 58419370Spst fprintf (stderr, "Killing inferior\n"); 58519370Spst kill_inferior (); 58619370Spst write_ok (own_buf); 58719370Spst fprintf (stderr, "GDBserver restarting\n"); 58819370Spst 58919370Spst /* Wait till we are at 1st instruction in prog. */ 59046283Sdfr signal = start_inferior (&argv[2], &status); 59119370Spst goto restart; 59219370Spst break; 59319370Spst } 59419370Spst else 59519370Spst { 59619370Spst fprintf (stderr, "GDBserver exiting\n"); 59719370Spst exit (0); 59819370Spst } 59919370Spst } 60019370Spst } 60119370Spst 60219370Spst /* We come here when getpkt fails. 60319370Spst 60498944Sobrien For the extended remote protocol we exit (and this is the only 60598944Sobrien way we gracefully exit!). 60619370Spst 60798944Sobrien For the traditional remote protocol close the connection, 60898944Sobrien and re-open it at the top of the loop. */ 60919370Spst if (extended_protocol) 61019370Spst { 61119370Spst remote_close (); 61219370Spst exit (0); 61319370Spst } 61419370Spst else 61519370Spst { 61698944Sobrien fprintf (stderr, "Remote side has terminated connection. " 61798944Sobrien "GDBserver will reopen the connection.\n"); 61819370Spst remote_close (); 61919370Spst } 62019370Spst } 62119370Spst} 622