2013-05-21 Hui Zhu <hui@codesourcery.com>
* breakpoint.c (dprintf_breakpoint_ops): Remove its static. * breakpoint.h (dprintf_breakpoint_ops): Add extern. * mi/mi-cmd-break.c (ctype.h): New include. (gdb_obstack.h): New include. (mi_argv_to_format, mi_cmd_break_insert_1): New. (mi_cmd_break_insert): Call mi_cmd_break_insert_1. (mi_cmd_dprintf_insert): New. * mi/mi-cmds.c (mi_cmds): Add "dprintf-insert". * mi/mi-cmds.h (mi_cmd_dprintf_insert): New extern. 2013-05-21 Hui Zhu <hui@codesourcery.com> * gdb.texinfo (GDB/MI Breakpoint Commands): Describe the "-dprintf-insert" command. 2013-05-21 Hui Zhu <hui@codesourcery.com> * gdb.mi/Makefile.in (PROGS): Add "mi-dprintf". * gdb.mi/mi-dprintf.exp, gdb.mi/mi-dprintf.c: New.
This commit is contained in:
parent
624852650a
commit
c5867ab65c
@ -1,3 +1,15 @@
|
||||
2013-05-21 Hui Zhu <hui@codesourcery.com>
|
||||
|
||||
* breakpoint.c (dprintf_breakpoint_ops): Remove its static.
|
||||
* breakpoint.h (dprintf_breakpoint_ops): Add extern.
|
||||
* mi/mi-cmd-break.c (ctype.h): New include.
|
||||
(gdb_obstack.h): New include.
|
||||
(mi_argv_to_format, mi_cmd_break_insert_1): New.
|
||||
(mi_cmd_break_insert): Call mi_cmd_break_insert_1.
|
||||
(mi_cmd_dprintf_insert): New.
|
||||
* mi/mi-cmds.c (mi_cmds): Add "dprintf-insert".
|
||||
* mi/mi-cmds.h (mi_cmd_dprintf_insert): New extern.
|
||||
|
||||
2013-05-20 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* python/py-prettyprint.c (search_pp_list): Decref 'attr'.
|
||||
|
2
gdb/NEWS
2
gdb/NEWS
@ -70,6 +70,8 @@ show debug nios2
|
||||
** The -trace-save MI command can optionally save trace buffer in Common
|
||||
Trace Format now.
|
||||
|
||||
** The new command -dprintf-insert sets a dynamic printf breakpoint.
|
||||
|
||||
*** Changes in GDB 7.6
|
||||
|
||||
* Target record has been renamed to record-full.
|
||||
|
@ -301,7 +301,7 @@ struct breakpoint_ops bkpt_breakpoint_ops;
|
||||
static struct breakpoint_ops bkpt_probe_breakpoint_ops;
|
||||
|
||||
/* Dynamic printf class type. */
|
||||
static struct breakpoint_ops dprintf_breakpoint_ops;
|
||||
struct breakpoint_ops dprintf_breakpoint_ops;
|
||||
|
||||
/* The style in which to perform a dynamic printf. This is a user
|
||||
option because different output options have different tradeoffs;
|
||||
|
@ -1212,6 +1212,7 @@ extern void tbreak_command (char *, int);
|
||||
extern struct breakpoint_ops base_breakpoint_ops;
|
||||
extern struct breakpoint_ops bkpt_breakpoint_ops;
|
||||
extern struct breakpoint_ops tracepoint_breakpoint_ops;
|
||||
extern struct breakpoint_ops dprintf_breakpoint_ops;
|
||||
|
||||
extern void initialize_breakpoint_ops (void);
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2013-05-21 Hui Zhu <hui@codesourcery.com>
|
||||
|
||||
* gdb.texinfo (GDB/MI Breakpoint Commands): Describe the
|
||||
"-dprintf-insert" command.
|
||||
|
||||
2013-05-17 Doug Evans <dje@google.com>
|
||||
|
||||
* gdb.texinfo (Maintenance Commands): Update doc for
|
||||
|
@ -29789,6 +29789,84 @@ times="0"@}]@}
|
||||
@c (gdb)
|
||||
@end smallexample
|
||||
|
||||
@subheading The @code{-dprintf-insert} Command
|
||||
@findex -dprintf-insert
|
||||
|
||||
@subsubheading Synopsis
|
||||
|
||||
@smallexample
|
||||
-dprintf-insert [ -t ] [ -f ] [ -d ]
|
||||
[ -c @var{condition} ] [ -i @var{ignore-count} ]
|
||||
[ -p @var{thread-id} ] [ @var{location} ] [ @var{format} ]
|
||||
[ @var{argument} ]
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
If specified, @var{location}, can be one of:
|
||||
|
||||
@itemize @bullet
|
||||
@item @var{function}
|
||||
@c @item +offset
|
||||
@c @item -offset
|
||||
@c @item @var{linenum}
|
||||
@item @var{filename}:@var{linenum}
|
||||
@item @var{filename}:function
|
||||
@item *@var{address}
|
||||
@end itemize
|
||||
|
||||
The possible optional parameters of this command are:
|
||||
|
||||
@table @samp
|
||||
@item -t
|
||||
Insert a temporary breakpoint.
|
||||
@item -f
|
||||
If @var{location} cannot be parsed (for example, if it
|
||||
refers to unknown files or functions), create a pending
|
||||
breakpoint. Without this flag, @value{GDBN} will report
|
||||
an error, and won't create a breakpoint, if @var{location}
|
||||
cannot be parsed.
|
||||
@item -d
|
||||
Create a disabled breakpoint.
|
||||
@item -c @var{condition}
|
||||
Make the breakpoint conditional on @var{condition}.
|
||||
@item -i @var{ignore-count}
|
||||
Set the ignore count of the breakpoint (@pxref{Conditions, ignore count})
|
||||
to @var{ignore-count}.
|
||||
@item -p @var{thread-id}
|
||||
Restrict the breakpoint to the specified @var{thread-id}.
|
||||
@end table
|
||||
|
||||
@subsubheading Result
|
||||
|
||||
@xref{GDB/MI Breakpoint Information}, for details on the format of the
|
||||
resulting breakpoint.
|
||||
|
||||
@c An out-of-band breakpoint instead of part of the result?
|
||||
|
||||
@subsubheading @value{GDBN} Command
|
||||
|
||||
The corresponding @value{GDBN} command is @samp{dprintf}.
|
||||
|
||||
@subsubheading Example
|
||||
|
||||
@smallexample
|
||||
(gdb)
|
||||
4-dprintf-insert foo "At foo entry\n"
|
||||
4^done,bkpt=@{number="1",type="dprintf",disp="keep",enabled="y",
|
||||
addr="0x000000000040061b",func="foo",file="mi-dprintf.c",
|
||||
fullname="mi-dprintf.c",line="25",thread-groups=["i1"],
|
||||
times="0",script=@{"printf \"At foo entry\\n\"","continue"@},
|
||||
original-location="foo"@}
|
||||
(gdb)
|
||||
5-dprintf-insert 26 "arg=%d, g=%d\n" arg g
|
||||
5^done,bkpt=@{number="2",type="dprintf",disp="keep",enabled="y",
|
||||
addr="0x000000000040062a",func="foo",file="mi-dprintf.c",
|
||||
fullname="mi-dprintf.c",line="26",thread-groups=["i1"],
|
||||
times="0",script=@{"printf \"arg=%d, g=%d\\n\", arg, g","continue"@},
|
||||
original-location="mi-dprintf.c:26"@}
|
||||
(gdb)
|
||||
@end smallexample
|
||||
|
||||
@subheading The @code{-break-list} Command
|
||||
@findex -break-list
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "observer.h"
|
||||
#include "mi-main.h"
|
||||
#include "mi-cmd-break.h"
|
||||
#include "gdb_obstack.h"
|
||||
#include <ctype.h>
|
||||
|
||||
enum
|
||||
{
|
||||
@ -84,11 +86,83 @@ setup_breakpoint_reporting (void)
|
||||
}
|
||||
|
||||
|
||||
/* Implements the -break-insert command.
|
||||
See the MI manual for the list of possible options. */
|
||||
/* Convert arguments in ARGV to the string in "format",argv,argv...
|
||||
and return it. */
|
||||
|
||||
void
|
||||
mi_cmd_break_insert (char *command, char **argv, int argc)
|
||||
static char *
|
||||
mi_argv_to_format (char **argv, int argc)
|
||||
{
|
||||
int i;
|
||||
struct obstack obstack;
|
||||
char *ret;
|
||||
|
||||
obstack_init (&obstack);
|
||||
|
||||
/* Convert ARGV[OIND + 1] to format string and save to FORMAT. */
|
||||
obstack_1grow (&obstack, '\"');
|
||||
for (i = 0; i < strlen (argv[0]); i++)
|
||||
{
|
||||
switch (argv[0][i])
|
||||
{
|
||||
case '\\':
|
||||
obstack_grow (&obstack, "\\\\", 2);
|
||||
break;
|
||||
case '\a':
|
||||
obstack_grow (&obstack, "\\a", 2);
|
||||
break;
|
||||
case '\b':
|
||||
obstack_grow (&obstack, "\\b", 2);
|
||||
break;
|
||||
case '\f':
|
||||
obstack_grow (&obstack, "\\f", 2);
|
||||
break;
|
||||
case '\n':
|
||||
obstack_grow (&obstack, "\\n", 2);
|
||||
break;
|
||||
case '\r':
|
||||
obstack_grow (&obstack, "\\r", 2);
|
||||
break;
|
||||
case '\t':
|
||||
obstack_grow (&obstack, "\\t", 2);
|
||||
break;
|
||||
case '\v':
|
||||
obstack_grow (&obstack, "\\v", 2);
|
||||
break;
|
||||
default:
|
||||
if (isprint (argv[0][i]))
|
||||
obstack_grow (&obstack, argv[0] + i, 1);
|
||||
else
|
||||
{
|
||||
char tmp[5];
|
||||
|
||||
sprintf (tmp, "\\%o", (unsigned char) argv[0][i]);
|
||||
obstack_grow (&obstack, tmp, strlen (tmp));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
obstack_1grow (&obstack, '\"');
|
||||
|
||||
/* Apply other argv to FORMAT. */
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
obstack_1grow (&obstack, ',');
|
||||
obstack_grow (&obstack, argv[i], strlen (argv[i]));
|
||||
}
|
||||
obstack_1grow (&obstack, '\0');
|
||||
|
||||
ret = xstrdup (obstack_finish (&obstack));
|
||||
obstack_free (&obstack, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Insert breakpoint.
|
||||
If dprintf is true, it will insert dprintf.
|
||||
If not, it will insert other type breakpoint. */
|
||||
|
||||
static void
|
||||
mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
|
||||
{
|
||||
char *address = NULL;
|
||||
int hardware = 0;
|
||||
@ -99,9 +173,10 @@ mi_cmd_break_insert (char *command, char **argv, int argc)
|
||||
int pending = 0;
|
||||
int enabled = 1;
|
||||
int tracepoint = 0;
|
||||
struct cleanup *back_to;
|
||||
struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
|
||||
enum bptype type_wanted;
|
||||
struct breakpoint_ops *ops;
|
||||
char *extra_string = NULL;
|
||||
|
||||
enum opt
|
||||
{
|
||||
@ -163,35 +238,79 @@ mi_cmd_break_insert (char *command, char **argv, int argc)
|
||||
}
|
||||
|
||||
if (oind >= argc)
|
||||
error (_("-break-insert: Missing <location>"));
|
||||
if (oind < argc - 1)
|
||||
error (_("-break-insert: Garbage following <location>"));
|
||||
error (_("-%s-insert: Missing <location>"),
|
||||
dprintf ? "dprintf" : "break");
|
||||
address = argv[oind];
|
||||
if (dprintf)
|
||||
{
|
||||
int format_num = oind + 1;
|
||||
|
||||
if (hardware || tracepoint)
|
||||
error (_("-dprintf-insert: does not support -h or -a"));
|
||||
if (format_num >= argc)
|
||||
error (_("-dprintf-insert: Missing <format>"));
|
||||
|
||||
extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
|
||||
make_cleanup (xfree, extra_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oind < argc - 1)
|
||||
error (_("-break-insert: Garbage following <location>"));
|
||||
}
|
||||
|
||||
/* Now we have what we need, let's insert the breakpoint! */
|
||||
back_to = setup_breakpoint_reporting ();
|
||||
setup_breakpoint_reporting ();
|
||||
|
||||
/* Note that to request a fast tracepoint, the client uses the
|
||||
"hardware" flag, although there's nothing of hardware related to
|
||||
fast tracepoints -- one can implement slow tracepoints with
|
||||
hardware breakpoints, but fast tracepoints are always software.
|
||||
"fast" is a misnomer, actually, "jump" would be more appropriate.
|
||||
A simulator or an emulator could conceivably implement fast
|
||||
regular non-jump based tracepoints. */
|
||||
type_wanted = (tracepoint
|
||||
? (hardware ? bp_fast_tracepoint : bp_tracepoint)
|
||||
: (hardware ? bp_hardware_breakpoint : bp_breakpoint));
|
||||
ops = tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
|
||||
if (tracepoint)
|
||||
{
|
||||
/* Note that to request a fast tracepoint, the client uses the
|
||||
"hardware" flag, although there's nothing of hardware related to
|
||||
fast tracepoints -- one can implement slow tracepoints with
|
||||
hardware breakpoints, but fast tracepoints are always software.
|
||||
"fast" is a misnomer, actually, "jump" would be more appropriate.
|
||||
A simulator or an emulator could conceivably implement fast
|
||||
regular non-jump based tracepoints. */
|
||||
type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint;
|
||||
ops = &tracepoint_breakpoint_ops;
|
||||
}
|
||||
else if (dprintf)
|
||||
{
|
||||
type_wanted = bp_dprintf;
|
||||
ops = &dprintf_breakpoint_ops;
|
||||
}
|
||||
else
|
||||
{
|
||||
type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
|
||||
ops = &bkpt_breakpoint_ops;
|
||||
}
|
||||
|
||||
create_breakpoint (get_current_arch (), address, condition, thread,
|
||||
NULL,
|
||||
extra_string,
|
||||
0 /* condition and thread are valid. */,
|
||||
temp_p, type_wanted,
|
||||
ignore_count,
|
||||
pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
|
||||
ops, 0, enabled, 0, 0);
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
/* Implements the -break-insert command.
|
||||
See the MI manual for the list of possible options. */
|
||||
|
||||
void
|
||||
mi_cmd_break_insert (char *command, char **argv, int argc)
|
||||
{
|
||||
mi_cmd_break_insert_1 (0, command, argv, argc);
|
||||
}
|
||||
|
||||
/* Implements the -dprintf-insert command.
|
||||
See the MI manual for the list of possible options. */
|
||||
|
||||
void
|
||||
mi_cmd_dprintf_insert (char *command, char **argv, int argc)
|
||||
{
|
||||
mi_cmd_break_insert_1 (1, command, argv, argc);
|
||||
}
|
||||
|
||||
enum wp_type
|
||||
|
@ -61,6 +61,8 @@ static struct mi_cmd mi_cmds[] =
|
||||
DEF_MI_CMD_CLI ("break-info", "info break", 1),
|
||||
DEF_MI_CMD_MI_1 ("break-insert", mi_cmd_break_insert,
|
||||
&mi_suppress_notification.breakpoint),
|
||||
DEF_MI_CMD_MI_1 ("dprintf-insert", mi_cmd_dprintf_insert,
|
||||
&mi_suppress_notification.breakpoint),
|
||||
DEF_MI_CMD_CLI ("break-list", "info break", 0),
|
||||
DEF_MI_CMD_MI_1 ("break-passcount", mi_cmd_break_passcount,
|
||||
&mi_suppress_notification.breakpoint),
|
||||
|
@ -39,6 +39,7 @@ typedef void (mi_cmd_argv_ftype) (char *command, char **argv, int argc);
|
||||
extern mi_cmd_argv_ftype mi_cmd_ada_task_info;
|
||||
extern mi_cmd_argv_ftype mi_cmd_add_inferior;
|
||||
extern mi_cmd_argv_ftype mi_cmd_break_insert;
|
||||
extern mi_cmd_argv_ftype mi_cmd_dprintf_insert;
|
||||
extern mi_cmd_argv_ftype mi_cmd_break_commands;
|
||||
extern mi_cmd_argv_ftype mi_cmd_break_passcount;
|
||||
extern mi_cmd_argv_ftype mi_cmd_break_watch;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2013-05-21 Hui Zhu <hui@codesourcery.com>
|
||||
|
||||
* gdb.mi/Makefile.in (PROGS): Add "mi-dprintf".
|
||||
* gdb.mi/mi-dprintf.exp, gdb.mi/mi-dprintf.c: New.
|
||||
|
||||
2013-05-20 Doug Evans <dje@google.com>
|
||||
|
||||
* lib/dwarf.exp (Dwarf): New variable _abbrev_section.
|
||||
|
@ -3,7 +3,7 @@ srcdir = @srcdir@
|
||||
|
||||
PROGS = basics c_variable cpp_variable var-cmd dw2-ref-missing-frame \
|
||||
gdb669-pthreads gdb701 gdb792 mi-async mi-basics mi-break \
|
||||
mi-cli mi-console mi-disassemble mi-eval mi-file \
|
||||
mi-cli mi-console mi-disassemble mi-dprintf mi-eval mi-file \
|
||||
mi-file-transfer mi-non-stop mi-non-stop-exit \
|
||||
mi-ns-stale-regcache mi-nsintrall mi-nsmoribund mi-nsthrexec \
|
||||
mi-pending mi-pthreads mi-read-memory mi-regs mi-return \
|
||||
|
59
gdb/testsuite/gdb.mi/mi-dprintf.c
Normal file
59
gdb/testsuite/gdb.mi/mi-dprintf.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
Contributed by Hui Zhu <hui@codesourcery.com>
|
||||
|
||||
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/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int g;
|
||||
|
||||
void
|
||||
foo (int arg)
|
||||
{
|
||||
g += arg;
|
||||
g *= 2; /* set dprintf 1 here */
|
||||
g /= 2.5; /* set breakpoint 1 here */
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int loc = 1234;
|
||||
|
||||
/* Ensure these functions are available. */
|
||||
printf ("kickoff %d\n", loc);
|
||||
fprintf (stderr, "also to stderr %d\n", loc);
|
||||
|
||||
foo (loc++);
|
||||
foo (loc++);
|
||||
foo (loc++);
|
||||
return g;
|
||||
}
|
||||
|
||||
/* Make sure function 'malloc' is linked into program. On some bare-metal
|
||||
port, if we don't use 'malloc', it will not be linked in program. 'malloc'
|
||||
is needed, otherwise we'll see such error message
|
||||
evaluation of this expression requires the program to have a function
|
||||
"malloc". */
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
void *p = malloc (16);
|
||||
|
||||
free (p);
|
||||
}
|
145
gdb/testsuite/gdb.mi/mi-dprintf.exp
Normal file
145
gdb/testsuite/gdb.mi/mi-dprintf.exp
Normal file
@ -0,0 +1,145 @@
|
||||
# Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
# Contributed by Hui Zhu <hui@codesourcery.com>
|
||||
|
||||
# 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/>.
|
||||
|
||||
load_lib mi-support.exp
|
||||
set MIFLAGS "-i=mi"
|
||||
|
||||
gdb_exit
|
||||
if [mi_gdb_start] {
|
||||
continue
|
||||
}
|
||||
|
||||
standard_testfile
|
||||
|
||||
if {[build_executable $testfile.exp $testfile $srcfile {debug}] == -1} {
|
||||
untested "failed to compile $testfile"
|
||||
return -1
|
||||
}
|
||||
|
||||
mi_delete_breakpoints
|
||||
|
||||
set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
|
||||
set dp_location1 [gdb_get_line_number "set dprintf 1 here"]
|
||||
|
||||
mi_run_to_main
|
||||
|
||||
mi_gdb_test "1-dprintf-insert" \
|
||||
"1\\^error,msg=\"-dprintf-insert: Missing <location>\"" "mi insert without location"
|
||||
|
||||
mi_gdb_test "2-dprintf-insert foo" \
|
||||
"2\\^error,msg=\"-dprintf-insert: Missing <format>\"" "mi insert breakpoint without format string"
|
||||
|
||||
mi_gdb_test "3-dprintf-insert 29" \
|
||||
"3\\^error,msg=\"-dprintf-insert: Missing <format>\"" "mi insert second breakpoint without format string"
|
||||
|
||||
mi_gdb_test "-break-insert main" ".*" "mi insert breakpoint main"
|
||||
mi_delete_breakpoints
|
||||
|
||||
mi_gdb_test "4-dprintf-insert foo \"At foo entry\\n\"" \
|
||||
"4\\^done,bkpt=\{number=\".*\",type=\"dprintf\".*func=\"foo\",file=\".*mi-dprintf.c\",fullname=\".*mi-dprintf.c\",line=\".*\".*" "mi insert dprintf foo"
|
||||
|
||||
mi_gdb_test "5-dprintf-insert $dp_location1 \"arg=%d, g=%d\\n\" arg g" \
|
||||
"5\\^done,bkpt=\{number=\".*\",type=\"dprintf\".*func=\"foo\",file=\".*mi-dprintf.c\",fullname=\".*mi-dprintf.c\",line=\"$dp_location1\".*" \
|
||||
"mi insert dprintf dp_location1"
|
||||
|
||||
mi_gdb_test "6-break-info" \
|
||||
"6\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\},\{width=\".*\",alignment=\".*\",col_name=\"type\",colhdr=\"Type\"\},\{width=\".*\",alignment=\".*\",col_name=\"disp\",colhdr=\"Disp\"\},\{width=\".*\",alignment=\".*\",col_name=\"enabled\",colhdr=\"Enb\"\},\{width=\".*\",alignment=\".*\",col_name=\"addr\",colhdr=\"Address\"\},\{width=\".*\",alignment=\".*\",col_name=\"what\",colhdr=\"What\"\}\\\],body=\\\[bkpt=\{number=\"3\",type=\"dprintf\".*func=\"foo\",file=\".*mi-dprintf.c\",fullname=\".*mi-dprintf.c\",line=\".*\".*,bkpt=\{number=\".*\",type=\"dprintf\".*func=\"foo\",file=\".*mi-dprintf.c\",fullname=\".*mi-dprintf.c\",line=\"$dp_location1\".*" \
|
||||
"mi info dprintf"
|
||||
|
||||
mi_gdb_test "-break-insert $bp_location1" ".*" "mi insert breakpoint bp_location1"
|
||||
|
||||
proc mi_continue_dprintf {args} {
|
||||
with_test_prefix $args {
|
||||
global mi_gdb_prompt
|
||||
|
||||
mi_run_cmd
|
||||
set msg "mi 1st dprintf"
|
||||
gdb_expect {
|
||||
-re ".*At foo entry.*arg=1234, g=1234.*" {
|
||||
pass $msg
|
||||
}
|
||||
-re ".*$mi_gdb_prompt$" {
|
||||
fail $msg
|
||||
}
|
||||
timeout {
|
||||
fail $msg
|
||||
}
|
||||
}
|
||||
mi_expect_stop ".*" ".*" ".*" ".*" ".*" "" "$msg stop"
|
||||
|
||||
set msg "mi 2nd dprintf"
|
||||
mi_send_resuming_command "exec-continue" "$msg continue"
|
||||
gdb_expect {
|
||||
-re ".*At foo entry.*arg=1235, g=2222.*" {
|
||||
pass $msg
|
||||
}
|
||||
-re ".*$mi_gdb_prompt$" {
|
||||
fail $msg
|
||||
}
|
||||
timeout {
|
||||
fail $msg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mi_continue_dprintf "gdb"
|
||||
|
||||
# The "call" style depends on having I/O functions available, so test.
|
||||
|
||||
if ![target_info exists gdb,noinferiorio] {
|
||||
|
||||
# Now switch styles and rerun; in the absence of redirection the
|
||||
# output should be the same.
|
||||
|
||||
mi_gdb_test "set dprintf-style call" ".*" "mi set dprintf style to call"
|
||||
mi_continue_dprintf "call"
|
||||
|
||||
mi_gdb_test "set dprintf-function fprintf" ".*" "mi set dprintf-channel stderr"
|
||||
mi_gdb_test "set dprintf-channel stderr" ".*" "mi set dprintf channel"
|
||||
mi_continue_dprintf "fprintf"
|
||||
}
|
||||
|
||||
set target_can_dprintf 0
|
||||
set msg "set dprintf style to agent"
|
||||
send_gdb "set dprintf-style agent\n"
|
||||
gdb_expect {
|
||||
-re "warning: Target cannot run dprintf commands, falling back to GDB printf.*$mi_gdb_prompt$" {
|
||||
unsupported "$msg"
|
||||
}
|
||||
-re ".*done.*$mi_gdb_prompt$" {
|
||||
set target_can_dprintf 1
|
||||
pass "$msg"
|
||||
}
|
||||
-re ".*$mi_gdb_prompt$" {
|
||||
fail "$msg"
|
||||
}
|
||||
timeout {
|
||||
fail "$msg"
|
||||
}
|
||||
}
|
||||
|
||||
if $target_can_dprintf {
|
||||
mi_run_cmd
|
||||
|
||||
mi_gdb_test "continue" ".*breakpoint-hit.*func=\"foo\".*" "mi 1st dprintf, agent"
|
||||
|
||||
mi_gdb_test "continue" ".*breakpoint-hit.*func=\"foo\".*" "mi 2nd dprintf, agent"
|
||||
|
||||
mi_gdb_test "6-break-info" ".*modified.*" "mi info dprintf second time"
|
||||
}
|
||||
|
||||
mi_gdb_test "set dprintf-style foobar" ".*error.*" "mi set dprintf style to an unrecognized type"
|
Loading…
x
Reference in New Issue
Block a user