GDB (API)
|
00001 /* Generic static probe support for GDB. 00002 00003 Copyright (C) 2012-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "probe.h" 00022 #include "command.h" 00023 #include "cli/cli-cmds.h" 00024 #include "cli/cli-utils.h" 00025 #include "objfiles.h" 00026 #include "symtab.h" 00027 #include "progspace.h" 00028 #include "filenames.h" 00029 #include "exceptions.h" 00030 #include "linespec.h" 00031 #include "gdb_regex.h" 00032 #include "frame.h" 00033 #include "arch-utils.h" 00034 #include <ctype.h> 00035 00036 00037 00038 /* See definition in probe.h. */ 00039 00040 struct symtabs_and_lines 00041 parse_probes (char **argptr, struct linespec_result *canonical) 00042 { 00043 char *arg_start, *arg_end, *arg; 00044 char *objfile_namestr = NULL, *provider = NULL, *name, *p; 00045 struct cleanup *cleanup; 00046 struct symtabs_and_lines result; 00047 struct objfile *objfile; 00048 struct program_space *pspace; 00049 const struct probe_ops *probe_ops; 00050 const char *cs; 00051 00052 result.sals = NULL; 00053 result.nelts = 0; 00054 00055 arg_start = *argptr; 00056 00057 cs = *argptr; 00058 probe_ops = probe_linespec_to_ops (&cs); 00059 gdb_assert (probe_ops != NULL); 00060 00061 arg = (char *) cs; 00062 arg = skip_spaces (arg); 00063 if (!*arg) 00064 error (_("argument to `%s' missing"), arg_start); 00065 00066 arg_end = skip_to_space (arg); 00067 00068 /* We make a copy here so we can write over parts with impunity. */ 00069 arg = savestring (arg, arg_end - arg); 00070 cleanup = make_cleanup (xfree, arg); 00071 00072 /* Extract each word from the argument, separated by ":"s. */ 00073 p = strchr (arg, ':'); 00074 if (p == NULL) 00075 { 00076 /* This is `-p name'. */ 00077 name = arg; 00078 } 00079 else 00080 { 00081 char *hold = p + 1; 00082 00083 *p = '\0'; 00084 p = strchr (hold, ':'); 00085 if (p == NULL) 00086 { 00087 /* This is `-p provider:name'. */ 00088 provider = arg; 00089 name = hold; 00090 } 00091 else 00092 { 00093 /* This is `-p objfile:provider:name'. */ 00094 *p = '\0'; 00095 objfile_namestr = arg; 00096 provider = hold; 00097 name = p + 1; 00098 } 00099 } 00100 00101 if (*name == '\0') 00102 error (_("no probe name specified")); 00103 if (provider && *provider == '\0') 00104 error (_("invalid provider name")); 00105 if (objfile_namestr && *objfile_namestr == '\0') 00106 error (_("invalid objfile name")); 00107 00108 ALL_PSPACES (pspace) 00109 ALL_PSPACE_OBJFILES (pspace, objfile) 00110 { 00111 VEC (probe_p) *probes; 00112 struct probe *probe; 00113 int ix; 00114 00115 if (!objfile->sf || !objfile->sf->sym_probe_fns) 00116 continue; 00117 00118 if (objfile_namestr 00119 && FILENAME_CMP (objfile_name (objfile), objfile_namestr) != 0 00120 && FILENAME_CMP (lbasename (objfile_name (objfile)), 00121 objfile_namestr) != 0) 00122 continue; 00123 00124 probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile); 00125 00126 for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++) 00127 { 00128 struct symtab_and_line *sal; 00129 00130 if (probe_ops != &probe_ops_any && probe->pops != probe_ops) 00131 continue; 00132 00133 if (provider && strcmp (probe->provider, provider) != 0) 00134 continue; 00135 00136 if (strcmp (probe->name, name) != 0) 00137 continue; 00138 00139 ++result.nelts; 00140 result.sals = xrealloc (result.sals, 00141 result.nelts 00142 * sizeof (struct symtab_and_line)); 00143 sal = &result.sals[result.nelts - 1]; 00144 00145 init_sal (sal); 00146 00147 sal->pc = probe->address; 00148 sal->explicit_pc = 1; 00149 sal->section = find_pc_overlay (sal->pc); 00150 sal->pspace = pspace; 00151 sal->probe = probe; 00152 } 00153 } 00154 00155 if (result.nelts == 0) 00156 { 00157 throw_error (NOT_FOUND_ERROR, 00158 _("No probe matching objfile=`%s', provider=`%s', name=`%s'"), 00159 objfile_namestr ? objfile_namestr : _("<any>"), 00160 provider ? provider : _("<any>"), 00161 name); 00162 } 00163 00164 if (canonical) 00165 { 00166 canonical->special_display = 1; 00167 canonical->pre_expanded = 1; 00168 canonical->addr_string = savestring (*argptr, arg_end - *argptr); 00169 } 00170 00171 *argptr = arg_end; 00172 do_cleanups (cleanup); 00173 00174 return result; 00175 } 00176 00177 /* See definition in probe.h. */ 00178 00179 VEC (probe_p) * 00180 find_probes_in_objfile (struct objfile *objfile, const char *provider, 00181 const char *name) 00182 { 00183 VEC (probe_p) *probes, *result = NULL; 00184 int ix; 00185 struct probe *probe; 00186 00187 if (!objfile->sf || !objfile->sf->sym_probe_fns) 00188 return NULL; 00189 00190 probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile); 00191 for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++) 00192 { 00193 if (strcmp (probe->provider, provider) != 0) 00194 continue; 00195 00196 if (strcmp (probe->name, name) != 0) 00197 continue; 00198 00199 VEC_safe_push (probe_p, result, probe); 00200 } 00201 00202 return result; 00203 } 00204 00205 /* See definition in probe.h. */ 00206 00207 struct probe * 00208 find_probe_by_pc (CORE_ADDR pc) 00209 { 00210 struct objfile *objfile; 00211 00212 ALL_OBJFILES (objfile) 00213 { 00214 VEC (probe_p) *probes; 00215 int ix; 00216 struct probe *probe; 00217 00218 if (!objfile->sf || !objfile->sf->sym_probe_fns) 00219 continue; 00220 00221 /* If this proves too inefficient, we can replace with a hash. */ 00222 probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile); 00223 for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++) 00224 if (probe->address == pc) 00225 return probe; 00226 } 00227 00228 return NULL; 00229 } 00230 00231 00232 00233 /* Make a vector of probes matching OBJNAME, PROVIDER, and PROBE_NAME. 00234 If POPS is not NULL, only probes of this certain probe_ops will match. 00235 Each argument is a regexp, or NULL, which matches anything. */ 00236 00237 static VEC (probe_p) * 00238 collect_probes (char *objname, char *provider, char *probe_name, 00239 const struct probe_ops *pops) 00240 { 00241 struct objfile *objfile; 00242 VEC (probe_p) *result = NULL; 00243 struct cleanup *cleanup, *cleanup_temps; 00244 regex_t obj_pat, prov_pat, probe_pat; 00245 00246 cleanup = make_cleanup (VEC_cleanup (probe_p), &result); 00247 00248 cleanup_temps = make_cleanup (null_cleanup, NULL); 00249 if (provider != NULL) 00250 compile_rx_or_error (&prov_pat, provider, _("Invalid provider regexp")); 00251 if (probe_name != NULL) 00252 compile_rx_or_error (&probe_pat, probe_name, _("Invalid probe regexp")); 00253 if (objname != NULL) 00254 compile_rx_or_error (&obj_pat, objname, _("Invalid object file regexp")); 00255 00256 ALL_OBJFILES (objfile) 00257 { 00258 VEC (probe_p) *probes; 00259 struct probe *probe; 00260 int ix; 00261 00262 if (! objfile->sf || ! objfile->sf->sym_probe_fns) 00263 continue; 00264 00265 if (objname) 00266 { 00267 if (regexec (&obj_pat, objfile_name (objfile), 0, NULL, 0) != 0) 00268 continue; 00269 } 00270 00271 probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile); 00272 00273 for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++) 00274 { 00275 if (pops != NULL && probe->pops != pops) 00276 continue; 00277 00278 if (provider 00279 && regexec (&prov_pat, probe->provider, 0, NULL, 0) != 0) 00280 continue; 00281 00282 if (probe_name 00283 && regexec (&probe_pat, probe->name, 0, NULL, 0) != 0) 00284 continue; 00285 00286 VEC_safe_push (probe_p, result, probe); 00287 } 00288 } 00289 00290 do_cleanups (cleanup_temps); 00291 discard_cleanups (cleanup); 00292 return result; 00293 } 00294 00295 /* A qsort comparison function for probe_p objects. */ 00296 00297 static int 00298 compare_probes (const void *a, const void *b) 00299 { 00300 const struct probe *pa = *((const struct probe **) a); 00301 const struct probe *pb = *((const struct probe **) b); 00302 int v; 00303 00304 v = strcmp (pa->provider, pb->provider); 00305 if (v) 00306 return v; 00307 00308 v = strcmp (pa->name, pb->name); 00309 if (v) 00310 return v; 00311 00312 if (pa->address < pb->address) 00313 return -1; 00314 if (pa->address > pb->address) 00315 return 1; 00316 00317 return strcmp (objfile_name (pa->objfile), objfile_name (pb->objfile)); 00318 } 00319 00320 /* Helper function that generate entries in the ui_out table being 00321 crafted by `info_probes_for_ops'. */ 00322 00323 static void 00324 gen_ui_out_table_header_info (VEC (probe_p) *probes, 00325 const struct probe_ops *p) 00326 { 00327 /* `headings' refers to the names of the columns when printing `info 00328 probes'. */ 00329 VEC (info_probe_column_s) *headings = NULL; 00330 struct cleanup *c; 00331 info_probe_column_s *column; 00332 size_t headings_size; 00333 int ix; 00334 00335 gdb_assert (p != NULL); 00336 00337 if (p->gen_info_probes_table_header == NULL 00338 && p->gen_info_probes_table_values == NULL) 00339 return; 00340 00341 gdb_assert (p->gen_info_probes_table_header != NULL 00342 && p->gen_info_probes_table_values != NULL); 00343 00344 c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings); 00345 p->gen_info_probes_table_header (&headings); 00346 00347 headings_size = VEC_length (info_probe_column_s, headings); 00348 00349 for (ix = 0; 00350 VEC_iterate (info_probe_column_s, headings, ix, column); 00351 ++ix) 00352 { 00353 struct probe *probe; 00354 int jx; 00355 size_t size_max = strlen (column->print_name); 00356 00357 for (jx = 0; VEC_iterate (probe_p, probes, jx, probe); ++jx) 00358 { 00359 /* `probe_fields' refers to the values of each new field that this 00360 probe will display. */ 00361 VEC (const_char_ptr) *probe_fields = NULL; 00362 struct cleanup *c2; 00363 const char *val; 00364 int kx; 00365 00366 if (probe->pops != p) 00367 continue; 00368 00369 c2 = make_cleanup (VEC_cleanup (const_char_ptr), &probe_fields); 00370 p->gen_info_probes_table_values (probe, &probe_fields); 00371 00372 gdb_assert (VEC_length (const_char_ptr, probe_fields) 00373 == headings_size); 00374 00375 for (kx = 0; VEC_iterate (const_char_ptr, probe_fields, kx, val); 00376 ++kx) 00377 { 00378 /* It is valid to have a NULL value here, which means that the 00379 backend does not have something to write and this particular 00380 field should be skipped. */ 00381 if (val == NULL) 00382 continue; 00383 00384 size_max = max (strlen (val), size_max); 00385 } 00386 do_cleanups (c2); 00387 } 00388 00389 ui_out_table_header (current_uiout, size_max, ui_left, 00390 column->field_name, column->print_name); 00391 } 00392 00393 do_cleanups (c); 00394 } 00395 00396 /* Helper function to print extra information about a probe and an objfile 00397 represented by PROBE. */ 00398 00399 static void 00400 print_ui_out_info (struct probe *probe) 00401 { 00402 int ix; 00403 int j = 0; 00404 /* `values' refers to the actual values of each new field in the output 00405 of `info probe'. `headings' refers to the names of each new field. */ 00406 VEC (const_char_ptr) *values = NULL; 00407 VEC (info_probe_column_s) *headings = NULL; 00408 info_probe_column_s *column; 00409 struct cleanup *c; 00410 00411 gdb_assert (probe != NULL); 00412 gdb_assert (probe->pops != NULL); 00413 00414 if (probe->pops->gen_info_probes_table_header == NULL 00415 && probe->pops->gen_info_probes_table_values == NULL) 00416 return; 00417 00418 gdb_assert (probe->pops->gen_info_probes_table_header != NULL 00419 && probe->pops->gen_info_probes_table_values != NULL); 00420 00421 c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings); 00422 make_cleanup (VEC_cleanup (const_char_ptr), &values); 00423 00424 probe->pops->gen_info_probes_table_header (&headings); 00425 probe->pops->gen_info_probes_table_values (probe, &values); 00426 00427 gdb_assert (VEC_length (info_probe_column_s, headings) 00428 == VEC_length (const_char_ptr, values)); 00429 00430 for (ix = 0; 00431 VEC_iterate (info_probe_column_s, headings, ix, column); 00432 ++ix) 00433 { 00434 const char *val = VEC_index (const_char_ptr, values, j++); 00435 00436 if (val == NULL) 00437 ui_out_field_skip (current_uiout, column->field_name); 00438 else 00439 ui_out_field_string (current_uiout, column->field_name, val); 00440 } 00441 00442 do_cleanups (c); 00443 } 00444 00445 /* Helper function that returns the number of extra fields which POPS will 00446 need. */ 00447 00448 static int 00449 get_number_extra_fields (const struct probe_ops *pops) 00450 { 00451 VEC (info_probe_column_s) *headings = NULL; 00452 struct cleanup *c; 00453 int n; 00454 00455 if (pops->gen_info_probes_table_header == NULL) 00456 return 0; 00457 00458 c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings); 00459 pops->gen_info_probes_table_header (&headings); 00460 00461 n = VEC_length (info_probe_column_s, headings); 00462 00463 do_cleanups (c); 00464 00465 return n; 00466 } 00467 00468 /* See comment in probe.h. */ 00469 00470 void 00471 info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops) 00472 { 00473 char *provider, *probe_name = NULL, *objname = NULL; 00474 struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); 00475 VEC (probe_p) *probes; 00476 int i, any_found; 00477 int ui_out_extra_fields = 0; 00478 size_t size_addr; 00479 size_t size_name = strlen ("Name"); 00480 size_t size_objname = strlen ("Object"); 00481 size_t size_provider = strlen ("Provider"); 00482 struct probe *probe; 00483 struct gdbarch *gdbarch = get_current_arch (); 00484 00485 /* Do we have a `provider:probe:objfile' style of linespec? */ 00486 provider = extract_arg (&arg); 00487 if (provider) 00488 { 00489 make_cleanup (xfree, provider); 00490 00491 probe_name = extract_arg (&arg); 00492 if (probe_name) 00493 { 00494 make_cleanup (xfree, probe_name); 00495 00496 objname = extract_arg (&arg); 00497 if (objname) 00498 make_cleanup (xfree, objname); 00499 } 00500 } 00501 00502 if (pops == NULL) 00503 { 00504 const struct probe_ops *po; 00505 int ix; 00506 00507 /* If the probe_ops is NULL, it means the user has requested a "simple" 00508 `info probes', i.e., she wants to print all information about all 00509 probes. For that, we have to identify how many extra fields we will 00510 need to add in the ui_out table. 00511 00512 To do that, we iterate over all probe_ops, querying each one about 00513 its extra fields, and incrementing `ui_out_extra_fields' to reflect 00514 that number. */ 00515 00516 for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix) 00517 ui_out_extra_fields += get_number_extra_fields (po); 00518 } 00519 else 00520 ui_out_extra_fields = get_number_extra_fields (pops); 00521 00522 probes = collect_probes (objname, provider, probe_name, pops); 00523 make_cleanup (VEC_cleanup (probe_p), &probes); 00524 make_cleanup_ui_out_table_begin_end (current_uiout, 00525 4 + ui_out_extra_fields, 00526 VEC_length (probe_p, probes), 00527 "StaticProbes"); 00528 00529 if (!VEC_empty (probe_p, probes)) 00530 qsort (VEC_address (probe_p, probes), VEC_length (probe_p, probes), 00531 sizeof (probe_p), compare_probes); 00532 00533 /* What's the size of an address in our architecture? */ 00534 size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10; 00535 00536 /* Determining the maximum size of each field (`provider', `name' and 00537 `objname'). */ 00538 for (i = 0; VEC_iterate (probe_p, probes, i, probe); ++i) 00539 { 00540 size_name = max (strlen (probe->name), size_name); 00541 size_provider = max (strlen (probe->provider), size_provider); 00542 size_objname = max (strlen (objfile_name (probe->objfile)), size_objname); 00543 } 00544 00545 ui_out_table_header (current_uiout, size_provider, ui_left, "provider", 00546 _("Provider")); 00547 ui_out_table_header (current_uiout, size_name, ui_left, "name", _("Name")); 00548 ui_out_table_header (current_uiout, size_addr, ui_left, "addr", _("Where")); 00549 00550 if (pops == NULL) 00551 { 00552 const struct probe_ops *po; 00553 int ix; 00554 00555 /* We have to generate the table header for each new probe type that we 00556 will print. */ 00557 for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix) 00558 gen_ui_out_table_header_info (probes, po); 00559 } 00560 else 00561 gen_ui_out_table_header_info (probes, pops); 00562 00563 ui_out_table_header (current_uiout, size_objname, ui_left, "object", 00564 _("Object")); 00565 ui_out_table_body (current_uiout); 00566 00567 for (i = 0; VEC_iterate (probe_p, probes, i, probe); ++i) 00568 { 00569 struct cleanup *inner; 00570 00571 inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe"); 00572 00573 ui_out_field_string (current_uiout, "provider", probe->provider); 00574 ui_out_field_string (current_uiout, "name", probe->name); 00575 ui_out_field_core_addr (current_uiout, "addr", 00576 get_objfile_arch (probe->objfile), 00577 probe->address); 00578 00579 if (pops == NULL) 00580 { 00581 const struct probe_ops *po; 00582 int ix; 00583 00584 for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); 00585 ++ix) 00586 if (probe->pops == po) 00587 print_ui_out_info (probe); 00588 } 00589 else 00590 print_ui_out_info (probe); 00591 00592 ui_out_field_string (current_uiout, "object", 00593 objfile_name (probe->objfile)); 00594 ui_out_text (current_uiout, "\n"); 00595 00596 do_cleanups (inner); 00597 } 00598 00599 any_found = !VEC_empty (probe_p, probes); 00600 do_cleanups (cleanup); 00601 00602 if (!any_found) 00603 ui_out_message (current_uiout, 0, _("No probes matched.\n")); 00604 } 00605 00606 /* Implementation of the `info probes' command. */ 00607 00608 static void 00609 info_probes_command (char *arg, int from_tty) 00610 { 00611 info_probes_for_ops (arg, from_tty, NULL); 00612 } 00613 00614 /* See comments in probe.h. */ 00615 00616 unsigned 00617 get_probe_argument_count (struct probe *probe) 00618 { 00619 const struct sym_probe_fns *probe_fns; 00620 00621 gdb_assert (probe->objfile != NULL); 00622 gdb_assert (probe->objfile->sf != NULL); 00623 00624 probe_fns = probe->objfile->sf->sym_probe_fns; 00625 00626 gdb_assert (probe_fns != NULL); 00627 00628 return probe_fns->sym_get_probe_argument_count (probe); 00629 } 00630 00631 /* See comments in probe.h. */ 00632 00633 int 00634 can_evaluate_probe_arguments (struct probe *probe) 00635 { 00636 const struct sym_probe_fns *probe_fns; 00637 00638 gdb_assert (probe->objfile != NULL); 00639 gdb_assert (probe->objfile->sf != NULL); 00640 00641 probe_fns = probe->objfile->sf->sym_probe_fns; 00642 00643 gdb_assert (probe_fns != NULL); 00644 00645 return probe_fns->can_evaluate_probe_arguments (probe); 00646 } 00647 00648 /* See comments in probe.h. */ 00649 00650 struct value * 00651 evaluate_probe_argument (struct probe *probe, unsigned n) 00652 { 00653 const struct sym_probe_fns *probe_fns; 00654 00655 gdb_assert (probe->objfile != NULL); 00656 gdb_assert (probe->objfile->sf != NULL); 00657 00658 probe_fns = probe->objfile->sf->sym_probe_fns; 00659 00660 gdb_assert (probe_fns != NULL); 00661 00662 return probe_fns->sym_evaluate_probe_argument (probe, n); 00663 } 00664 00665 /* See comments in probe.h. */ 00666 00667 struct value * 00668 probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n) 00669 { 00670 struct probe *probe; 00671 unsigned n_args; 00672 00673 probe = find_probe_by_pc (get_frame_pc (frame)); 00674 if (!probe) 00675 return NULL; 00676 00677 n_args = get_probe_argument_count (probe); 00678 if (n >= n_args) 00679 return NULL; 00680 00681 return evaluate_probe_argument (probe, n); 00682 } 00683 00684 /* See comment in probe.h. */ 00685 00686 const struct probe_ops * 00687 probe_linespec_to_ops (const char **linespecp) 00688 { 00689 int ix; 00690 const struct probe_ops *probe_ops; 00691 00692 for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, probe_ops); ix++) 00693 if (probe_ops->is_linespec (linespecp)) 00694 return probe_ops; 00695 00696 return NULL; 00697 } 00698 00699 /* See comment in probe.h. */ 00700 00701 int 00702 probe_is_linespec_by_keyword (const char **linespecp, const char *const *keywords) 00703 { 00704 const char *s = *linespecp; 00705 const char *const *csp; 00706 00707 for (csp = keywords; *csp; csp++) 00708 { 00709 const char *keyword = *csp; 00710 size_t len = strlen (keyword); 00711 00712 if (strncmp (s, keyword, len) == 0 && isspace (s[len])) 00713 { 00714 *linespecp += len + 1; 00715 return 1; 00716 } 00717 } 00718 00719 return 0; 00720 } 00721 00722 /* Implementation of `is_linespec' method for `struct probe_ops'. */ 00723 00724 static int 00725 probe_any_is_linespec (const char **linespecp) 00726 { 00727 static const char *const keywords[] = { "-p", "-probe", NULL }; 00728 00729 return probe_is_linespec_by_keyword (linespecp, keywords); 00730 } 00731 00732 /* Dummy method used for `probe_ops_any'. */ 00733 00734 static void 00735 probe_any_get_probes (VEC (probe_p) **probesp, struct objfile *objfile) 00736 { 00737 /* No probes can be provided by this dummy backend. */ 00738 } 00739 00740 /* Operations associated with a generic probe. */ 00741 00742 const struct probe_ops probe_ops_any = 00743 { 00744 probe_any_is_linespec, 00745 probe_any_get_probes, 00746 }; 00747 00748 /* See comments in probe.h. */ 00749 00750 struct cmd_list_element ** 00751 info_probes_cmdlist_get (void) 00752 { 00753 static struct cmd_list_element *info_probes_cmdlist; 00754 00755 if (info_probes_cmdlist == NULL) 00756 add_prefix_cmd ("probes", class_info, info_probes_command, 00757 _("\ 00758 Show available static probes.\n\ 00759 Usage: info probes [all|TYPE [ARGS]]\n\ 00760 TYPE specifies the type of the probe, and can be one of the following:\n\ 00761 - stap\n\ 00762 If you specify TYPE, there may be additional arguments needed by the\n\ 00763 subcommand.\n\ 00764 If you do not specify any argument, or specify `all', then the command\n\ 00765 will show information about all types of probes."), 00766 &info_probes_cmdlist, "info probes ", 00767 0/*allow-unknown*/, &infolist); 00768 00769 return &info_probes_cmdlist; 00770 } 00771 00772 VEC (probe_ops_cp) *all_probe_ops; 00773 00774 void _initialize_probe (void); 00775 00776 void 00777 _initialize_probe (void) 00778 { 00779 VEC_safe_push (probe_ops_cp, all_probe_ops, &probe_ops_any); 00780 00781 add_cmd ("all", class_info, info_probes_command, 00782 _("\ 00783 Show information about all type of probes."), 00784 info_probes_cmdlist_get ()); 00785 }