mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-01 18:32:32 +08:00
gdb/
* infcall.c (call_function_by_hand): Move BP_ADDR comment to AT_ENTRY_POINT. (call_function_by_hand) <ON_STACK>: Call write_memory with gdbarch_breakpoint_from_pc, if possible. (call_function_by_hand) <AT_ENTRY_POINT>: The BP_ADDR comment is moved here. gdb/testsuite/ * gdb.base/valgrind-infcall.c: New file. * gdb.base/valgrind-infcall.exp: New file.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2012-07-31 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
* infcall.c (call_function_by_hand): Move BP_ADDR comment to
|
||||||
|
AT_ENTRY_POINT.
|
||||||
|
(call_function_by_hand) <ON_STACK>: Call write_memory with
|
||||||
|
gdbarch_breakpoint_from_pc, if possible.
|
||||||
|
(call_function_by_hand) <AT_ENTRY_POINT>: The BP_ADDR comment is moved
|
||||||
|
here.
|
||||||
|
|
||||||
2012-07-31 Yao Qi <yao@codesourcery.com>
|
2012-07-31 Yao Qi <yao@codesourcery.com>
|
||||||
|
|
||||||
* tracepoint.c: Add 'static' for some variables.
|
* tracepoint.c: Add 'static' for some variables.
|
||||||
|
@ -618,15 +618,38 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
|
|||||||
not just the breakpoint but also an extra word containing the
|
not just the breakpoint but also an extra word containing the
|
||||||
size (?) of the structure being passed. */
|
size (?) of the structure being passed. */
|
||||||
|
|
||||||
/* The actual breakpoint (at BP_ADDR) is inserted separatly so there
|
|
||||||
is no need to write that out. */
|
|
||||||
|
|
||||||
switch (gdbarch_call_dummy_location (gdbarch))
|
switch (gdbarch_call_dummy_location (gdbarch))
|
||||||
{
|
{
|
||||||
case ON_STACK:
|
case ON_STACK:
|
||||||
sp = push_dummy_code (gdbarch, sp, funaddr,
|
{
|
||||||
args, nargs, target_values_type,
|
const gdb_byte *bp_bytes;
|
||||||
&real_pc, &bp_addr, get_current_regcache ());
|
CORE_ADDR bp_addr_as_address;
|
||||||
|
int bp_size;
|
||||||
|
|
||||||
|
/* Be careful BP_ADDR is in inferior PC encoding while
|
||||||
|
BP_ADDR_AS_ADDRESS is a plain memory address. */
|
||||||
|
|
||||||
|
sp = push_dummy_code (gdbarch, sp, funaddr, args, nargs,
|
||||||
|
target_values_type, &real_pc, &bp_addr,
|
||||||
|
get_current_regcache ());
|
||||||
|
|
||||||
|
/* Write a legitimate instruction at the point where the infcall
|
||||||
|
breakpoint is going to be inserted. While this instruction
|
||||||
|
is never going to be executed, a user investigating the
|
||||||
|
memory from GDB would see this instruction instead of random
|
||||||
|
uninitialized bytes. We chose the breakpoint instruction
|
||||||
|
as it may look as the most logical one to the user and also
|
||||||
|
valgrind 3.7.0 needs it for proper vgdb inferior calls.
|
||||||
|
|
||||||
|
If software breakpoints are unsupported for this target we
|
||||||
|
leave the user visible memory content uninitialized. */
|
||||||
|
|
||||||
|
bp_addr_as_address = bp_addr;
|
||||||
|
bp_bytes = gdbarch_breakpoint_from_pc (gdbarch, &bp_addr_as_address,
|
||||||
|
&bp_size);
|
||||||
|
if (bp_bytes != NULL)
|
||||||
|
write_memory (bp_addr_as_address, bp_bytes, bp_size);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case AT_ENTRY_POINT:
|
case AT_ENTRY_POINT:
|
||||||
{
|
{
|
||||||
@ -634,8 +657,12 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
|
|||||||
|
|
||||||
real_pc = funaddr;
|
real_pc = funaddr;
|
||||||
dummy_addr = entry_point_address ();
|
dummy_addr = entry_point_address ();
|
||||||
|
|
||||||
/* A call dummy always consists of just a single breakpoint, so
|
/* A call dummy always consists of just a single breakpoint, so
|
||||||
its address is the same as the address of the dummy. */
|
its address is the same as the address of the dummy.
|
||||||
|
|
||||||
|
The actual breakpoint is inserted separatly so there is no need to
|
||||||
|
write that out. */
|
||||||
bp_addr = dummy_addr;
|
bp_addr = dummy_addr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2012-07-27 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
|
* gdb.base/valgrind-infcall.c: New file.
|
||||||
|
* gdb.base/valgrind-infcall.exp: New file.
|
||||||
|
|
||||||
2012-07-30 Doug Evans <dje@google.com>
|
2012-07-30 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
* gdb.dwarf2/fission-reread.S: Use .data instead of .bss.
|
* gdb.dwarf2/fission-reread.S: Use .data instead of .bss.
|
||||||
|
40
gdb/testsuite/gdb.base/valgrind-infcall.c
Normal file
40
gdb/testsuite/gdb.base/valgrind-infcall.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2012 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/>. */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static volatile int infcall_var;
|
||||||
|
|
||||||
|
static int
|
||||||
|
gdb_test_infcall (void)
|
||||||
|
{
|
||||||
|
return ++infcall_var;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
gdb_test_infcall ();
|
||||||
|
p = malloc (1);
|
||||||
|
if (p == NULL)
|
||||||
|
return 1;
|
||||||
|
free (p);
|
||||||
|
free (p); /* double-free */
|
||||||
|
return 0;
|
||||||
|
}
|
115
gdb/testsuite/gdb.base/valgrind-infcall.exp
Normal file
115
gdb/testsuite/gdb.base/valgrind-infcall.exp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# Copyright 2012 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/>.
|
||||||
|
|
||||||
|
if [is_remote target] {
|
||||||
|
# The test always runs locally.
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
set test valgrind-infcall
|
||||||
|
set srcfile $test.c
|
||||||
|
set executable $test
|
||||||
|
set binfile ${objdir}/${subdir}/${executable}
|
||||||
|
if {[build_executable $test.exp $executable $srcfile {debug}] == -1} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
set test "spawn valgrind"
|
||||||
|
set cmd "valgrind --vgdb-error=0 $binfile"
|
||||||
|
set res [remote_spawn host $cmd];
|
||||||
|
if { $res < 0 || $res == "" } {
|
||||||
|
verbose -log "Spawning $cmd failed."
|
||||||
|
unsupported $test
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
pass $test
|
||||||
|
# Declare GDB now as running.
|
||||||
|
set gdb_spawn_id -1
|
||||||
|
|
||||||
|
# GDB started by vgdb stops already after the startup is executed, like with
|
||||||
|
# non-extended gdbserver. It is also not correct to run/attach the inferior.
|
||||||
|
set use_gdb_stub 1
|
||||||
|
|
||||||
|
set test "valgrind started"
|
||||||
|
# The trailing '.' differs for different memcheck versions.
|
||||||
|
gdb_test_multiple "" $test {
|
||||||
|
-re "Memcheck, a memory error detector\\.?\r\n" {
|
||||||
|
pass $test
|
||||||
|
}
|
||||||
|
-re "valgrind: failed to start tool 'memcheck' for platform '.*': No such file or directory" {
|
||||||
|
unsupported $test
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
-re "valgrind: wrong ELF executable class" {
|
||||||
|
unsupported $test
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
-re "command not found" {
|
||||||
|
# The spawn succeeded, but then valgrind was not found - e.g. if
|
||||||
|
# we spawned SSH to a remote system.
|
||||||
|
unsupported $test
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
-re "valgrind: Bad option '--vgdb-error=0'" {
|
||||||
|
# valgrind is not >= 3.7.0.
|
||||||
|
unsupported $test
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set test "vgdb prompt"
|
||||||
|
# The trailing '.' differs for different memcheck versions.
|
||||||
|
gdb_test_multiple "" $test {
|
||||||
|
-re " (target remote | \[^\r\n\]*/vgdb \[^\r\n\]*)\r\n" {
|
||||||
|
set vgdbcmd $expect_out(1,string)
|
||||||
|
pass $test
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Do not kill valgrind.
|
||||||
|
unset gdb_spawn_id
|
||||||
|
set board [host_info name]
|
||||||
|
unset_board_info fileid
|
||||||
|
|
||||||
|
clean_restart $executable
|
||||||
|
|
||||||
|
gdb_test "$vgdbcmd" " in _start .*" "target remote for vgdb"
|
||||||
|
|
||||||
|
gdb_test "monitor v.set gdb_output" "valgrind output will go to gdb.*"
|
||||||
|
|
||||||
|
set continue_count 1
|
||||||
|
while 1 {
|
||||||
|
set test "continue #$continue_count"
|
||||||
|
gdb_test_multiple "continue" "" {
|
||||||
|
-re "Invalid free\\(\\).*: main .*\r\n$gdb_prompt $" {
|
||||||
|
pass $test
|
||||||
|
break
|
||||||
|
}
|
||||||
|
-re "\r\n$gdb_prompt $" {
|
||||||
|
pass "$test (false warning)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set continue_count [expr $continue_count + 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
set test "p gdb_test_infcall ()"
|
||||||
|
gdb_test_multiple $test $test {
|
||||||
|
-re "unhandled instruction bytes.*\r\n$gdb_prompt $" {
|
||||||
|
fail $test
|
||||||
|
}
|
||||||
|
-re "Continuing \\.\\.\\..*\r\n\\\$1 = 2\r\n$gdb_prompt $" {
|
||||||
|
pass $test
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user