Bug 15289

Summary: "set remote hardware-watchpoint-limit" broken (zinteger commands)
Product: gdb Reporter: Pedro Alves <pedro>
Component: gdbAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: HEAD   
Target Milestone: 7.6   
URL: http://sourceware.org/ml/gdb-patches/2013-03/msg00033.html
Host: Target:
Build: Last reconfirmed:

Description Pedro Alves 2013-03-20 15:28:53 UTC
(gdb) help set remote hardware-watchpoint-limit 
Set the maximum number of target hardware watchpoints.
Specify a negative limit for unlimited.
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

That is broken in head and 7.6 branch.

$ ./gdb -q -nx -ex "set remote hardware-watchpoint-limit -1"
integer 4294967295 out of range

It works with 7.5.1, so a recent regression.

Needs to be fixed before 7.6 is out.
Comment 1 Pedro Alves 2013-03-20 15:38:14 UTC
git bisect says:

23c77880a5ba598190f48054d867575c4d0540e8 is the first bad commit
commit 23c77880a5ba598190f48054d867575c4d0540e8
Author: qiyao <qiyao>
Date:   Tue Jul 24 12:49:18 2012 +0000

    gdb/
        * cli/cli-setshow.c (do_setshow_command): Handle case 'var_uinteger'
        and 'var_zuninteger' together.  Handle case 'var_integer' and
        'var_zinteger' together.
Comment 2 Sourceware Commits 2013-03-20 18:58:17 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	palves@sourceware.org	2013-03-20 18:58:16

Modified files:
	gdb            : ChangeLog 
	gdb/cli        : cli-setshow.c 
	gdb/testsuite  : ChangeLog 
	gdb/testsuite/gdb.base: remote.exp 

Log message:
	Fix PR gdb/15289 - "set remote hardware-watchpoint-limit" broken (zinteger commands)
	
	This is a regression from 7.5, introduced/exposed by:
	http://sourceware.org/ml/gdb-patches/2012-07/msg00259.html
	
	There are a series of issues with this code.
	
	It does:
	
	unsigned int val = parse_and_eval_long (arg);
	^^^^^^^^^^^^
	
	(unsigned, usually 32-bit) while parse_and_eval_long returns a LONGEST
	(usually 64-bit), so we lose precision without noticing:
	
	(gdb) set remote hardware-watchpoint-limit 0x100000000
	(gdb) show remote hardware-watchpoint-limit 0x100000000
	The maximum number of target hardware watchpoints is 0.
	
	While at it, print the invalid number with plongest, so the user sees
	what GDB thought the number was:
	
	(gdb) set remote hardware-watchpoint-limit 0x100000000
	integer 4294967296 out of range
	
	So with "set remote hardware-watchpoint-limit -1", val ends converted
	to 0xffffffff, which then fails the
	
	else if (val >= INT_MAX)
	error (_("integer %u out of range"), val);
	
	test.
	
	Looking at that INT_MAX check, we forbid INT_MAX itself, but we
	shouldn't, as that does fit in 'int' -- we want to forbid values
	_greater_ than INT_MAX (and less than INT_MIN, while at it):
	
	(gdb) set remote hardware-watchpoint-limit 2147483647
	integer 2147483647 out of range
	
	The same problem is in the new var_zuinteger_unlimited code, which
	also uses "int" for variable.
	
	Also, when printing a 'signed int', we should use %d, not %u.
	
	This adds a couple regression tests.  Not completely thorough in checking
	all kinds of invalid input; I'm saving more exaustive testing around
	zXXinteger commands for something like new test-assisting commands
	like "maint test cmd-zinteger -1", where testing would focus on the
	command types, and thus be independent of particular user commands of
	particular GDB features.
	
	Tested on x86_64 Fedora 17.
	
	gdb/
	2013-03-20  Pedro Alves  <palves@redhat.com>
	
	PR gdb/15289
	
	* cli/cli-setshow.c (do_set_command)
	<var_uinteger, var_zuinteger>: Use LONGEST for variable holding
	the result of parsing the command argument.  Throw error if the
	value is greater than UINT_MAX.  Print the invalid value with
	plongest.
	<var_integer, var_zinteger>: Use LONGEST for variable holding the
	result of parsing the command argument.  Throw error if the value
	is greater than INT_MAX, not greater or equal.  Also throw error
	if the value is less than INT_MIN.  Print the invalid value with
	plongest.
	<var_zuinteger_unlimited>: Throw error if the value is greater
	than INT_MAX, not greater or equal.
	(do_show_command) <var_integer, var_zinteger,
	var_zuinteger_unlimited>: Use %d for printing int, not %u.
	
	gdb/testsuite/
	2013-03-20  Pedro Alves  <palves@redhat.com>
	
	PR gdb/15289
	
	* gdb.base/remote.exp: Test
	"set remote hardware-watchpoint-limit -1",
	"set remote hardware-breakpoint-limit -1",
	"set remote hardware-watchpoint-limit 2147483647" and
	"set remote hardware-breakpoint-limit 2147483647".

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.15289&r2=1.15290
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/cli/cli-setshow.c.diff?cvsroot=src&r1=1.55&r2=1.56
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.3590&r2=1.3591
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/remote.exp.diff?cvsroot=src&r1=1.22&r2=1.23
Comment 3 Sourceware Commits 2013-03-20 19:19:35 UTC
CVSROOT:	/cvs/src
Module name:	src
Branch: 	gdb_7_6-branch
Changes by:	palves@sourceware.org	2013-03-20 19:19:33

