diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 30 | ||||
-rw-r--r-- | gdb/NEWS | 4 | ||||
-rw-r--r-- | gdb/btrace.c | 72 | ||||
-rw-r--r-- | gdb/btrace.h | 6 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 63 | ||||
-rw-r--r-- | gdb/python/py-record-btrace.c | 9 | ||||
-rw-r--r-- | gdb/record-btrace.c | 177 | ||||
-rw-r--r-- | gdb/record-btrace.h | 4 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.btrace/cpu.exp | 76 |
11 files changed, 416 insertions, 33 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d058d9e..b86bb7f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,35 @@ 2018-04-13 Markus Metzger <markus.t.metzger@intel.com> + * NEWS (New options): announce set/show record btrace cpu. + * btrace.c: Include record-btrace.h. + (btrace_compute_ftrace_pt): Skip enabling errata workarounds if + the vendor is unknown. + (btrace_compute_ftrace_1): Add cpu parameter. Update callers. + Maybe overwrite the btrace configuration's cpu. + (btrace_compute_ftrace): Add cpu parameter. Update callers. + (btrace_fetch): Add cpu parameter. Update callers. + (btrace_maint_update_pt_packets): Call record_btrace_get_cpu. + Maybe overwrite the btrace configuration's cpu. Skip enabling + errata workarounds if the vendor is unknown. + * python/py-record-btrace.c: Include record-btrace.h. + (recpy_bt_begin, recpy_bt_end, recpy_bt_instruction_history) + (recpy_bt_function_call_history): Call record_btrace_get_cpu. + * record-btrace.c (record_btrace_cpu_state_kind): New. + (record_btrace_cpu): New. + (set_record_btrace_cpu_cmdlist): New. + (record_btrace_get_cpu): New. + (require_btrace_thread, record_btrace_info) + (record_btrace_resume_thread): Call record_btrace_get_cpu. + (cmd_set_record_btrace_cpu_none): New. + (cmd_set_record_btrace_cpu_auto): New. + (cmd_set_record_btrace_cpu): New. + (cmd_show_record_btrace_cpu): New. + (_initialize_record_btrace): Initialize set/show record btrace cpu + commands. + * record-btrace.h (record_btrace_get_cpu): New. + +2018-04-13 Markus Metzger <markus.t.metzger@intel.com> + * record.c (set_record_command): Fix typo in message. 2018-04-13 Markus Metzger <markus.t.metzger@intel.com> @@ -17,6 +17,10 @@ set|show varsize-limit objects being printed when those objects have a variable type, instead of that maximum size being hardcoded to 65536 bytes. +set|show record btrace cpu + Controls the processor to be used for enabling errata workarounds for + branch trace decode. + * New targets RiscV ELF riscv*-*-elf diff --git a/gdb/btrace.c b/gdb/btrace.c index 158d03c..269ee51 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -35,6 +35,9 @@ #include "gdbcmd.h" #include "cli/cli-utils.h" +/* For maintenance commands. */ +#include "record-btrace.h" + #include <inttypes.h> #include <ctype.h> #include <algorithm> @@ -1428,15 +1431,20 @@ btrace_compute_ftrace_pt (struct thread_info *tp, config.begin = btrace->data; config.end = btrace->data + btrace->size; - config.cpu.vendor = pt_translate_cpu_vendor (btrace->config.cpu.vendor); - config.cpu.family = btrace->config.cpu.family; - config.cpu.model = btrace->config.cpu.model; - config.cpu.stepping = btrace->config.cpu.stepping; + /* We treat an unknown vendor as 'no errata'. */ + if (btrace->config.cpu.vendor != CV_UNKNOWN) + { + config.cpu.vendor + = pt_translate_cpu_vendor (btrace->config.cpu.vendor); + config.cpu.family = btrace->config.cpu.family; + config.cpu.model = btrace->config.cpu.model; + config.cpu.stepping = btrace->config.cpu.stepping; - errcode = pt_cpu_errata (&config.errata, &config.cpu); - if (errcode < 0) - error (_("Failed to configure the Intel Processor Trace decoder: %s."), - pt_errstr (pt_errcode (errcode))); + errcode = pt_cpu_errata (&config.errata, &config.cpu); + if (errcode < 0) + error (_("Failed to configure the Intel Processor Trace " + "decoder: %s."), pt_errstr (pt_errcode (errcode))); + } decoder = pt_insn_alloc_decoder (&config); if (decoder == NULL) @@ -1485,10 +1493,14 @@ btrace_compute_ftrace_pt (struct thread_info *tp, #endif /* defined (HAVE_LIBIPT) */ /* Compute the function branch trace from a block branch trace BTRACE for - a thread given by BTINFO. */ + a thread given by BTINFO. If CPU is not NULL, overwrite the cpu in the + branch trace configuration. This is currently only used for the PT + format. */ static void -btrace_compute_ftrace_1 (struct thread_info *tp, struct btrace_data *btrace, +btrace_compute_ftrace_1 (struct thread_info *tp, + struct btrace_data *btrace, + const struct btrace_cpu *cpu, std::vector<unsigned int> &gaps) { DEBUG ("compute ftrace"); @@ -1503,6 +1515,10 @@ btrace_compute_ftrace_1 (struct thread_info *tp, struct btrace_data *btrace, return; case BTRACE_FORMAT_PT: + /* Overwrite the cpu we use for enabling errata workarounds. */ + if (cpu != nullptr) + btrace->variant.pt.config.cpu = *cpu; + btrace_compute_ftrace_pt (tp, &btrace->variant.pt, gaps); return; } @@ -1521,13 +1537,14 @@ btrace_finalize_ftrace (struct thread_info *tp, std::vector<unsigned int> &gaps) } static void -btrace_compute_ftrace (struct thread_info *tp, struct btrace_data *btrace) +btrace_compute_ftrace (struct thread_info *tp, struct btrace_data *btrace, + const struct btrace_cpu *cpu) { std::vector<unsigned int> gaps; TRY { - btrace_compute_ftrace_1 (tp, btrace, gaps); + btrace_compute_ftrace_1 (tp, btrace, cpu, gaps); } CATCH (error, RETURN_MASK_ALL) { @@ -1564,7 +1581,7 @@ btrace_add_pc (struct thread_info *tp) block->begin = pc; block->end = pc; - btrace_compute_ftrace (tp, &btrace); + btrace_compute_ftrace (tp, &btrace, NULL); do_cleanups (cleanup); } @@ -1872,7 +1889,7 @@ btrace_decode_error (enum btrace_format format, int errcode) /* See btrace.h. */ void -btrace_fetch (struct thread_info *tp) +btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu) { struct btrace_thread_info *btinfo; struct btrace_target_info *tinfo; @@ -1948,7 +1965,7 @@ btrace_fetch (struct thread_info *tp) btrace_maint_clear (btinfo); btrace_clear_history (btinfo); - btrace_compute_ftrace (tp, &btrace); + btrace_compute_ftrace (tp, &btrace, cpu); } do_cleanups (cleanup); @@ -3028,6 +3045,7 @@ static void btrace_maint_update_pt_packets (struct btrace_thread_info *btinfo) { struct pt_packet_decoder *decoder; + const struct btrace_cpu *cpu; struct btrace_data_pt *pt; struct pt_config config; int errcode; @@ -3044,15 +3062,23 @@ btrace_maint_update_pt_packets (struct btrace_thread_info *btinfo) config.begin = pt->data; config.end = pt->data + pt->size; - config.cpu.vendor = pt_translate_cpu_vendor (pt->config.cpu.vendor); - config.cpu.family = pt->config.cpu.family; - config.cpu.model = pt->config.cpu.model; - config.cpu.stepping = pt->config.cpu.stepping; + cpu = record_btrace_get_cpu (); + if (cpu == nullptr) + cpu = &pt->config.cpu; + + /* We treat an unknown vendor as 'no errata'. */ + if (cpu->vendor != CV_UNKNOWN) + { + config.cpu.vendor = pt_translate_cpu_vendor (cpu->vendor); + config.cpu.family = cpu->family; + config.cpu.model = cpu->model; + config.cpu.stepping = cpu->stepping; - errcode = pt_cpu_errata (&config.errata, &config.cpu); - if (errcode < 0) - error (_("Failed to configure the Intel Processor Trace decoder: %s."), - pt_errstr (pt_errcode (errcode))); + errcode = pt_cpu_errata (&config.errata, &config.cpu); + if (errcode < 0) + error (_("Failed to configure the Intel Processor Trace " + "decoder: %s."), pt_errstr (pt_errcode (errcode))); + } decoder = pt_pkt_alloc_decoder (&config); if (decoder == NULL) diff --git a/gdb/btrace.h b/gdb/btrace.h index 5c3f21b..4d57edb 100644 --- a/gdb/btrace.h +++ b/gdb/btrace.h @@ -385,8 +385,10 @@ extern void btrace_teardown (struct thread_info *); extern const char *btrace_decode_error (enum btrace_format format, int errcode); -/* Fetch the branch trace for a single thread. */ -extern void btrace_fetch (struct thread_info *); +/* Fetch the branch trace for a single thread. If CPU is not NULL, assume + CPU for trace decode. */ +extern void btrace_fetch (struct thread_info *, + const struct btrace_cpu *cpu); /* Clear the branch trace for a single thread. */ extern void btrace_clear (struct thread_info *); diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index f11fa0c..d21288b 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2018-04-13 Markus Metzger <markus.t.metzger@intel.com> + + * gdb.texinfo: Document set/show record btrace cpu. + 2018-03-27 Joel Brobecker <brobecker@adacore.com> * gdb.texinfo (Ada Settings): New subsubsection. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index bd20b39..5a83619 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -6952,10 +6952,73 @@ and to read-write memory. Beware that the accessed memory corresponds to the live target and not necessarily to the current replay position. +@item set record btrace cpu @var{identifier} +Set the processor to be used for enabling workarounds for processor +errata when decoding the trace. + +Processor errata are defects in processor operation, caused by its +design or manufacture. They can cause a trace not to match the +specification. This, in turn, may cause trace decode to fail. +@value{GDBN} can detect erroneous trace packets and correct them, thus +avoiding the decoding failures. These corrections are known as +@dfn{errata workarounds}, and are enabled based on the processor on +which the trace was recorded. + +By default, @value{GDBN} attempts to detect the processor +automatically, and apply the necessary workarounds for it. However, +you may need to specify the processor if @value{GDBN} does not yet +support it. This command allows you to do that, and also allows to +disable the workarounds. + +The argument @var{identifier} identifies the @sc{cpu} and is of the +form: @code{@var{vendor}:@var{procesor identifier}}. In addition, +there are two special identifiers, @code{none} and @code{auto} +(default). + +The following vendor identifiers and corresponding processor +identifiers are currently supported: + +@multitable @columnfractions .1 .9 + +@item @code{intel} +@tab @var{family}/@var{model}[/@var{stepping}] + +@end multitable + +On GNU/Linux systems, the processor @var{family}, @var{model}, and +@var{stepping} can be obtained from @code{/proc/cpuinfo}. + +If @var{identifier} is @code{auto}, enable errata workarounds for the +processor on which the trace was recorded. If @var{identifier} is +@code{none}, errata workarounds are disabled. + +For example, when using an old @value{GDBN} on a new system, decode +may fail because @value{GDBN} does not support the new processor. It +often suffices to specify an older processor that @value{GDBN} +supports. + +@smallexample +(gdb) info record +Active record target: record-btrace +Recording format: Intel Processor Trace. +Buffer size: 16kB. +Failed to configure the Intel Processor Trace decoder: unknown cpu. +(gdb) set record btrace cpu intel:6/158 +(gdb) info record +Active record target: record-btrace +Recording format: Intel Processor Trace. +Buffer size: 16kB. +Recorded 84872 instructions in 3189 functions (0 gaps) for thread 1 (...). +@end smallexample + @kindex show record btrace @item show record btrace replay-memory-access Show the current setting of @code{replay-memory-access}. +@item show record btrace cpu +Show the processor to be used for enabling trace decode errata +workarounds. + @kindex set record btrace bts @item set record btrace bts buffer-size @var{size} @itemx set record btrace bts buffer-size unlimited diff --git a/gdb/python/py-record-btrace.c b/gdb/python/py-record-btrace.c index 35828a6..d78df7f 100644 --- a/gdb/python/py-record-btrace.c +++ b/gdb/python/py-record-btrace.c @@ -24,6 +24,7 @@ #include "btrace.h" #include "py-record.h" #include "py-record-btrace.h" +#include "record-btrace.h" #include "disasm.h" #if defined (IS_PY3K) @@ -678,7 +679,7 @@ recpy_bt_begin (PyObject *self, void *closure) if (tinfo == NULL) Py_RETURN_NONE; - btrace_fetch (tinfo); + btrace_fetch (tinfo, record_btrace_get_cpu ()); if (btrace_is_empty (tinfo)) Py_RETURN_NONE; @@ -700,7 +701,7 @@ recpy_bt_end (PyObject *self, void *closure) if (tinfo == NULL) Py_RETURN_NONE; - btrace_fetch (tinfo); + btrace_fetch (tinfo, record_btrace_get_cpu ()); if (btrace_is_empty (tinfo)) Py_RETURN_NONE; @@ -724,7 +725,7 @@ recpy_bt_instruction_history (PyObject *self, void *closure) if (tinfo == NULL) Py_RETURN_NONE; - btrace_fetch (tinfo); + btrace_fetch (tinfo, record_btrace_get_cpu ()); if (btrace_is_empty (tinfo)) Py_RETURN_NONE; @@ -753,7 +754,7 @@ recpy_bt_function_call_history (PyObject *self, void *closure) if (tinfo == NULL) Py_RETURN_NONE; - btrace_fetch (tinfo); + btrace_fetch (tinfo, record_btrace_get_cpu ()); if (btrace_is_empty (tinfo)) Py_RETURN_NONE; diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 455e254..8736894 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -61,6 +61,20 @@ static const char *const replay_memory_access_types[] = /* The currently allowed replay memory access type. */ static const char *replay_memory_access = replay_memory_access_read_only; +/* The cpu state kinds. */ +enum record_btrace_cpu_state_kind +{ + CS_AUTO, + CS_NONE, + CS_CPU +}; + +/* The current cpu state. */ +static enum record_btrace_cpu_state_kind record_btrace_cpu_state = CS_AUTO; + +/* The current cpu for trace decode. */ +static struct btrace_cpu record_btrace_cpu; + /* Command lists for "set/show record btrace". */ static struct cmd_list_element *set_record_btrace_cmdlist; static struct cmd_list_element *show_record_btrace_cmdlist; @@ -88,6 +102,9 @@ static struct cmd_list_element *show_record_btrace_bts_cmdlist; static struct cmd_list_element *set_record_btrace_pt_cmdlist; static struct cmd_list_element *show_record_btrace_pt_cmdlist; +/* Command list for "set record btrace cpu". */ +static struct cmd_list_element *set_record_btrace_cpu_cmdlist; + /* Print a record-btrace debug message. Use do ... while (0) to avoid ambiguities when used in if statements. */ @@ -101,6 +118,26 @@ static struct cmd_list_element *show_record_btrace_pt_cmdlist; while (0) +/* Return the cpu configured by the user. Returns NULL if the cpu was + configured as auto. */ +const struct btrace_cpu * +record_btrace_get_cpu (void) +{ + switch (record_btrace_cpu_state) + { + case CS_AUTO: + return nullptr; + + case CS_NONE: + record_btrace_cpu.vendor = CV_UNKNOWN; + /* Fall through. */ + case CS_CPU: + return &record_btrace_cpu; + } + + error (_("Internal error: bad record btrace cpu state.")); +} + /* Update the branch trace for the current thread and return a pointer to its thread_info. @@ -120,7 +157,7 @@ require_btrace_thread (void) validate_registers_access (); - btrace_fetch (tp); + btrace_fetch (tp, record_btrace_get_cpu ()); if (btrace_is_empty (tp)) error (_("No trace.")); @@ -440,7 +477,7 @@ record_btrace_info (struct target_ops *self) if (conf != NULL) record_btrace_print_conf (conf); - btrace_fetch (tp); + btrace_fetch (tp, record_btrace_get_cpu ()); insns = 0; calls = 0; @@ -1848,7 +1885,7 @@ record_btrace_resume_thread (struct thread_info *tp, btinfo = &tp->btrace; /* Fetch the latest branch trace. */ - btrace_fetch (tp); + btrace_fetch (tp, record_btrace_get_cpu ()); /* A resume request overwrites a preceding resume or stop request. */ btinfo->flags &= ~(BTHR_MOVE | BTHR_STOP); @@ -2982,7 +3019,113 @@ cmd_show_replay_memory_access (struct ui_file *file, int from_tty, replay_memory_access); } -/* The "set record btrace bts" command. */ +/* The "set record btrace cpu none" command. */ + +static void +cmd_set_record_btrace_cpu_none (const char *args, int from_tty) +{ + if (args != nullptr && *args != 0) + error (_("Trailing junk: '%s'."), args); + + record_btrace_cpu_state = CS_NONE; +} + +/* The "set record btrace cpu auto" command. */ + +static void +cmd_set_record_btrace_cpu_auto (const char *args, int from_tty) +{ + if (args != nullptr && *args != 0) + error (_("Trailing junk: '%s'."), args); + + record_btrace_cpu_state = CS_AUTO; +} + +/* The "set record btrace cpu" command. */ + +static void +cmd_set_record_btrace_cpu (const char *args, int from_tty) +{ + if (args == nullptr) + args = ""; + + /* We use a hard-coded vendor string for now. */ + unsigned int family, model, stepping; + int l1, l2, matches = sscanf (args, "intel: %u/%u%n/%u%n", &family, + &model, &l1, &stepping, &l2); + if (matches == 3) + { + if (strlen (args) != l2) + error (_("Trailing junk: '%s'."), args + l2); + } + else if (matches == 2) + { + if (strlen (args) != l1) + error (_("Trailing junk: '%s'."), args + l1); + + stepping = 0; + } + else + error (_("Bad format. See \"help set record btrace cpu\".")); + + if (USHRT_MAX < family) + error (_("Cpu family too big.")); + + if (UCHAR_MAX < model) + error (_("Cpu model too big.")); + + if (UCHAR_MAX < stepping) + error (_("Cpu stepping too big.")); + + record_btrace_cpu.vendor = CV_INTEL; + record_btrace_cpu.family = family; + record_btrace_cpu.model = model; + record_btrace_cpu.stepping = stepping; + + record_btrace_cpu_state = CS_CPU; +} + +/* The "show record btrace cpu" command. */ + +static void +cmd_show_record_btrace_cpu (const char *args, int from_tty) +{ + const char *cpu; + + if (args != nullptr && *args != 0) + error (_("Trailing junk: '%s'."), args); + + switch (record_btrace_cpu_state) + { + case CS_AUTO: + printf_unfiltered (_("btrace cpu is 'auto'.\n")); + return; + + case CS_NONE: + printf_unfiltered (_("btrace cpu is 'none'.\n")); + return; + + case CS_CPU: + switch (record_btrace_cpu.vendor) + { + case CV_INTEL: + if (record_btrace_cpu.stepping == 0) + printf_unfiltered (_("btrace cpu is 'intel: %u/%u'.\n"), + record_btrace_cpu.family, + record_btrace_cpu.model); + else + printf_unfiltered (_("btrace cpu is 'intel: %u/%u/%u'.\n"), + record_btrace_cpu.family, + record_btrace_cpu.model, + record_btrace_cpu.stepping); + return; + } + } + + error (_("Internal error: bad cpu state.")); +} + +/* The "s record btrace bts" command. */ static void cmd_set_record_btrace_bts (const char *args, int from_tty) @@ -3090,6 +3233,32 @@ replay."), &set_record_btrace_cmdlist, &show_record_btrace_cmdlist); + add_prefix_cmd ("cpu", class_support, cmd_set_record_btrace_cpu, + _("\ +Set the cpu to be used for trace decode.\n\n\ +The format is \"<vendor>:<identifier>\" or \"none\" or \"auto\" (default).\n\ +For vendor \"intel\" the format is \"<family>/<model>[/<stepping>]\".\n\n\ +When decoding branch trace, enable errata workarounds for the specified cpu.\n\ +The default is \"auto\", which uses the cpu on which the trace was recorded.\n\ +When GDB does not support that cpu, this option can be used to enable\n\ +workarounds for a similar cpu that GDB supports.\n\n\ +When set to \"none\", errata workarounds are disabled."), + &set_record_btrace_cpu_cmdlist, + _("set record btrace cpu "), 1, + &set_record_btrace_cmdlist); + + add_cmd ("auto", class_support, cmd_set_record_btrace_cpu_auto, _("\ +Automatically determine the cpu to be used for trace decode."), + &set_record_btrace_cpu_cmdlist); + + add_cmd ("none", class_support, cmd_set_record_btrace_cpu_none, _("\ +Do not enable errata workarounds for trace decode."), + &set_record_btrace_cpu_cmdlist); + + add_cmd ("cpu", class_support, cmd_show_record_btrace_cpu, _("\ +Show the cpu to be used for trace decode."), + &show_record_btrace_cmdlist); + add_prefix_cmd ("bts", class_support, cmd_set_record_btrace_bts, _("Set record btrace bts options"), &set_record_btrace_bts_cmdlist, diff --git a/gdb/record-btrace.h b/gdb/record-btrace.h index ba66719..e17b643 100644 --- a/gdb/record-btrace.h +++ b/gdb/record-btrace.h @@ -25,4 +25,8 @@ /* Push the record_btrace target. */ extern void record_btrace_push_target (void); +/* Return the cpu configured by the user via "set btrace cpu". Returns + NULL if the cpu was configured as auto. */ +extern const struct btrace_cpu *record_btrace_get_cpu (void); + #endif /* RECORD_BTRACE_H */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0dc05dd..47fa4cf 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2018-04-13 Markus Metzger <markus.t.metzger@intel.com> + * gdb.btrace/cpu.exp: New. + +2018-04-13 Markus Metzger <markus.t.metzger@intel.com> + * gdb.base/step-indirect-call-thunk.exp: New. * gdb.base/step-indirect-call-thunk.c: New. * gdb.reverse/step-indirect-call-thunk.exp: New. diff --git a/gdb/testsuite/gdb.btrace/cpu.exp b/gdb/testsuite/gdb.btrace/cpu.exp new file mode 100644 index 0000000..fbe9821 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/cpu.exp @@ -0,0 +1,76 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2018 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +gdb_start + +proc test_good { arg } { + gdb_test_no_output "set record btrace cpu $arg" "set cpu $arg" + gdb_test "show record btrace cpu" "btrace cpu is '$arg'\." \ + "show cpu $arg" +} + +proc test_bad { arg current } { + gdb_test "set record btrace cpu $arg" \ + "Bad format\. See \"help set record btrace cpu\"\." \ + "set cpu $arg" + gdb_test "show record btrace cpu" "btrace cpu is '$current'\." \ + "show cpu $arg" +} + +proc test_junk { arg junk current } { + gdb_test "set record btrace cpu $arg" \ + "Trailing junk: '$junk'\." \ + "set cpu $arg" + gdb_test "show record btrace cpu" "btrace cpu is '$current'\." \ + "show cpu $arg" +} + +gdb_test "show record btrace cpu" "btrace cpu is 'auto'\." "default cpu" + +gdb_test "set record" \ + "\"set record\" must be followed by an appropriate subcommand.*" \ + "set record" +gdb_test "set record btrace" \ + "\"set record btrace\" must be followed by an appropriate subcommand.*" \ + "set record btrace" +test_bad "" "auto" + +test_good "intel: 0/0" +test_good "intel: 0/0/1" + +# We omit a zero stepping in the output. +gdb_test_no_output "set record btrace cpu intel: 0/0/0" \ + "set cpu intel: 0/0/0" +gdb_test "show record btrace cpu" "btrace cpu is 'intel: 0/0'\." \ + "show cpu intel: 0/0/0" + +test_good "auto" +test_good "none" + +test_bad "intel: foo" "none" +test_bad "intel: 0" "none" +test_bad "intel: 0/" "none" +test_bad "intel: 0/foo" "none" +test_bad "intel: foo/bar" "none" +test_bad "intel: foo/0" "none" +test_bad "intel: 0x0/0" "none" + +test_junk "intel: 0/0 foo" " foo" "none" +test_junk "intel: 0/0x0" "x0" "none" +test_junk "intel: 0/0/foo" "/foo" "none" +test_junk "intel: 0/0/0 foo" " foo" "none" +test_junk "intel: 0/0/0x0" "x0" "none" |