GNU Binutils with patches for OS216
修訂 | 9bec6088410ea9627f0abbe676716b89c0436eae (tree) |
---|---|
時間 | 2019-06-05 07:30:03 |
作者 | Pedro Alves <palves@redh...> |
Commiter | Pedro Alves |
Make "frame apply" support -OPT options
This adds support for '-'-style options to the "frame apply" family of
commands -- "frame apply COUNT", "frame apply level", "frame apply
all", "faas" and "tfaas".
The -q/-c/-s flags were already supported, -past-main/-past-entry is
new:
~
(gdb) help frame apply all
Apply a command to all frames.
Usage: frame apply all [OPTION]... COMMAND
Prints the frame location information followed by COMMAND output.
By default, an error raised during the execution of COMMAND
aborts "frame apply".
Options:
~
TAB completion of options is now supported. Also, TAB completion of
COMMAND in "frame apply all COMMAND" does the right thing now, making
use of complete_command, added by the previous patch. E.g.:
The change to tfaas_command is necessary because otherwise you get
this:
That's because the above is equivalent to:
and the "--" instructs "thread apply" to consider everything up to
"--" as its command options. And from that view, "frame" is an
invalid option.
The change makes tfaas be equivalent to:
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>
* cli/cli-utils.c (parse_flags_qcs): Use validate_flags_qcs.
(validate_flags_qcs): New.
* cli/cli-utils.h (struct qcs_flags): Change field types to int.
(validate_flags_qcs): Declare.
* stack.c (qcs_flag_option_def, fr_qcs_flags_option_defs): New.
(make_frame_apply_options_def_group): New.
(frame_apply_command_count): Process options with
gdb::option::process_options.
(frame_apply_completer): New.
(frame_apply_level_completer, frame_apply_all_completer)
(frame_apply_completer): New.
(_initialize_stack): Update help of "frame apply", "frame apply
level", "frame apply all" and "faas" to mention supported options
and install command completers.
* stack.h (frame_apply_all_completer): Declare.
* thread.c: Include "stack.h".
(tfaas_command): Add "--".
(_initialize_thread): Update help "tfaas" to mention supported
options and install command completer.
gdb/testsuite/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>
* gdb.base/options.exp (test-frame-apply): New.
(top level): Test print commands with different "frame apply"
prefixes.
@@ -573,8 +573,18 @@ parse_flags_qcs (const char *which_command, const char **str, | ||
573 | 573 | gdb_assert_not_reached ("int qcs flag out of bound"); |
574 | 574 | } |
575 | 575 | |
576 | - if (flags->cont && flags->silent) | |
577 | - error (_("%s: -c and -s are mutually exclusive"), which_command); | |
576 | + validate_flags_qcs (which_command, flags); | |
578 | 577 | |
579 | 578 | return true; |
580 | 579 | } |
580 | + | |
581 | +/* See documentation in cli-utils.h. */ | |
582 | + | |
583 | +void | |
584 | +validate_flags_qcs (const char *which_command, qcs_flags *flags) | |
585 | +{ | |
586 | + if (flags->cont && flags->silent) | |
587 | + error (_("%s: -c and -s are mutually exclusive"), which_command); | |
588 | +} | |
589 | + | |
590 | +/* See documentation in cli-utils.h. */ |
@@ -229,13 +229,14 @@ check_for_argument (char **str, const char *arg) | ||
229 | 229 | such that FLAGS [N - 1] is the valid found flag. */ |
230 | 230 | extern int parse_flags (const char **str, const char *flags); |
231 | 231 | |
232 | -/* qcs_flags struct regroups the flags parsed by parse_flags_qcs. */ | |
232 | +/* qcs_flags struct groups the -q, -c, and -s flags parsed by "thread | |
233 | + apply" and "frame apply" commands */ | |
233 | 234 | |
234 | 235 | struct qcs_flags |
235 | 236 | { |
236 | - bool quiet = false; | |
237 | - bool cont = false; | |
238 | - bool silent = false; | |
237 | + int quiet = false; | |
238 | + int cont = false; | |
239 | + int silent = false; | |
239 | 240 | }; |
240 | 241 | |
241 | 242 | /* A helper function that uses parse_flags to handle the flags qcs : |
@@ -259,4 +260,9 @@ struct qcs_flags | ||
259 | 260 | extern bool parse_flags_qcs (const char *which_command, const char **str, |
260 | 261 | qcs_flags *flags); |
261 | 262 | |
263 | +/* Validate FLAGS. Throws an error if both FLAGS->CONT and | |
264 | + FLAGS->SILENT are true. WHICH_COMMAND is included in the error | |
265 | + message. */ | |
266 | +extern void validate_flags_qcs (const char *which_command, qcs_flags *flags); | |
267 | + | |
262 | 268 | #endif /* CLI_CLI_UTILS_H */ |
@@ -2823,6 +2823,42 @@ func_command (const char *arg, int from_tty) | ||
2823 | 2823 | } |
2824 | 2824 | } |
2825 | 2825 | |
2826 | +/* The qcs command line flags for the "frame apply" commands. Keep | |
2827 | + this in sync with the "thread apply" commands. */ | |
2828 | + | |
2829 | +using qcs_flag_option_def | |
2830 | + = gdb::option::flag_option_def<qcs_flags>; | |
2831 | + | |
2832 | +static const gdb::option::option_def fr_qcs_flags_option_defs[] = { | |
2833 | + qcs_flag_option_def { | |
2834 | + "q", [] (qcs_flags *opt) { return &opt->quiet; }, | |
2835 | + N_("Disables printing the frame location information."), | |
2836 | + }, | |
2837 | + | |
2838 | + qcs_flag_option_def { | |
2839 | + "c", [] (qcs_flags *opt) { return &opt->cont; }, | |
2840 | + N_("Print any error raised by COMMAND and continue."), | |
2841 | + }, | |
2842 | + | |
2843 | + qcs_flag_option_def { | |
2844 | + "s", [] (qcs_flags *opt) { return &opt->silent; }, | |
2845 | + N_("Silently ignore any errors or empty output produced by COMMAND."), | |
2846 | + }, | |
2847 | +}; | |
2848 | + | |
2849 | +/* Create an option_def_group array for all the "frame apply" options, | |
2850 | + with FLAGS and SET_BT_OPTS as context. */ | |
2851 | + | |
2852 | +static inline std::array<gdb::option::option_def_group, 2> | |
2853 | +make_frame_apply_options_def_group (qcs_flags *flags, | |
2854 | + set_backtrace_options *set_bt_opts) | |
2855 | +{ | |
2856 | + return {{ | |
2857 | + { {fr_qcs_flags_option_defs}, flags }, | |
2858 | + { {set_backtrace_option_defs}, set_bt_opts }, | |
2859 | + }}; | |
2860 | +} | |
2861 | + | |
2826 | 2862 | /* Apply a GDB command to all stack frames, or a set of identified frames, |
2827 | 2863 | or innermost COUNT frames. |
2828 | 2864 | With a negative COUNT, apply command on outermost -COUNT frames. |
@@ -2852,10 +2888,13 @@ frame_apply_command_count (const char *which_command, | ||
2852 | 2888 | struct frame_info *trailing, int count) |
2853 | 2889 | { |
2854 | 2890 | qcs_flags flags; |
2855 | - struct frame_info *fi; | |
2891 | + set_backtrace_options set_bt_opts = user_set_backtrace_options; | |
2856 | 2892 | |
2857 | - while (cmd != NULL && parse_flags_qcs (which_command, &cmd, &flags)) | |
2858 | - ; | |
2893 | + auto group = make_frame_apply_options_def_group (&flags, &set_bt_opts); | |
2894 | + gdb::option::process_options | |
2895 | + (&cmd, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group); | |
2896 | + | |
2897 | + validate_flags_qcs (which_command, &flags); | |
2859 | 2898 | |
2860 | 2899 | if (cmd == NULL || *cmd == '\0') |
2861 | 2900 | error (_("Please specify a command to apply on the selected frames")); |
@@ -2866,7 +2905,12 @@ frame_apply_command_count (const char *which_command, | ||
2866 | 2905 | these also. */ |
2867 | 2906 | scoped_restore_current_thread restore_thread; |
2868 | 2907 | |
2869 | - for (fi = trailing; fi && count--; fi = get_prev_frame (fi)) | |
2908 | + /* These options are handled quite deep in the unwind machinery, so | |
2909 | + we get to pass them down by swapping globals. */ | |
2910 | + scoped_restore restore_set_backtrace_options | |
2911 | + = make_scoped_restore (&user_set_backtrace_options, set_bt_opts); | |
2912 | + | |
2913 | + for (frame_info *fi = trailing; fi && count--; fi = get_prev_frame (fi)) | |
2870 | 2914 | { |
2871 | 2915 | QUIT; |
2872 | 2916 |
@@ -2909,6 +2953,104 @@ frame_apply_command_count (const char *which_command, | ||
2909 | 2953 | } |
2910 | 2954 | } |
2911 | 2955 | |
2956 | +/* Completer for the "frame apply ..." commands. */ | |
2957 | + | |
2958 | +static void | |
2959 | +frame_apply_completer (completion_tracker &tracker, const char *text) | |
2960 | +{ | |
2961 | + const auto group = make_frame_apply_options_def_group (nullptr, nullptr); | |
2962 | + if (gdb::option::complete_options | |
2963 | + (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group)) | |
2964 | + return; | |
2965 | + | |
2966 | + complete_nested_command_line (tracker, text); | |
2967 | +} | |
2968 | + | |
2969 | +/* Completer for the "frame apply" commands. */ | |
2970 | + | |
2971 | +static void | |
2972 | +frame_apply_level_cmd_completer (struct cmd_list_element *ignore, | |
2973 | + completion_tracker &tracker, | |
2974 | + const char *text, const char */*word*/) | |
2975 | +{ | |
2976 | + /* Do this explicitly because there's an early return below. */ | |
2977 | + tracker.set_use_custom_word_point (true); | |
2978 | + | |
2979 | + number_or_range_parser levels (text); | |
2980 | + | |
2981 | + /* Skip the LEVEL list to find the options and command args. */ | |
2982 | + try | |
2983 | + { | |
2984 | + while (!levels.finished ()) | |
2985 | + { | |
2986 | + /* Call for effect. */ | |
2987 | + levels.get_number (); | |
2988 | + | |
2989 | + if (levels.in_range ()) | |
2990 | + levels.skip_range (); | |
2991 | + } | |
2992 | + } | |
2993 | + catch (const gdb_exception_error &ex) | |
2994 | + { | |
2995 | + /* get_number throws if it parses a negative number, for | |
2996 | + example. But a seemingly negative number may be the start of | |
2997 | + an option instead. */ | |
2998 | + } | |
2999 | + | |
3000 | + const char *cmd = levels.cur_tok (); | |
3001 | + | |
3002 | + if (cmd == text) | |
3003 | + { | |
3004 | + /* No level list yet. */ | |
3005 | + return; | |
3006 | + } | |
3007 | + | |
3008 | + /* Check if we're past a valid LEVEL already. */ | |
3009 | + if (levels.finished () | |
3010 | + && cmd > text && !isspace (cmd[-1])) | |
3011 | + return; | |
3012 | + | |
3013 | + /* We're past LEVELs, advance word point. */ | |
3014 | + tracker.advance_custom_word_point_by (cmd - text); | |
3015 | + text = cmd; | |
3016 | + | |
3017 | + frame_apply_completer (tracker, text); | |
3018 | +} | |
3019 | + | |
3020 | +/* Completer for the "frame apply all" command. */ | |
3021 | + | |
3022 | +void | |
3023 | +frame_apply_all_cmd_completer (struct cmd_list_element *ignore, | |
3024 | + completion_tracker &tracker, | |
3025 | + const char *text, const char */*word*/) | |
3026 | +{ | |
3027 | + frame_apply_completer (tracker, text); | |
3028 | +} | |
3029 | + | |
3030 | +/* Completer for the "frame apply COUNT" command. */ | |
3031 | + | |
3032 | +static void | |
3033 | +frame_apply_cmd_completer (struct cmd_list_element *ignore, | |
3034 | + completion_tracker &tracker, | |
3035 | + const char *text, const char */*word*/) | |
3036 | +{ | |
3037 | + const char *cmd = text; | |
3038 | + | |
3039 | + int count = get_number_trailer (&cmd, 0); | |
3040 | + if (count == 0) | |
3041 | + return; | |
3042 | + | |
3043 | + /* Check if we're past a valid COUNT already. */ | |
3044 | + if (cmd > text && !isspace (cmd[-1])) | |
3045 | + return; | |
3046 | + | |
3047 | + /* We're past COUNT, advance word point. */ | |
3048 | + tracker.advance_custom_word_point_by (cmd - text); | |
3049 | + text = cmd; | |
3050 | + | |
3051 | + frame_apply_completer (tracker, text); | |
3052 | +} | |
3053 | + | |
2912 | 3054 | /* Implementation of the "frame apply level" command. */ |
2913 | 3055 | |
2914 | 3056 | static void |
@@ -3095,44 +3237,62 @@ A single numerical argument specifies the frame to select."), | ||
3095 | 3237 | |
3096 | 3238 | add_com_alias ("f", "frame", class_stack, 1); |
3097 | 3239 | |
3098 | -#define FRAME_APPLY_FLAGS_HELP "\ | |
3240 | +#define FRAME_APPLY_OPTION_HELP "\ | |
3099 | 3241 | Prints the frame location information followed by COMMAND output.\n\ |
3100 | -FLAG arguments are -q (quiet), -c (continue), -s (silent).\n\ | |
3101 | -Flag -q disables printing the frame location information.\n\ | |
3102 | -By default, if a COMMAND raises an error, frame apply is aborted.\n\ | |
3103 | -Flag -c indicates to print the error and continue.\n\ | |
3104 | -Flag -s indicates to silently ignore a COMMAND that raises an error\n\ | |
3105 | -or produces no output." | |
3106 | - | |
3107 | - add_prefix_cmd ("apply", class_stack, frame_apply_command, | |
3108 | - _("Apply a command to a number of frames.\n\ | |
3109 | -Usage: frame apply COUNT [FLAG]... COMMAND\n\ | |
3242 | +\n\ | |
3243 | +By default, an error raised during the execution of COMMAND\n\ | |
3244 | +aborts \"frame apply\".\n\ | |
3245 | +\n\ | |
3246 | +Options:\n\ | |
3247 | +%OPTIONS%" | |
3248 | + | |
3249 | + const auto frame_apply_opts | |
3250 | + = make_frame_apply_options_def_group (nullptr, nullptr); | |
3251 | + | |
3252 | + static std::string frame_apply_cmd_help = gdb::option::build_help (N_("\ | |
3253 | +Apply a command to a number of frames.\n\ | |
3254 | +Usage: frame apply COUNT [OPTION]... COMMAND\n\ | |
3110 | 3255 | With a negative COUNT argument, applies the command on outermost -COUNT frames.\n" |
3111 | -FRAME_APPLY_FLAGS_HELP), | |
3112 | - &frame_apply_cmd_list, "frame apply ", 1, &frame_cmd_list); | |
3256 | + FRAME_APPLY_OPTION_HELP), | |
3257 | + frame_apply_opts); | |
3113 | 3258 | |
3114 | - add_cmd ("all", class_stack, frame_apply_all_command, | |
3115 | - _("\ | |
3259 | + cmd = add_prefix_cmd ("apply", class_stack, frame_apply_command, | |
3260 | + frame_apply_cmd_help.c_str (), | |
3261 | + &frame_apply_cmd_list, "frame apply ", 1, | |
3262 | + &frame_cmd_list); | |
3263 | + set_cmd_completer_handle_brkchars (cmd, frame_apply_cmd_completer); | |
3264 | + | |
3265 | + static std::string frame_apply_all_cmd_help = gdb::option::build_help (N_("\ | |
3116 | 3266 | Apply a command to all frames.\n\ |
3117 | 3267 | \n\ |
3118 | -Usage: frame apply all [FLAG]... COMMAND\n" | |
3119 | -FRAME_APPLY_FLAGS_HELP), | |
3120 | - &frame_apply_cmd_list); | |
3268 | +Usage: frame apply all [OPTION]... COMMAND\n" | |
3269 | + FRAME_APPLY_OPTION_HELP), | |
3270 | + frame_apply_opts); | |
3121 | 3271 | |
3122 | - add_cmd ("level", class_stack, frame_apply_level_command, | |
3123 | - _("\ | |
3272 | + cmd = add_cmd ("all", class_stack, frame_apply_all_command, | |
3273 | + frame_apply_all_cmd_help.c_str (), | |
3274 | + &frame_apply_cmd_list); | |
3275 | + set_cmd_completer_handle_brkchars (cmd, frame_apply_all_cmd_completer); | |
3276 | + | |
3277 | + static std::string frame_apply_level_cmd_help = gdb::option::build_help (N_("\ | |
3124 | 3278 | Apply a command to a list of frames.\n\ |
3125 | 3279 | \n\ |
3126 | -Usage: frame apply level LEVEL... [FLAG]... COMMAND\n\ | |
3127 | -ID is a space-separated list of LEVELs of frames to apply COMMAND on.\n" | |
3128 | -FRAME_APPLY_FLAGS_HELP), | |
3280 | +Usage: frame apply level LEVEL... [OPTION]... COMMAND\n\ | |
3281 | +LEVEL is a space-separated list of levels of frames to apply COMMAND on.\n" | |
3282 | + FRAME_APPLY_OPTION_HELP), | |
3283 | + frame_apply_opts); | |
3284 | + | |
3285 | + cmd = add_cmd ("level", class_stack, frame_apply_level_command, | |
3286 | + frame_apply_level_cmd_help.c_str (), | |
3129 | 3287 | &frame_apply_cmd_list); |
3288 | + set_cmd_completer_handle_brkchars (cmd, frame_apply_level_cmd_completer); | |
3130 | 3289 | |
3131 | - add_com ("faas", class_stack, faas_command, _("\ | |
3290 | + cmd = add_com ("faas", class_stack, faas_command, _("\ | |
3132 | 3291 | Apply a command to all frames (ignoring errors and empty output).\n\ |
3133 | -Usage: faas COMMAND\n\ | |
3134 | -shortcut for 'frame apply all -s COMMAND'")); | |
3135 | - | |
3292 | +Usage: faas [OPTION]... COMMAND\n\ | |
3293 | +shortcut for 'frame apply all -s [OPTION]... COMMAND'\n\ | |
3294 | +See \"help frame apply all\" for available options.")); | |
3295 | + set_cmd_completer_handle_brkchars (cmd, frame_apply_all_cmd_completer); | |
3136 | 3296 | |
3137 | 3297 | add_prefix_cmd ("frame", class_stack, |
3138 | 3298 | &frame_cmd.base_command, _("\ |
@@ -52,4 +52,9 @@ struct symtab* get_last_displayed_symtab (void); | ||
52 | 52 | int get_last_displayed_line (void); |
53 | 53 | symtab_and_line get_last_displayed_sal (); |
54 | 54 | |
55 | +/* Completer for the "frame apply all" command. */ | |
56 | +void frame_apply_all_cmd_completer (struct cmd_list_element *ignore, | |
57 | + completion_tracker &tracker, | |
58 | + const char *text, const char */*word*/); | |
59 | + | |
55 | 60 | #endif /* #ifndef STACK_H */ |
@@ -25,6 +25,9 @@ | ||
25 | 25 | |
26 | 26 | # - compile print |
27 | 27 | # - backtrace |
28 | +# - frame apply | |
29 | +# - faas | |
30 | +# - tfaas | |
28 | 31 | |
29 | 32 | load_lib completion-support.exp |
30 | 33 |
@@ -295,6 +298,79 @@ proc_with_prefix test-backtrace {} { | ||
295 | 298 | "backtrace (1 + xxx1" |
296 | 299 | } |
297 | 300 | |
301 | +# Basic option-machinery + "frame apply" command integration tests. | |
302 | +proc_with_prefix test-frame-apply {} { | |
303 | + test_gdb_complete_unique "frame apply all" "frame apply all" | |
304 | + | |
305 | + gdb_test "frame apply level 0-" \ | |
306 | + "Please specify a command to apply on the selected frames" | |
307 | + test_gdb_complete_none "frame apply level 0-" | |
308 | + | |
309 | + foreach cmd { | |
310 | + "frame apply all" | |
311 | + "frame apply 1" | |
312 | + "frame apply level 0" | |
313 | + "faas" | |
314 | + "tfaas" | |
315 | + } { | |
316 | + test_gdb_completion_offers_commands "$cmd " | |
317 | + | |
318 | + # tfaas is silent on command error by design. This procedure | |
319 | + # hides that aspect. EXPECTED_RE is only considered when not | |
320 | + # testing with "faas"/"tfaas". | |
321 | + proc test_error_cmd {cmd arg expected_re} { | |
322 | + if {$cmd == "tfaas"} { | |
323 | + gdb_test_no_output "$cmd$arg" | |
324 | + } else { | |
325 | + gdb_test "$cmd$arg" $expected_re | |
326 | + } | |
327 | + } | |
328 | + # Same, but for tests where both "faas" and "tfaas" are | |
329 | + # expected to be silent. | |
330 | + proc test_error_cmd2 {cmd arg expected_re} { | |
331 | + if {$cmd == "tfaas" || $cmd == "faas"} { | |
332 | + gdb_test_no_output "$cmd$arg" | |
333 | + } else { | |
334 | + gdb_test "$cmd$arg" $expected_re | |
335 | + } | |
336 | + } | |
337 | + | |
338 | + test_error_cmd $cmd " -" "Ambiguous option at: -" | |
339 | + test_gdb_complete_multiple "$cmd " "-" "" { | |
340 | + "-c" | |
341 | + "-past-entry" | |
342 | + "-past-main" | |
343 | + "-q" | |
344 | + "-s" | |
345 | + } | |
346 | + | |
347 | + with_test_prefix "no-trailing-space" { | |
348 | + test_error_cmd $cmd " --" \ | |
349 | + "Please specify a command to apply on the selected frames" | |
350 | + test_gdb_complete_unique "$cmd --" "$cmd --" | |
351 | + } | |
352 | + | |
353 | + with_test_prefix "trailing-space" { | |
354 | + test_error_cmd $cmd " -- " \ | |
355 | + "Please specify a command to apply on the selected frames" | |
356 | + test_gdb_completion_offers_commands "$cmd -- " | |
357 | + } | |
358 | + | |
359 | + # '-' is a valid TUI command. | |
360 | + test_error_cmd2 $cmd " -- -" \ | |
361 | + "Cannot enable the TUI when output is not a terminal" | |
362 | + test_gdb_complete_unique \ | |
363 | + "$cmd -- -" \ | |
364 | + "$cmd -- -" | |
365 | + | |
366 | + test_error_cmd2 $cmd " -foo" \ | |
367 | + "Undefined command: \"-foo\". Try \"help\"\\." | |
368 | + test_gdb_complete_none "$cmd -foo" | |
369 | + | |
370 | + test_gdb_completion_offers_commands "$cmd -s " | |
371 | + } | |
372 | +} | |
373 | + | |
298 | 374 | # Miscellaneous tests. |
299 | 375 | proc_with_prefix test-misc {variant} { |
300 | 376 | global all_options |
@@ -731,13 +807,28 @@ foreach_with_prefix cmd { | ||
731 | 807 | test-enum $cmd |
732 | 808 | } |
733 | 809 | |
734 | -# Run the print integration tests. | |
735 | -test-print "" | |
810 | +# Run the print integration tests, both as "standalone", and under | |
811 | +# "frame apply". The latter checks that the "frame apply ... COMMAND" | |
812 | +# commands recurse the completion machinery for COMMAND completion | |
813 | +# correctly. | |
814 | +foreach prefix { | |
815 | + "" | |
816 | + "frame apply all " | |
817 | + "frame apply 1 " | |
818 | + "frame apply level 0 " | |
819 | +} { | |
820 | + test-print $prefix | |
821 | +} | |
736 | 822 | |
737 | -# Same for "compile print". | |
823 | +# Same for "compile print". Not really a wrapper prefix command like | |
824 | +# "frame apply", but similar enough that we test pretty much the same | |
825 | +# things. | |
738 | 826 | if ![skip_compile_feature_tests] { |
739 | 827 | test-print "compile " |
740 | 828 | } |
741 | 829 | |
742 | 830 | # Basic "backtrace" integration tests. |
743 | 831 | test-backtrace |
832 | + | |
833 | +# Basic "frame apply" integration tests. | |
834 | +test-frame-apply |
@@ -46,6 +46,7 @@ | ||
46 | 46 | #include <algorithm> |
47 | 47 | #include "common/gdb_optional.h" |
48 | 48 | #include "inline-frame.h" |
49 | +#include "stack.h" | |
49 | 50 | |
50 | 51 | /* Definition of struct thread_info exported to gdbthread.h. */ |
51 | 52 |
@@ -1653,7 +1654,7 @@ static void | ||
1653 | 1654 | tfaas_command (const char *cmd, int from_tty) |
1654 | 1655 | { |
1655 | 1656 | std::string expanded |
1656 | - = std::string ("thread apply all -s frame apply all -s ") + cmd; | |
1657 | + = std::string ("thread apply all -s -- frame apply all -s ") + cmd; | |
1657 | 1658 | execute_command (expanded.c_str (), from_tty); |
1658 | 1659 | } |
1659 | 1660 |
@@ -1938,6 +1939,7 @@ void | ||
1938 | 1939 | _initialize_thread (void) |
1939 | 1940 | { |
1940 | 1941 | static struct cmd_list_element *thread_apply_list = NULL; |
1942 | + cmd_list_element *c; | |
1941 | 1943 | |
1942 | 1944 | add_info ("threads", info_threads_command, |
1943 | 1945 | _("Display currently known threads.\n\ |
@@ -1983,10 +1985,12 @@ Apply a command to all threads (ignoring errors and empty output).\n\ | ||
1983 | 1985 | Usage: taas COMMAND\n\ |
1984 | 1986 | shortcut for 'thread apply all -s COMMAND'")); |
1985 | 1987 | |
1986 | - add_com ("tfaas", class_run, tfaas_command, _("\ | |
1988 | + c = add_com ("tfaas", class_run, tfaas_command, _("\ | |
1987 | 1989 | Apply a command to all frames of all threads (ignoring errors and empty output).\n\ |
1988 | -Usage: tfaas COMMAND\n\ | |
1989 | -shortcut for 'thread apply all -s frame apply all -s COMMAND'")); | |
1990 | +Usage: tfaas [OPTION]... COMMAND\n\ | |
1991 | +shortcut for 'thread apply all -s -- frame apply all -s [OPTION]... COMMAND'\n\ | |
1992 | +See \"help frame apply all\" for available options.")); | |
1993 | + set_cmd_completer_handle_brkchars (c, frame_apply_all_cmd_completer); | |
1990 | 1994 | |
1991 | 1995 | add_cmd ("name", class_run, thread_name_command, |
1992 | 1996 | _("Set the current thread's name.\n\ |