xref: /dragonfly/contrib/gdb-7/gdb/probe.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
1 /* Generic static probe support for GDB.
2 
3    Copyright (C) 2012-2013 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 #include "probe.h"
22 #include "command.h"
23 #include "cli/cli-cmds.h"
24 #include "cli/cli-utils.h"
25 #include "objfiles.h"
26 #include "symtab.h"
27 #include "progspace.h"
28 #include "filenames.h"
29 #include "exceptions.h"
30 #include "linespec.h"
31 #include "gdb_regex.h"
32 #include "frame.h"
33 #include "arch-utils.h"
34 #include <ctype.h>
35 
36 
37 
38 /* See definition in probe.h.  */
39 
40 struct symtabs_and_lines
parse_probes(char ** argptr,struct linespec_result * canonical)41 parse_probes (char **argptr, struct linespec_result *canonical)
42 {
43   char *arg_start, *arg_end, *arg;
44   char *objfile_name = NULL, *provider = NULL, *name, *p;
45   struct cleanup *cleanup;
46   struct symtabs_and_lines result;
47   struct objfile *objfile;
48   struct program_space *pspace;
49   const struct probe_ops *probe_ops;
50   const char *cs;
51 
52   result.sals = NULL;
53   result.nelts = 0;
54 
55   arg_start = *argptr;
56 
57   cs = *argptr;
58   probe_ops = probe_linespec_to_ops (&cs);
59   gdb_assert (probe_ops != NULL);
60 
61   arg = (char *) cs;
62   arg = skip_spaces (arg);
63   if (!*arg)
64     error (_("argument to `%s' missing"), arg_start);
65 
66   arg_end = skip_to_space (arg);
67 
68   /* We make a copy here so we can write over parts with impunity.  */
69   arg = savestring (arg, arg_end - arg);
70   cleanup = make_cleanup (xfree, arg);
71 
72   /* Extract each word from the argument, separated by ":"s.  */
73   p = strchr (arg, ':');
74   if (p == NULL)
75     {
76       /* This is `-p name'.  */
77       name = arg;
78     }
79   else
80     {
81       char *hold = p + 1;
82 
83       *p = '\0';
84       p = strchr (hold, ':');
85       if (p == NULL)
86           {
87             /* This is `-p provider:name'.  */
88             provider = arg;
89             name = hold;
90           }
91       else
92           {
93             /* This is `-p objfile:provider:name'.  */
94             *p = '\0';
95             objfile_name = arg;
96             provider = hold;
97             name = p + 1;
98           }
99     }
100 
101   if (*name == '\0')
102     error (_("no probe name specified"));
103   if (provider && *provider == '\0')
104     error (_("invalid provider name"));
105   if (objfile_name && *objfile_name == '\0')
106     error (_("invalid objfile name"));
107 
108   ALL_PSPACES (pspace)
109     ALL_PSPACE_OBJFILES (pspace, objfile)
110       {
111           VEC (probe_p) *probes;
112           struct probe *probe;
113           int ix;
114 
115           if (!objfile->sf || !objfile->sf->sym_probe_fns)
116             continue;
117 
118           if (objfile_name
119               && FILENAME_CMP (objfile->name, objfile_name) != 0
120               && FILENAME_CMP (lbasename (objfile->name), objfile_name) != 0)
121             continue;
122 
123           probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
124 
125           for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
126             {
127               struct symtab_and_line *sal;
128 
129               if (probe_ops != &probe_ops_any && probe->pops != probe_ops)
130                 continue;
131 
132               if (provider && strcmp (probe->provider, provider) != 0)
133                 continue;
134 
135               if (strcmp (probe->name, name) != 0)
136                 continue;
137 
138               ++result.nelts;
139               result.sals = xrealloc (result.sals,
140                                             result.nelts
141                                             * sizeof (struct symtab_and_line));
142               sal = &result.sals[result.nelts - 1];
143 
144               init_sal (sal);
145 
146               sal->pc = probe->address;
147               sal->explicit_pc = 1;
148               sal->section = find_pc_overlay (sal->pc);
149               sal->pspace = pspace;
150               sal->probe = probe;
151             }
152       }
153 
154   if (result.nelts == 0)
155     {
156       throw_error (NOT_FOUND_ERROR,
157                        _("No probe matching objfile=`%s', provider=`%s', name=`%s'"),
158                        objfile_name ? objfile_name : _("<any>"),
159                        provider ? provider : _("<any>"),
160                        name);
161     }
162 
163   if (canonical)
164     {
165       canonical->special_display = 1;
166       canonical->pre_expanded = 1;
167       canonical->addr_string = savestring (*argptr, arg_end - *argptr);
168     }
169 
170   *argptr = arg_end;
171   do_cleanups (cleanup);
172 
173   return result;
174 }
175 
176 /* See definition in probe.h.  */
177 
VEC(probe_p)178 VEC (probe_p) *
179 find_probes_in_objfile (struct objfile *objfile, const char *provider,
180                               const char *name)
181 {
182   VEC (probe_p) *probes, *result = NULL;
183   int ix;
184   struct probe *probe;
185 
186   if (!objfile->sf || !objfile->sf->sym_probe_fns)
187     return NULL;
188 
189   probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
190   for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
191     {
192       if (strcmp (probe->provider, provider) != 0)
193           continue;
194 
195       if (strcmp (probe->name, name) != 0)
196           continue;
197 
198       VEC_safe_push (probe_p, result, probe);
199     }
200 
201   return result;
202 }
203 
204 /* See definition in probe.h.  */
205 
206 struct probe *
find_probe_by_pc(CORE_ADDR pc)207 find_probe_by_pc (CORE_ADDR pc)
208 {
209   struct objfile *objfile;
210 
211   ALL_OBJFILES (objfile)
212   {
213     VEC (probe_p) *probes;
214     int ix;
215     struct probe *probe;
216 
217     if (!objfile->sf || !objfile->sf->sym_probe_fns)
218       continue;
219 
220     /* If this proves too inefficient, we can replace with a hash.  */
221     probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
222     for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
223       if (probe->address == pc)
224           return probe;
225   }
226 
227   return NULL;
228 }
229 
230 
231 
232 /* A helper function for collect_probes that compiles a regexp and
233    throws an exception on error.  This installs a cleanup to free the
234    resulting pattern on success.  If RX is NULL, this does nothing.  */
235 
236 static void
compile_rx_or_error(regex_t * pattern,const char * rx,const char * message)237 compile_rx_or_error (regex_t *pattern, const char *rx, const char *message)
238 {
239   int code;
240 
241   if (!rx)
242     return;
243 
244   code = regcomp (pattern, rx, REG_NOSUB);
245   if (code == 0)
246     make_regfree_cleanup (pattern);
247   else
248     {
249       char *err = get_regcomp_error (code, pattern);
250 
251       make_cleanup (xfree, err);
252       error (("%s: %s"), message, err);
253     }
254 }
255 
256 /* Make a vector of probes matching OBJNAME, PROVIDER, and PROBE_NAME.
257    If POPS is not NULL, only probes of this certain probe_ops will match.
258    Each argument is a regexp, or NULL, which matches anything.  */
259 
VEC(probe_p)260 static VEC (probe_p) *
261 collect_probes (char *objname, char *provider, char *probe_name,
262                     const struct probe_ops *pops)
263 {
264   struct objfile *objfile;
265   VEC (probe_p) *result = NULL;
266   struct cleanup *cleanup, *cleanup_temps;
267   regex_t obj_pat, prov_pat, probe_pat;
268 
269   cleanup = make_cleanup (VEC_cleanup (probe_p), &result);
270 
271   cleanup_temps = make_cleanup (null_cleanup, NULL);
272   compile_rx_or_error (&prov_pat, provider, _("Invalid provider regexp"));
273   compile_rx_or_error (&probe_pat, probe_name, _("Invalid probe regexp"));
274   compile_rx_or_error (&obj_pat, objname, _("Invalid object file regexp"));
275 
276   ALL_OBJFILES (objfile)
277     {
278       VEC (probe_p) *probes;
279       struct probe *probe;
280       int ix;
281 
282       if (! objfile->sf || ! objfile->sf->sym_probe_fns)
283           continue;
284 
285       if (objname)
286           {
287             if (regexec (&obj_pat, objfile->name, 0, NULL, 0) != 0)
288               continue;
289           }
290 
291       probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
292 
293       for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
294           {
295             if (pops != NULL && probe->pops != pops)
296               continue;
297 
298             if (provider
299                 && regexec (&prov_pat, probe->provider, 0, NULL, 0) != 0)
300               continue;
301 
302             if (probe_name
303                 && regexec (&probe_pat, probe->name, 0, NULL, 0) != 0)
304               continue;
305 
306             VEC_safe_push (probe_p, result, probe);
307           }
308     }
309 
310   do_cleanups (cleanup_temps);
311   discard_cleanups (cleanup);
312   return result;
313 }
314 
315 /* A qsort comparison function for probe_p objects.  */
316 
317 static int
compare_probes(const void * a,const void * b)318 compare_probes (const void *a, const void *b)
319 {
320   const struct probe *pa = *((const struct probe **) a);
321   const struct probe *pb = *((const struct probe **) b);
322   int v;
323 
324   v = strcmp (pa->provider, pb->provider);
325   if (v)
326     return v;
327 
328   v = strcmp (pa->name, pb->name);
329   if (v)
330     return v;
331 
332   if (pa->address < pb->address)
333     return -1;
334   if (pa->address > pb->address)
335     return 1;
336 
337   return strcmp (pa->objfile->name, pb->objfile->name);
338 }
339 
340 /* Helper function that generate entries in the ui_out table being
341    crafted by `info_probes_for_ops'.  */
342 
343 static void
gen_ui_out_table_header_info(VEC (probe_p)* probes,const struct probe_ops * p)344 gen_ui_out_table_header_info (VEC (probe_p) *probes,
345                                     const struct probe_ops *p)
346 {
347   /* `headings' refers to the names of the columns when printing `info
348      probes'.  */
349   VEC (info_probe_column_s) *headings = NULL;
350   struct cleanup *c;
351   info_probe_column_s *column;
352   size_t headings_size;
353   int ix;
354 
355   gdb_assert (p != NULL);
356 
357   if (p->gen_info_probes_table_header == NULL
358       && p->gen_info_probes_table_values == NULL)
359     return;
360 
361   gdb_assert (p->gen_info_probes_table_header != NULL
362                 && p->gen_info_probes_table_values != NULL);
363 
364   c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
365   p->gen_info_probes_table_header (&headings);
366 
367   headings_size = VEC_length (info_probe_column_s, headings);
368 
369   for (ix = 0;
370        VEC_iterate (info_probe_column_s, headings, ix, column);
371        ++ix)
372     {
373       struct probe *probe;
374       int jx;
375       size_t size_max = strlen (column->print_name);
376 
377       for (jx = 0; VEC_iterate (probe_p, probes, jx, probe); ++jx)
378           {
379             /* `probe_fields' refers to the values of each new field that this
380                probe will display.  */
381             VEC (const_char_ptr) *probe_fields = NULL;
382             struct cleanup *c2;
383             const char *val;
384             int kx;
385 
386             if (probe->pops != p)
387               continue;
388 
389             c2 = make_cleanup (VEC_cleanup (const_char_ptr), &probe_fields);
390             p->gen_info_probes_table_values (probe, &probe_fields);
391 
392             gdb_assert (VEC_length (const_char_ptr, probe_fields)
393                           == headings_size);
394 
395             for (kx = 0; VEC_iterate (const_char_ptr, probe_fields, kx, val);
396                  ++kx)
397               {
398                 /* It is valid to have a NULL value here, which means that the
399                      backend does not have something to write and this particular
400                      field should be skipped.  */
401                 if (val == NULL)
402                     continue;
403 
404                 size_max = max (strlen (val), size_max);
405               }
406             do_cleanups (c2);
407           }
408 
409       ui_out_table_header (current_uiout, size_max, ui_left,
410                                  column->field_name, column->print_name);
411     }
412 
413   do_cleanups (c);
414 }
415 
416 /* Helper function to print extra information about a probe and an objfile
417    represented by PROBE.  */
418 
419 static void
print_ui_out_info(struct probe * probe)420 print_ui_out_info (struct probe *probe)
421 {
422   int ix;
423   int j = 0;
424   /* `values' refers to the actual values of each new field in the output
425      of `info probe'.  `headings' refers to the names of each new field.  */
426   VEC (const_char_ptr) *values = NULL;
427   VEC (info_probe_column_s) *headings = NULL;
428   info_probe_column_s *column;
429   struct cleanup *c;
430 
431   gdb_assert (probe != NULL);
432   gdb_assert (probe->pops != NULL);
433 
434   if (probe->pops->gen_info_probes_table_header == NULL
435       && probe->pops->gen_info_probes_table_values == NULL)
436     return;
437 
438   gdb_assert (probe->pops->gen_info_probes_table_header != NULL
439                 && probe->pops->gen_info_probes_table_values != NULL);
440 
441   c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
442   make_cleanup (VEC_cleanup (const_char_ptr), &values);
443 
444   probe->pops->gen_info_probes_table_header (&headings);
445   probe->pops->gen_info_probes_table_values (probe, &values);
446 
447   gdb_assert (VEC_length (info_probe_column_s, headings)
448                 == VEC_length (const_char_ptr, values));
449 
450   for (ix = 0;
451        VEC_iterate (info_probe_column_s, headings, ix, column);
452        ++ix)
453     {
454       const char *val = VEC_index (const_char_ptr, values, j++);
455 
456       if (val == NULL)
457           ui_out_field_skip (current_uiout, column->field_name);
458       else
459           ui_out_field_string (current_uiout, column->field_name, val);
460     }
461 
462   do_cleanups (c);
463 }
464 
465 /* Helper function that returns the number of extra fields which POPS will
466    need.  */
467 
468 static int
get_number_extra_fields(const struct probe_ops * pops)469 get_number_extra_fields (const struct probe_ops *pops)
470 {
471   VEC (info_probe_column_s) *headings = NULL;
472   struct cleanup *c;
473   int n;
474 
475   if (pops->gen_info_probes_table_header == NULL)
476     return 0;
477 
478   c = make_cleanup (VEC_cleanup (info_probe_column_s), &headings);
479   pops->gen_info_probes_table_header (&headings);
480 
481   n = VEC_length (info_probe_column_s, headings);
482 
483   do_cleanups (c);
484 
485   return n;
486 }
487 
488 /* See comment in probe.h.  */
489 
490 void
info_probes_for_ops(char * arg,int from_tty,const struct probe_ops * pops)491 info_probes_for_ops (char *arg, int from_tty, const struct probe_ops *pops)
492 {
493   char *provider, *probe_name = NULL, *objname = NULL;
494   struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
495   VEC (probe_p) *probes;
496   int i, any_found;
497   int ui_out_extra_fields = 0;
498   size_t size_addr;
499   size_t size_name = strlen ("Name");
500   size_t size_objname = strlen ("Object");
501   size_t size_provider = strlen ("Provider");
502   struct probe *probe;
503   struct gdbarch *gdbarch = get_current_arch ();
504 
505   /* Do we have a `provider:probe:objfile' style of linespec?  */
506   provider = extract_arg (&arg);
507   if (provider)
508     {
509       make_cleanup (xfree, provider);
510 
511       probe_name = extract_arg (&arg);
512       if (probe_name)
513           {
514             make_cleanup (xfree, probe_name);
515 
516             objname = extract_arg (&arg);
517             if (objname)
518               make_cleanup (xfree, objname);
519           }
520     }
521 
522   if (pops == NULL)
523     {
524       const struct probe_ops *po;
525       int ix;
526 
527       /* If the probe_ops is NULL, it means the user has requested a "simple"
528            `info probes', i.e., she wants to print all information about all
529            probes.  For that, we have to identify how many extra fields we will
530            need to add in the ui_out table.
531 
532            To do that, we iterate over all probe_ops, querying each one about
533            its extra fields, and incrementing `ui_out_extra_fields' to reflect
534            that number.  */
535 
536       for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
537           ui_out_extra_fields += get_number_extra_fields (po);
538     }
539   else
540     ui_out_extra_fields = get_number_extra_fields (pops);
541 
542   probes = collect_probes (objname, provider, probe_name, pops);
543   make_cleanup (VEC_cleanup (probe_p), &probes);
544   make_cleanup_ui_out_table_begin_end (current_uiout,
545                                                4 + ui_out_extra_fields,
546                                                VEC_length (probe_p, probes),
547                                                "StaticProbes");
548 
549   if (!VEC_empty (probe_p, probes))
550     qsort (VEC_address (probe_p, probes), VEC_length (probe_p, probes),
551              sizeof (probe_p), compare_probes);
552 
553   /* What's the size of an address in our architecture?  */
554   size_addr = gdbarch_addr_bit (gdbarch) == 64 ? 18 : 10;
555 
556   /* Determining the maximum size of each field (`provider', `name' and
557      `objname').  */
558   for (i = 0; VEC_iterate (probe_p, probes, i, probe); ++i)
559     {
560       size_name = max (strlen (probe->name), size_name);
561       size_provider = max (strlen (probe->provider), size_provider);
562       size_objname = max (strlen (probe->objfile->name), size_objname);
563     }
564 
565   ui_out_table_header (current_uiout, size_provider, ui_left, "provider",
566                            _("Provider"));
567   ui_out_table_header (current_uiout, size_name, ui_left, "name", _("Name"));
568   ui_out_table_header (current_uiout, size_addr, ui_left, "addr", _("Where"));
569 
570   if (pops == NULL)
571     {
572       const struct probe_ops *po;
573       int ix;
574 
575       /* We have to generate the table header for each new probe type that we
576            will print.  */
577       for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po); ++ix)
578           gen_ui_out_table_header_info (probes, po);
579     }
580   else
581     gen_ui_out_table_header_info (probes, pops);
582 
583   ui_out_table_header (current_uiout, size_objname, ui_left, "object",
584                            _("Object"));
585   ui_out_table_body (current_uiout);
586 
587   for (i = 0; VEC_iterate (probe_p, probes, i, probe); ++i)
588     {
589       struct cleanup *inner;
590 
591       inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe");
592 
593       ui_out_field_string (current_uiout, "provider", probe->provider);
594       ui_out_field_string (current_uiout, "name", probe->name);
595       ui_out_field_core_addr (current_uiout, "addr",
596                                     get_objfile_arch (probe->objfile),
597                                     probe->address);
598 
599       if (pops == NULL)
600           {
601             const struct probe_ops *po;
602             int ix;
603 
604             for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, po);
605                  ++ix)
606               if (probe->pops == po)
607                 print_ui_out_info (probe);
608           }
609       else
610           print_ui_out_info (probe);
611 
612       ui_out_field_string (current_uiout, "object", probe->objfile->name);
613       ui_out_text (current_uiout, "\n");
614 
615       do_cleanups (inner);
616     }
617 
618   any_found = !VEC_empty (probe_p, probes);
619   do_cleanups (cleanup);
620 
621   if (!any_found)
622     ui_out_message (current_uiout, 0, _("No probes matched.\n"));
623 }
624 
625 /* Implementation of the `info probes' command.  */
626 
627 static void
info_probes_command(char * arg,int from_tty)628 info_probes_command (char *arg, int from_tty)
629 {
630   info_probes_for_ops (arg, from_tty, NULL);
631 }
632 
633 /* See comments in probe.h.  */
634 
635 struct value *
probe_safe_evaluate_at_pc(struct frame_info * frame,unsigned n)636 probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
637 {
638   struct probe *probe;
639   const struct sym_probe_fns *probe_fns;
640   unsigned n_args;
641 
642   probe = find_probe_by_pc (get_frame_pc (frame));
643   if (!probe)
644     return NULL;
645 
646   gdb_assert (probe->objfile != NULL);
647   gdb_assert (probe->objfile->sf != NULL);
648   gdb_assert (probe->objfile->sf->sym_probe_fns != NULL);
649 
650   probe_fns = probe->objfile->sf->sym_probe_fns;
651   n_args = probe_fns->sym_get_probe_argument_count (probe);
652 
653   if (n >= n_args)
654     return NULL;
655 
656   return probe_fns->sym_evaluate_probe_argument (probe, n);
657 }
658 
659 /* See comment in probe.h.  */
660 
661 const struct probe_ops *
probe_linespec_to_ops(const char ** linespecp)662 probe_linespec_to_ops (const char **linespecp)
663 {
664   int ix;
665   const struct probe_ops *probe_ops;
666 
667   for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, probe_ops); ix++)
668     if (probe_ops->is_linespec (linespecp))
669       return probe_ops;
670 
671   return NULL;
672 }
673 
674 /* See comment in probe.h.  */
675 
676 int
probe_is_linespec_by_keyword(const char ** linespecp,const char * const * keywords)677 probe_is_linespec_by_keyword (const char **linespecp, const char *const *keywords)
678 {
679   const char *s = *linespecp;
680   const char *const *csp;
681 
682   for (csp = keywords; *csp; csp++)
683     {
684       const char *keyword = *csp;
685       size_t len = strlen (keyword);
686 
687       if (strncmp (s, keyword, len) == 0 && isspace (s[len]))
688           {
689             *linespecp += len + 1;
690             return 1;
691           }
692     }
693 
694   return 0;
695 }
696 
697 /* Implementation of `is_linespec' method for `struct probe_ops'.  */
698 
699 static int
probe_any_is_linespec(const char ** linespecp)700 probe_any_is_linespec (const char **linespecp)
701 {
702   static const char *const keywords[] = { "-p", "-probe", NULL };
703 
704   return probe_is_linespec_by_keyword (linespecp, keywords);
705 }
706 
707 /* Dummy method used for `probe_ops_any'.  */
708 
709 static void
probe_any_get_probes(VEC (probe_p)** probesp,struct objfile * objfile)710 probe_any_get_probes (VEC (probe_p) **probesp, struct objfile *objfile)
711 {
712   /* No probes can be provided by this dummy backend.  */
713 }
714 
715 /* Operations associated with a generic probe.  */
716 
717 const struct probe_ops probe_ops_any =
718 {
719   probe_any_is_linespec,
720   probe_any_get_probes,
721 };
722 
723 /* See comments in probe.h.  */
724 
725 struct cmd_list_element **
info_probes_cmdlist_get(void)726 info_probes_cmdlist_get (void)
727 {
728   static struct cmd_list_element *info_probes_cmdlist;
729 
730   if (info_probes_cmdlist == NULL)
731     add_prefix_cmd ("probes", class_info, info_probes_command,
732                         _("\
733 Show available static probes.\n\
734 Usage: info probes [all|TYPE [ARGS]]\n\
735 TYPE specifies the type of the probe, and can be one of the following:\n\
736   - stap\n\
737 If you specify TYPE, there may be additional arguments needed by the\n\
738 subcommand.\n\
739 If you do not specify any argument, or specify `all', then the command\n\
740 will show information about all types of probes."),
741                         &info_probes_cmdlist, "info probes ",
742                         0/*allow-unknown*/, &infolist);
743 
744   return &info_probes_cmdlist;
745 }
746 
747 VEC (probe_ops_cp) *all_probe_ops;
748 
749 void _initialize_probe (void);
750 
751 void
_initialize_probe(void)752 _initialize_probe (void)
753 {
754   VEC_safe_push (probe_ops_cp, all_probe_ops, &probe_ops_any);
755 
756   add_cmd ("all", class_info, info_probes_command,
757              _("\
758 Show information about all type of probes."),
759              info_probes_cmdlist_get ());
760 }
761