Fix syscall group completion
[deliverable/binutils-gdb.git] / gdb / break-catch-syscall.c
CommitLineData
10304ef3
SDJ
1/* Everything about syscall catchpoints, for GDB.
2
61baf725 3 Copyright (C) 2009-2017 Free Software Foundation, Inc.
10304ef3
SDJ
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 <ctype.h>
22#include "breakpoint.h"
23#include "gdbcmd.h"
24#include "inferior.h"
25#include "cli/cli-utils.h"
26#include "annotate.h"
27#include "mi/mi-common.h"
28#include "valprint.h"
29#include "arch-utils.h"
30#include "observer.h"
31#include "xml-syscall.h"
32
33/* An instance of this type is used to represent a syscall catchpoint.
c1fc2657 34 A breakpoint is really of this type iff its ops pointer points to
10304ef3
SDJ
35 CATCH_SYSCALL_BREAKPOINT_OPS. */
36
c1fc2657 37struct syscall_catchpoint : public breakpoint
10304ef3 38{
10304ef3 39 /* Syscall numbers used for the 'catch syscall' feature. If no
e12c9b7a
TT
40 syscall has been specified for filtering, it is empty.
41 Otherwise, it holds a list of all syscalls to be caught. */
42 std::vector<int> syscalls_to_be_caught;
10304ef3
SDJ
43};
44
10304ef3
SDJ
45static const struct inferior_data *catch_syscall_inferior_data = NULL;
46
47struct catch_syscall_inferior_data
48{
49 /* We keep a count of the number of times the user has requested a
50 particular syscall to be tracked, and pass this information to the
51 target. This lets capable targets implement filtering directly. */
52
53 /* Number of times that "any" syscall is requested. */
54 int any_syscall_count;
55
56 /* Count of each system call. */
b6f48cb0 57 std::vector<int> syscalls_counts;
10304ef3
SDJ
58
59 /* This counts all syscall catch requests, so we can readily determine
60 if any catching is necessary. */
61 int total_syscalls_count;
62};
63
b6f48cb0 64static struct catch_syscall_inferior_data *
10304ef3
SDJ
65get_catch_syscall_inferior_data (struct inferior *inf)
66{
67 struct catch_syscall_inferior_data *inf_data;
68
9a3c8263
SM
69 inf_data = ((struct catch_syscall_inferior_data *)
70 inferior_data (inf, catch_syscall_inferior_data));
10304ef3
SDJ
71 if (inf_data == NULL)
72 {
b6f48cb0 73 inf_data = new struct catch_syscall_inferior_data ();
10304ef3
SDJ
74 set_inferior_data (inf, catch_syscall_inferior_data, inf_data);
75 }
76
77 return inf_data;
78}
79
80static void
81catch_syscall_inferior_data_cleanup (struct inferior *inf, void *arg)
82{
b6f48cb0
TT
83 struct catch_syscall_inferior_data *inf_data
84 = (struct catch_syscall_inferior_data *) arg;
85 delete inf_data;
10304ef3
SDJ
86}
87
88
89/* Implement the "insert" breakpoint_ops method for syscall
90 catchpoints. */
91
92static int
93insert_catch_syscall (struct bp_location *bl)
94{
95 struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
96 struct inferior *inf = current_inferior ();
97 struct catch_syscall_inferior_data *inf_data
98 = get_catch_syscall_inferior_data (inf);
99
100 ++inf_data->total_syscalls_count;
e12c9b7a 101 if (c->syscalls_to_be_caught.empty ())
10304ef3
SDJ
102 ++inf_data->any_syscall_count;
103 else
104 {
e12c9b7a 105 for (int iter : c->syscalls_to_be_caught)
10304ef3 106 {
b6f48cb0
TT
107 if (iter >= inf_data->syscalls_counts.size ())
108 inf_data->syscalls_counts.resize (iter + 1);
109 ++inf_data->syscalls_counts[iter];
10304ef3
SDJ
110 }
111 }
112
113 return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
114 inf_data->total_syscalls_count != 0,
115 inf_data->any_syscall_count,
b6f48cb0
TT
116 inf_data->syscalls_counts.size (),
117 inf_data->syscalls_counts.data ());
10304ef3
SDJ
118}
119
120/* Implement the "remove" breakpoint_ops method for syscall
121 catchpoints. */
122
123static int
73971819 124remove_catch_syscall (struct bp_location *bl, enum remove_bp_reason reason)
10304ef3
SDJ
125{
126 struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
127 struct inferior *inf = current_inferior ();
128 struct catch_syscall_inferior_data *inf_data
129 = get_catch_syscall_inferior_data (inf);
130
131 --inf_data->total_syscalls_count;
e12c9b7a 132 if (c->syscalls_to_be_caught.empty ())
10304ef3
SDJ
133 --inf_data->any_syscall_count;
134 else
135 {
e12c9b7a 136 for (int iter : c->syscalls_to_be_caught)
10304ef3 137 {
b6f48cb0 138 if (iter >= inf_data->syscalls_counts.size ())
10304ef3
SDJ
139 /* Shouldn't happen. */
140 continue;
b6f48cb0 141 --inf_data->syscalls_counts[iter];
10304ef3
SDJ
142 }
143 }
144
145 return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
146 inf_data->total_syscalls_count != 0,
147 inf_data->any_syscall_count,
b6f48cb0
TT
148 inf_data->syscalls_counts.size (),
149 inf_data->syscalls_counts.data ());
10304ef3
SDJ
150}
151
152/* Implement the "breakpoint_hit" breakpoint_ops method for syscall
153 catchpoints. */
154
155static int
156breakpoint_hit_catch_syscall (const struct bp_location *bl,
bd522513 157 const address_space *aspace, CORE_ADDR bp_addr,
10304ef3
SDJ
158 const struct target_waitstatus *ws)
159{
160 /* We must check if we are catching specific syscalls in this
161 breakpoint. If we are, then we must guarantee that the called
162 syscall is the same syscall we are catching. */
163 int syscall_number = 0;
164 const struct syscall_catchpoint *c
165 = (const struct syscall_catchpoint *) bl->owner;
166
167 if (ws->kind != TARGET_WAITKIND_SYSCALL_ENTRY
168 && ws->kind != TARGET_WAITKIND_SYSCALL_RETURN)
169 return 0;
170
171 syscall_number = ws->value.syscall_number;
172
173 /* Now, checking if the syscall is the same. */
e12c9b7a 174 if (!c->syscalls_to_be_caught.empty ())
10304ef3 175 {
e12c9b7a 176 for (int iter : c->syscalls_to_be_caught)
10304ef3
SDJ
177 if (syscall_number == iter)
178 return 1;
179
180 return 0;
181 }
182
183 return 1;
184}
185
186/* Implement the "print_it" breakpoint_ops method for syscall
187 catchpoints. */
188
189static enum print_stop_action
190print_it_catch_syscall (bpstat bs)
191{
192 struct ui_out *uiout = current_uiout;
193 struct breakpoint *b = bs->breakpoint_at;
194 /* These are needed because we want to know in which state a
195 syscall is. It can be in the TARGET_WAITKIND_SYSCALL_ENTRY
196 or TARGET_WAITKIND_SYSCALL_RETURN, and depending on it we
197 must print "called syscall" or "returned from syscall". */
198 ptid_t ptid;
199 struct target_waitstatus last;
200 struct syscall s;
201 struct gdbarch *gdbarch = bs->bp_location_at->gdbarch;
202
203 get_last_target_status (&ptid, &last);
204
205 get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
206
207 annotate_catchpoint (b->number);
f303dbd6 208 maybe_print_thread_hit_breakpoint (uiout);
10304ef3
SDJ
209
210 if (b->disposition == disp_del)
112e8700 211 uiout->text ("Temporary catchpoint ");
10304ef3 212 else
112e8700
SM
213 uiout->text ("Catchpoint ");
214 if (uiout->is_mi_like_p ())
10304ef3 215 {
112e8700 216 uiout->field_string ("reason",
10304ef3
SDJ
217 async_reason_lookup (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY
218 ? EXEC_ASYNC_SYSCALL_ENTRY
219 : EXEC_ASYNC_SYSCALL_RETURN));
112e8700 220 uiout->field_string ("disp", bpdisp_text (b->disposition));
10304ef3 221 }
112e8700 222 uiout->field_int ("bkptno", b->number);
10304ef3
SDJ
223
224 if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY)
112e8700 225 uiout->text (" (call to syscall ");
10304ef3 226 else
112e8700 227 uiout->text (" (returned from syscall ");
10304ef3 228
112e8700
SM
229 if (s.name == NULL || uiout->is_mi_like_p ())
230 uiout->field_int ("syscall-number", last.value.syscall_number);
10304ef3 231 if (s.name != NULL)
112e8700 232 uiout->field_string ("syscall-name", s.name);
10304ef3 233
112e8700 234 uiout->text ("), ");
10304ef3
SDJ
235
236 return PRINT_SRC_AND_LOC;
237}
238
239/* Implement the "print_one" breakpoint_ops method for syscall
240 catchpoints. */
241
242static void
243print_one_catch_syscall (struct breakpoint *b,
244 struct bp_location **last_loc)
245{
246 struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
247 struct value_print_options opts;
248 struct ui_out *uiout = current_uiout;
249 struct gdbarch *gdbarch = b->loc->gdbarch;
250
251 get_user_print_options (&opts);
252 /* Field 4, the address, is omitted (which makes the columns not
253 line up too nicely with the headers, but the effect is relatively
254 readable). */
255 if (opts.addressprint)
112e8700 256 uiout->field_skip ("addr");
10304ef3
SDJ
257 annotate_field (5);
258
e12c9b7a 259 if (c->syscalls_to_be_caught.size () > 1)
112e8700 260 uiout->text ("syscalls \"");
10304ef3 261 else
112e8700 262 uiout->text ("syscall \"");
10304ef3 263
e12c9b7a 264 if (!c->syscalls_to_be_caught.empty ())
10304ef3 265 {
10304ef3
SDJ
266 char *text = xstrprintf ("%s", "");
267
e12c9b7a 268 for (int iter : c->syscalls_to_be_caught)
10304ef3
SDJ
269 {
270 char *x = text;
271 struct syscall s;
272 get_syscall_by_number (gdbarch, iter, &s);
273
274 if (s.name != NULL)
275 text = xstrprintf ("%s%s, ", text, s.name);
276 else
277 text = xstrprintf ("%s%d, ", text, iter);
278
279 /* We have to xfree the last 'text' (now stored at 'x')
280 because xstrprintf dynamically allocates new space for it
281 on every call. */
282 xfree (x);
283 }
284 /* Remove the last comma. */
285 text[strlen (text) - 2] = '\0';
112e8700 286 uiout->field_string ("what", text);
10304ef3
SDJ
287 }
288 else
112e8700
SM
289 uiout->field_string ("what", "<any syscall>");
290 uiout->text ("\" ");
10304ef3 291
112e8700
SM
292 if (uiout->is_mi_like_p ())
293 uiout->field_string ("catch-type", "syscall");
10304ef3
SDJ
294}
295
296/* Implement the "print_mention" breakpoint_ops method for syscall
297 catchpoints. */
298
299static void
300print_mention_catch_syscall (struct breakpoint *b)
301{
302 struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
303 struct gdbarch *gdbarch = b->loc->gdbarch;
304
e12c9b7a 305 if (!c->syscalls_to_be_caught.empty ())
10304ef3 306 {
e12c9b7a 307 if (c->syscalls_to_be_caught.size () > 1)
10304ef3
SDJ
308 printf_filtered (_("Catchpoint %d (syscalls"), b->number);
309 else
310 printf_filtered (_("Catchpoint %d (syscall"), b->number);
311
e12c9b7a 312 for (int iter : c->syscalls_to_be_caught)
10304ef3
SDJ
313 {
314 struct syscall s;
315 get_syscall_by_number (gdbarch, iter, &s);
316
e12c9b7a 317 if (s.name != NULL)
10304ef3
SDJ
318 printf_filtered (" '%s' [%d]", s.name, s.number);
319 else
320 printf_filtered (" %d", s.number);
321 }
322 printf_filtered (")");
323 }
324 else
325 printf_filtered (_("Catchpoint %d (any syscall)"),
326 b->number);
327}
328
329/* Implement the "print_recreate" breakpoint_ops method for syscall
330 catchpoints. */
331
332static void
333print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
334{
335 struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
336 struct gdbarch *gdbarch = b->loc->gdbarch;
337
338 fprintf_unfiltered (fp, "catch syscall");
339
e12c9b7a 340 for (int iter : c->syscalls_to_be_caught)
10304ef3 341 {
e12c9b7a 342 struct syscall s;
10304ef3 343
e12c9b7a
TT
344 get_syscall_by_number (gdbarch, iter, &s);
345 if (s.name != NULL)
346 fprintf_unfiltered (fp, " %s", s.name);
347 else
348 fprintf_unfiltered (fp, " %d", s.number);
10304ef3 349 }
e12c9b7a 350
10304ef3
SDJ
351 print_recreate_thread (b, fp);
352}
353
354/* The breakpoint_ops structure to be used in syscall catchpoints. */
355
356static struct breakpoint_ops catch_syscall_breakpoint_ops;
357
358/* Returns non-zero if 'b' is a syscall catchpoint. */
359
360static int
361syscall_catchpoint_p (struct breakpoint *b)
362{
363 return (b->ops == &catch_syscall_breakpoint_ops);
364}
365
366static void
e12c9b7a 367create_syscall_event_catchpoint (int tempflag, std::vector<int> &&filter,
10304ef3
SDJ
368 const struct breakpoint_ops *ops)
369{
10304ef3
SDJ
370 struct gdbarch *gdbarch = get_current_arch ();
371
b270e6f9
TT
372 std::unique_ptr<syscall_catchpoint> c (new syscall_catchpoint ());
373 init_catchpoint (c.get (), gdbarch, tempflag, NULL, ops);
2f5404b3 374 c->syscalls_to_be_caught = std::move (filter);
10304ef3 375
b270e6f9 376 install_breakpoint (0, std::move (c), 1);
10304ef3
SDJ
377}
378
e12c9b7a
TT
379/* Splits the argument using space as delimiter. */
380
381static std::vector<int>
eb4c3f4a 382catch_syscall_split_args (const char *arg)
10304ef3 383{
e12c9b7a 384 std::vector<int> result;
10304ef3
SDJ
385 struct gdbarch *gdbarch = target_gdbarch ();
386
387 while (*arg != '\0')
388 {
389 int i, syscall_number;
390 char *endptr;
391 char cur_name[128];
392 struct syscall s;
393
394 /* Skip whitespace. */
395 arg = skip_spaces (arg);
396
397 for (i = 0; i < 127 && arg[i] && !isspace (arg[i]); ++i)
398 cur_name[i] = arg[i];
399 cur_name[i] = '\0';
400 arg += i;
401
e3487908 402 /* Check if the user provided a syscall name, group, or a number. */
10304ef3
SDJ
403 syscall_number = (int) strtol (cur_name, &endptr, 0);
404 if (*endptr == '\0')
e3487908
GKB
405 {
406 get_syscall_by_number (gdbarch, syscall_number, &s);
e12c9b7a 407 result.push_back (s.number);
e3487908
GKB
408 }
409 else if (startswith (cur_name, "g:")
410 || startswith (cur_name, "group:"))
411 {
412 /* We have a syscall group. Let's expand it into a syscall
413 list before inserting. */
414 struct syscall *syscall_list;
415 const char *group_name;
416
417 /* Skip over "g:" and "group:" prefix strings. */
418 group_name = strchr (cur_name, ':') + 1;
419
420 syscall_list = get_syscalls_by_group (gdbarch, group_name);
421
422 if (syscall_list == NULL)
423 error (_("Unknown syscall group '%s'."), group_name);
424
425 for (i = 0; syscall_list[i].name != NULL; i++)
426 {
427 /* Insert each syscall that are part of the group. No
428 need to check if it is valid. */
e12c9b7a 429 result.push_back (syscall_list[i].number);
e3487908
GKB
430 }
431
432 xfree (syscall_list);
433 }
10304ef3
SDJ
434 else
435 {
436 /* We have a name. Let's check if it's valid and convert it
437 to a number. */
438 get_syscall_by_name (gdbarch, cur_name, &s);
439
440 if (s.number == UNKNOWN_SYSCALL)
441 /* Here we have to issue an error instead of a warning,
442 because GDB cannot do anything useful if there's no
443 syscall number to be caught. */
444 error (_("Unknown syscall name '%s'."), cur_name);
10304ef3 445
e3487908 446 /* Ok, it's valid. */
e12c9b7a 447 result.push_back (s.number);
e3487908 448 }
10304ef3
SDJ
449 }
450
10304ef3
SDJ
451 return result;
452}
453
454/* Implement the "catch syscall" command. */
455
456static void
eb4c3f4a 457catch_syscall_command_1 (const char *arg, int from_tty,
10304ef3
SDJ
458 struct cmd_list_element *command)
459{
460 int tempflag;
e12c9b7a 461 std::vector<int> filter;
10304ef3
SDJ
462 struct syscall s;
463 struct gdbarch *gdbarch = get_current_arch ();
464
465 /* Checking if the feature if supported. */
466 if (gdbarch_get_syscall_number_p (gdbarch) == 0)
467 error (_("The feature 'catch syscall' is not supported on \
468this architecture yet."));
469
470 tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
471
472 arg = skip_spaces (arg);
473
474 /* We need to do this first "dummy" translation in order
475 to get the syscall XML file loaded or, most important,
476 to display a warning to the user if there's no XML file
477 for his/her architecture. */
478 get_syscall_by_number (gdbarch, 0, &s);
479
480 /* The allowed syntax is:
481 catch syscall
482 catch syscall <name | number> [<name | number> ... <name | number>]
483
484 Let's check if there's a syscall name. */
485
486 if (arg != NULL)
487 filter = catch_syscall_split_args (arg);
10304ef3 488
e12c9b7a 489 create_syscall_event_catchpoint (tempflag, std::move (filter),
10304ef3
SDJ
490 &catch_syscall_breakpoint_ops);
491}
492
493
494/* Returns 0 if 'bp' is NOT a syscall catchpoint,
495 non-zero otherwise. */
496static int
497is_syscall_catchpoint_enabled (struct breakpoint *bp)
498{
499 if (syscall_catchpoint_p (bp)
500 && bp->enable_state != bp_disabled
501 && bp->enable_state != bp_call_disabled)
502 return 1;
503 else
504 return 0;
505}
506
507int
508catch_syscall_enabled (void)
509{
510 struct catch_syscall_inferior_data *inf_data
511 = get_catch_syscall_inferior_data (current_inferior ());
512
513 return inf_data->total_syscalls_count != 0;
514}
515
516/* Helper function for catching_syscall_number. If B is a syscall
517 catchpoint for SYSCALL_NUMBER, return 1 (which will make
518 'breakpoint_find_if' return). Otherwise, return 0. */
519
520static int
521catching_syscall_number_1 (struct breakpoint *b,
522 void *data)
523{
524 int syscall_number = (int) (uintptr_t) data;
525
526 if (is_syscall_catchpoint_enabled (b))
527 {
528 struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
529
e12c9b7a 530 if (!c->syscalls_to_be_caught.empty ())
10304ef3 531 {
e12c9b7a 532 for (int iter : c->syscalls_to_be_caught)
10304ef3
SDJ
533 if (syscall_number == iter)
534 return 1;
535 }
536 else
537 return 1;
538 }
539
540 return 0;
541}
542
543int
544catching_syscall_number (int syscall_number)
545{
546 struct breakpoint *b = breakpoint_find_if (catching_syscall_number_1,
547 (void *) (uintptr_t) syscall_number);
548
549 return b != NULL;
550}
551
552/* Complete syscall names. Used by "catch syscall". */
eb3ff9a5
PA
553
554static void
10304ef3 555catch_syscall_completer (struct cmd_list_element *cmd,
eb3ff9a5 556 completion_tracker &tracker,
10304ef3
SDJ
557 const char *text, const char *word)
558{
e3487908 559 struct gdbarch *gdbarch = get_current_arch ();
3d415c26 560 gdb::unique_xmalloc_ptr<const char *> group_list;
e3487908 561 const char *prefix;
e3487908
GKB
562
563 /* Completion considers ':' to be a word separator, so we use this to
564 verify whether the previous word was a group prefix. If so, we
565 build the completion list using group names only. */
566 for (prefix = word; prefix != text && prefix[-1] != ' '; prefix--)
567 ;
568
569 if (startswith (prefix, "g:") || startswith (prefix, "group:"))
570 {
571 /* Perform completion inside 'group:' namespace only. */
3d415c26 572 group_list.reset (get_syscall_group_names (gdbarch));
eb3ff9a5 573 if (group_list != NULL)
3d415c26 574 complete_on_enum (tracker, group_list.get (), word, word);
e3487908
GKB
575 }
576 else
577 {
578 /* Complete with both, syscall names and groups. */
3d415c26
TT
579 gdb::unique_xmalloc_ptr<const char *> syscall_list
580 (get_syscall_names (gdbarch));
581 group_list.reset (get_syscall_group_names (gdbarch));
582
583 const char **group_ptr = group_list.get ();
584
585 /* Hold on to strings while we're using them. */
586 std::vector<std::string> holders;
e3487908
GKB
587
588 /* Append "group:" prefix to syscall groups. */
9a93831c
SM
589 for (int i = 0; group_ptr[i] != NULL; i++)
590 holders.push_back (string_printf ("group:%s", group_ptr[i]));
e3487908 591
9a93831c
SM
592 for (int i = 0; group_ptr[i] != NULL; i++)
593 group_ptr[i] = holders[i].c_str ();
e3487908 594
eb3ff9a5 595 if (syscall_list != NULL)
3d415c26 596 complete_on_enum (tracker, syscall_list.get (), word, word);
eb3ff9a5 597 if (group_list != NULL)
3d415c26 598 complete_on_enum (tracker, group_ptr, word, word);
e3487908 599 }
10304ef3
SDJ
600}
601
602static void
603clear_syscall_counts (struct inferior *inf)
604{
605 struct catch_syscall_inferior_data *inf_data
606 = get_catch_syscall_inferior_data (inf);
607
608 inf_data->total_syscalls_count = 0;
609 inf_data->any_syscall_count = 0;
b6f48cb0 610 inf_data->syscalls_counts.clear ();
10304ef3
SDJ
611}
612
613static void
614initialize_syscall_catchpoint_ops (void)
615{
616 struct breakpoint_ops *ops;
617
618 initialize_breakpoint_ops ();
619
620 /* Syscall catchpoints. */
621 ops = &catch_syscall_breakpoint_ops;
622 *ops = base_breakpoint_ops;
10304ef3
SDJ
623 ops->insert_location = insert_catch_syscall;
624 ops->remove_location = remove_catch_syscall;
625 ops->breakpoint_hit = breakpoint_hit_catch_syscall;
626 ops->print_it = print_it_catch_syscall;
627 ops->print_one = print_one_catch_syscall;
628 ops->print_mention = print_mention_catch_syscall;
629 ops->print_recreate = print_recreate_catch_syscall;
630}
631
10304ef3
SDJ
632void
633_initialize_break_catch_syscall (void)
634{
635 initialize_syscall_catchpoint_ops ();
636
637 observer_attach_inferior_exit (clear_syscall_counts);
638 catch_syscall_inferior_data
639 = register_inferior_data_with_cleanup (NULL,
640 catch_syscall_inferior_data_cleanup);
641
642 add_catch_command ("syscall", _("\
e3487908
GKB
643Catch system calls by their names, groups and/or numbers.\n\
644Arguments say which system calls to catch. If no arguments are given,\n\
645every system call will be caught. Arguments, if given, should be one\n\
646or more system call names (if your system supports that), system call\n\
647groups or system call numbers."),
10304ef3
SDJ
648 catch_syscall_command_1,
649 catch_syscall_completer,
650 CATCH_PERMANENT,
651 CATCH_TEMPORARY);
652}
This page took 0.228249 seconds and 4 git commands to generate.