int thread_db_handle_monitor_command (char *mon) { const char *cmd = "set libthread-db-search-path"; size_t cmd_len = strlen (cmd); if (strncmp (mon, cmd, cmd_len) == 0 && (mon[cmd_len] == '\0' || mon[cmd_len] == ' ')) { const char *cp = mon + cmd_len; if (libthread_db_search_path != NULL) free (libthread_db_search_path); /* Skip leading space (if any). */ while (isspace (*cp)) ++cp; if (*cp == '\0') cp = LIBTHREAD_DB_SEARCH_PATH; libthread_db_search_path = xstrdup (cp); monitor_output ("libthread-db-search-path set to `"); monitor_output (libthread_db_search_path); monitor_output ("'\n"); return 1; } /* Tell server.c to perform default processing. */ return 0; }
void monitor_show_help (void) { monitor_output ("The following monitor commands are supported:\n"); monitor_output (" set debug <0|1>\n"); monitor_output (" Enable general debugging messages\n"); monitor_output (" set remote-debug <0|1>\n"); monitor_output (" Enable remote protocol debugging messages\n"); }
static void mon_out (HChar c, void *opaque) { struct mon_out_buf *b = (struct mon_out_buf *) opaque; b->ret++; b->buf[b->next] = c; b->next++; if (b->next == DATASIZ) { b->buf[b->next] = '\0'; monitor_output(b->buf); b->next = 0; } }
UInt VG_(gdb_printf) ( const HChar *format, ... ) { struct mon_out_buf b; b.next = 0; b.ret = 0; va_list vargs; va_start(vargs, format); VG_(vcbprintf) (mon_out, &b, format, vargs); va_end(vargs); if (b.next > 0) { b.buf[b.next] = '\0'; monitor_output(b.buf); } return b.ret; }
/* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */ static void handle_output_debug_string (struct target_waitstatus *ourstatus) { #define READ_BUFFER_LEN 1024 CORE_ADDR addr; char s[READ_BUFFER_LEN + 1] = { 0 }; DWORD nbytes = current_event.u.DebugString.nDebugStringLength; if (nbytes == 0) return; if (nbytes > READ_BUFFER_LEN) nbytes = READ_BUFFER_LEN; addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData; if (current_event.u.DebugString.fUnicode) { /* The event tells us how many bytes, not chars, even in Unicode. */ WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 }; if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0) return; wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR)); } else { if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0) return; } if (strncmp (s, "cYg", 3) != 0) { if (!server_waiting) { OUTMSG2(("%s", s)); return; } monitor_output (s); } #undef READ_BUFFER_LEN }
/* Handle all of the extended 'q' packets. */ void handle_query (char *own_buf, int packet_len, int *new_packet_len_p) { static struct inferior_list_entry *thread_ptr; /* Reply the current thread id. */ if (strcmp ("qC", own_buf) == 0) { thread_ptr = all_threads.head; if (thread_ptr == NULL) strcpy (own_buf, "unset"); else sprintf (own_buf, "QC%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); return; } if (strcmp ("qSymbol::", own_buf) == 0) { if (the_target->look_up_symbols != NULL) (*the_target->look_up_symbols) (); strcpy (own_buf, "OK"); return; } if (strcmp ("qfThreadInfo", own_buf) == 0) { thread_ptr = all_threads.head; sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); thread_ptr = thread_ptr->next; return; } if (strcmp ("qsThreadInfo", own_buf) == 0) { if (thread_ptr != NULL) { sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); thread_ptr = thread_ptr->next; return; } else { sprintf (own_buf, "l"); return; } } if (the_target->read_offsets != NULL && strcmp ("qOffsets", own_buf) == 0) { CORE_ADDR text, data; if (the_target->read_offsets (&text, &data)) sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX", (long)text, (long)data, (long)data); else write_enn (own_buf); return; } if (the_target->qxfer_spu != NULL && strncmp ("qXfer:spu:read:", own_buf, 15) == 0) { char *annex; int n; unsigned int len; CORE_ADDR ofs; unsigned char *spu_buf; strcpy (own_buf, "E00"); if (decode_xfer_read (own_buf + 15, &annex, &ofs, &len) < 0) return; if (len > PBUFSIZ - 2) len = PBUFSIZ - 2; spu_buf = malloc (len + 1); if (!spu_buf) return; n = (*the_target->qxfer_spu) (annex, spu_buf, NULL, ofs, len + 1); if (n < 0) write_enn (own_buf); else if (n > len) *new_packet_len_p = write_qxfer_response (own_buf, spu_buf, len, 1); else *new_packet_len_p = write_qxfer_response (own_buf, spu_buf, n, 0); free (spu_buf); return; } if (the_target->qxfer_spu != NULL && strncmp ("qXfer:spu:write:", own_buf, 16) == 0) { char *annex; int n; unsigned int len; CORE_ADDR ofs; unsigned char *spu_buf; strcpy (own_buf, "E00"); spu_buf = malloc (packet_len - 15); if (!spu_buf) return; if (decode_xfer_write (own_buf + 16, packet_len - 16, &annex, &ofs, &len, spu_buf) < 0) { free (spu_buf); return; } n = (*the_target->qxfer_spu) (annex, NULL, (unsigned const char *)spu_buf, ofs, len); if (n < 0) write_enn (own_buf); else sprintf (own_buf, "%x", n); free (spu_buf); return; } if (the_target->read_auxv != NULL && strncmp ("qXfer:auxv:read:", own_buf, 16) == 0) { unsigned char *data; int n; CORE_ADDR ofs; unsigned int len; char *annex; /* Reject any annex; grab the offset and length. */ if (decode_xfer_read (own_buf + 16, &annex, &ofs, &len) < 0 || annex[0] != '\0') { strcpy (own_buf, "E00"); return; } /* Read one extra byte, as an indicator of whether there is more. */ if (len > PBUFSIZ - 2) len = PBUFSIZ - 2; data = malloc (len + 1); n = (*the_target->read_auxv) (ofs, data, len + 1); if (n < 0) write_enn (own_buf); else if (n > len) *new_packet_len_p = write_qxfer_response (own_buf, data, len, 1); else *new_packet_len_p = write_qxfer_response (own_buf, data, n, 0); free (data); return; } if (strncmp ("qXfer:features:read:", own_buf, 20) == 0) { CORE_ADDR ofs; unsigned int len, total_len; const char *document; char *annex; /* Check for support. */ document = get_features_xml ("target.xml"); if (document == NULL) { own_buf[0] = '\0'; return; } /* Grab the annex, offset, and length. */ if (decode_xfer_read (own_buf + 20, &annex, &ofs, &len) < 0) { strcpy (own_buf, "E00"); return; } /* Now grab the correct annex. */ document = get_features_xml (annex); if (document == NULL) { strcpy (own_buf, "E00"); return; } total_len = strlen (document); if (len > PBUFSIZ - 2) len = PBUFSIZ - 2; if (ofs > total_len) write_enn (own_buf); else if (len < total_len - ofs) *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, len, 1); else *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, total_len - ofs, 0); return; } if (strncmp ("qXfer:libraries:read:", own_buf, 21) == 0) { CORE_ADDR ofs; unsigned int len, total_len; char *document, *p; struct inferior_list_entry *dll_ptr; char *annex; /* Reject any annex; grab the offset and length. */ if (decode_xfer_read (own_buf + 21, &annex, &ofs, &len) < 0 || annex[0] != '\0') { strcpy (own_buf, "E00"); return; } /* Over-estimate the necessary memory. Assume that every character in the library name must be escaped. */ total_len = 64; for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next) total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name); document = malloc (total_len); strcpy (document, "<library-list>\n"); p = document + strlen (document); for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next) { struct dll_info *dll = (struct dll_info *) dll_ptr; char *name; strcpy (p, " <library name=\""); p = p + strlen (p); name = xml_escape_text (dll->name); strcpy (p, name); free (name); p = p + strlen (p); strcpy (p, "\"><segment address=\""); p = p + strlen (p); sprintf (p, "0x%lx", (long) dll->base_addr); p = p + strlen (p); strcpy (p, "\"/></library>\n"); p = p + strlen (p); } strcpy (p, "</library-list>\n"); total_len = strlen (document); if (len > PBUFSIZ - 2) len = PBUFSIZ - 2; if (ofs > total_len) write_enn (own_buf); else if (len < total_len - ofs) *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, len, 1); else *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, total_len - ofs, 0); free (document); return; } /* Protocol features query. */ if (strncmp ("qSupported", own_buf, 10) == 0 && (own_buf[10] == ':' || own_buf[10] == '\0')) { sprintf (own_buf, "PacketSize=%x", PBUFSIZ - 1); #if !defined (NO_PASS_SIGNALS) strcat (own_buf, ";QPassSignals+", PBUFSIZ - 1); #endif #if !defined (NO_LIBRARIES) /* We do not have any hook to indicate whether the target backend supports qXfer:libraries:read, so always report it. */ strcat (own_buf, ";qXfer:libraries:read+"); #endif strcat (own_buf, ";qXfer:memory map:read+"); if (the_target->read_auxv != NULL) strcat (own_buf, ";qXfer:auxv:read+"); if (the_target->qxfer_spu != NULL) strcat (own_buf, ";qXfer:spu:read+;qXfer:spu:write+"); if (get_features_xml ("target.xml") != NULL) strcat (own_buf, ";qXfer:features:read+"); return; } /* Thread-local storage support. */ if (the_target->get_tls_address != NULL && strncmp ("qGetTLSAddr:", own_buf, 12) == 0) { char *p = own_buf + 12; CORE_ADDR parts[3], address = 0; int i, err; for (i = 0; i < 3; i++) { char *p2; int len; if (p == NULL) break; p2 = strchr (p, ','); if (p2) { len = p2 - p; p2++; } else { len = strlen (p); p2 = NULL; } decode_address (&parts[i], p, len); p = p2; } if (p != NULL || i < 3) err = 1; else { struct thread_info *thread = gdb_id_to_thread (parts[0]); if (thread == NULL) err = 2; else err = the_target->get_tls_address (thread, parts[1], parts[2], &address); } if (err == 0) { sprintf (own_buf, "%llx", address); return; } else if (err > 0) { write_enn (own_buf); return; } /* Otherwise, pretend we do not understand this packet. */ } /* Handle "monitor" commands. */ if (strncmp ("qRcmd,", own_buf, 6) == 0) { char *mon = malloc (PBUFSIZ); int len = strlen (own_buf + 6); if ((len % 1) != 0 || unhexify (mon, own_buf + 6, len / 2) != len / 2) { write_enn (own_buf); free (mon); return; } mon[len / 2] = '\0'; write_ok (own_buf); if (strcmp (mon, "set debug 1") == 0) { debug_threads = 1; monitor_output ("Debug output enabled.\n"); } else if (strcmp (mon, "set debug 0") == 0) { debug_threads = 0; monitor_output ("Debug output disabled.\n"); } else if (strcmp (mon, "set remote-debug 1") == 0) { remote_debug = 1; monitor_output ("Protocol debug output enabled.\n"); } else if (strcmp (mon, "set remote-debug 0") == 0) { remote_debug = 0; monitor_output ("Protocol debug output disabled.\n"); } else if (strcmp (mon, "help") == 0) monitor_show_help (); else { int ok = 0; if (the_target->commands) ok = (*the_target->commands) (mon, len); else monitor_output ("Unknown monitor command.\n\n"); if (!ok) { monitor_show_help (); write_enn (own_buf); } } free (mon); return; } /* Otherwise we didn't know what packet it was. Say we didn't understand it. */ own_buf[0] = 0; }