Modified files:
	gdb            : ChangeLog 
	gdb/cli        : cli-setshow.c 
	gdb/testsuite  : ChangeLog 
	gdb/testsuite/gdb.base: remote.exp 

Log message:
	Fix PR gdb/15289 - "set remote hardware-watchpoint-limit" broken (zinteger commands)
	
	This is a regression from 7.5, introduced/exposed by:
	http://sourceware.org/ml/gdb-patches/2012-07/msg00259.html
	
	There are a series of issues with this code.
	
	It does:
	
	unsigned int val = parse_and_eval_long (arg);
	^^^^^^^^^^^^
	
	(unsigned, usually 32-bit) while parse_and_eval_long returns a LONGEST
	(usually 64-bit), so we lose precision without noticing:
	
	(gdb) set remote hardware-watchpoint-limit 0x100000000
	(gdb) show remote hardware-watchpoint-limit 0x100000000
	The maximum number of target hardware watchpoints is 0.
	
	While at it, print the invalid number with plongest, so the user sees
	what GDB thought the number was:
	
	(gdb) set remote hardware-watchpoint-limit 0x100000000
	integer 4294967296 out of range
	
	So with "set remote hardware-watchpoint-limit -1", val ends converted
	to 0xffffffff, which then fails the
	
	else if (val >= INT_MAX)
	error (_("integer %u out of range"), val);
	
	test.
	
	Looking at that INT_MAX check, we forbid INT_MAX itself, but we
	shouldn't, as that does fit in 'int' -- we want to forbid values
	_greater_ than INT_MAX (and less than INT_MIN, while at it):
	
	(gdb) set remote hardware-watchpoint-limit 2147483647
	integer 2147483647 out of range
	
	The same problem is in the new var_zuinteger_unlimited code, which
	also uses "int" for variable.
	
	Also, when printing a 'signed int', we should use %d, not %u.
	
	This adds a couple regression tests.  Not completely thorough in checking
	all kinds of invalid input; I'm saving more exaustive testing around
	zXXinteger commands for something like new test-assisting commands
	like "maint test cmd-zinteger -1", where testing would focus on the
	command types, and thus be independent of particular user commands of
	particular GDB features.
	
	Tested on x86_64 Fedora 17.
	
	gdb/
	2013-03-20  Pedro Alves  <palves@redhat.com>
	
	PR gdb/15289
	
	* cli/cli-setshow.c (do_set_command)
	<var_uinteger, var_zuinteger>: Use LONGEST for variable holding
	the result of parsing the command argument.  Throw error if the
	value is greater than UINT_MAX.  Print the invalid value with
	plongest.
	<var_integer, var_zinteger>: Use LONGEST for variable holding the
	result of parsing the command argument.  Throw error if the value
	is greater than INT_MAX, not greater or equal.  Also throw error
	if the value is less than INT_MIN.  Print the invalid value with
	plongest.
	<var_zuinteger_unlimited>: Throw error if the value is greater
	than INT_MAX, not greater or equal.
	(do_show_command) <var_integer, var_zinteger,
	var_zuinteger_unlimited>: Use %d for printing int, not %u.
	
	gdb/testsuite/
	2013-03-20  Pedro Alves  <palves@redhat.com>
	
	PR gdb/15289
	
	* gdb.base/remote.exp: Test
	"set remote hardware-watchpoint-limit -1",
	"set remote hardware-breakpoint-limit -1",
	"set remote hardware-watchpoint-limit 2147483647" and
	"set remote hardware-breakpoint-limit 2147483647".

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&only_with_tag=gdb_7_6-branch&r1=1.15260.2.8&r2=1.15260.2.9
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/cli/cli-setshow.c.diff?cvsroot=src&only_with_tag=gdb_7_6-branch&r1=1.55&r2=1.55.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&only_with_tag=gdb_7_6-branch&r1=1.3580.2.2&r2=1.3580.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/remote.exp.diff?cvsroot=src&only_with_tag=gdb_7_6-branch&r1=1.22&r2=1.22.2.1
Comment 4 Pedro Alves 2013-03-20 19:25:12 UTC
Patch checked in to mainline and 7.6.