mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
101 Commits
gdb-7.7-re
...
gdb-7.7.1-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bd8fc3a13 | ||
|
|
48583b3e99 | ||
|
|
a3d7b4db0f | ||
|
|
a2ef434fa3 | ||
|
|
d49b013545 | ||
|
|
1aaa02526a | ||
|
|
9c644de58e | ||
|
|
f105c30654 | ||
|
|
12c9d71bb0 | ||
|
|
fd2d29157c | ||
|
|
a4e669de9b | ||
|
|
ca70682781 | ||
|
|
8a90a4ef6a | ||
|
|
87a1630ead | ||
|
|
60180965bc | ||
|
|
2efbb06d22 | ||
|
|
c21d327c0c | ||
|
|
4e608f2e34 | ||
|
|
230109e7ff | ||
|
|
b4a18502ba | ||
|
|
8fe73b351d | ||
|
|
41683d52d5 | ||
|
|
3dfbfcef59 | ||
|
|
24e98d1dd3 | ||
|
|
68e9e29c82 | ||
|
|
b21f3065f4 | ||
|
|
cc5d52b482 | ||
|
|
999686dbc1 | ||
|
|
7456303a04 | ||
|
|
385bdf6339 | ||
|
|
ac8c178f3c | ||
|
|
eb7e3e2de0 | ||
|
|
7b3ae47652 | ||
|
|
7cdb9e50cd | ||
|
|
a799b84bec | ||
|
|
2130bcaff7 | ||
|
|
d4a0e7b071 | ||
|
|
157b39bcf7 | ||
|
|
9f5dbd6b28 | ||
|
|
e2373c51c1 | ||
|
|
85edbe3d78 | ||
|
|
7a2b89eb22 | ||
|
|
c3db1309cf | ||
|
|
f0632b0cc5 | ||
|
|
71882adabe | ||
|
|
917084c994 | ||
|
|
0de9013b39 | ||
|
|
ca1fa2152d | ||
|
|
c6961503c0 | ||
|
|
e54718a504 | ||
|
|
5525b6a9b6 | ||
|
|
d580d76896 | ||
|
|
2b87046f7f | ||
|
|
c9b40b66ff | ||
|
|
a1f93fc6fd | ||
|
|
c782ba4621 | ||
|
|
abd81597b3 | ||
|
|
fc9ec34d8a | ||
|
|
0136e467ea | ||
|
|
e80f9a926c | ||
|
|
e7e3187f9a | ||
|
|
133152d027 | ||
|
|
444f0736e7 | ||
|
|
70e0687e90 | ||
|
|
630cfb3be8 | ||
|
|
3f5670f01b | ||
|
|
66bb3d16d4 | ||
|
|
79a33da92a | ||
|
|
489f6a8faf | ||
|
|
6136a7464c | ||
|
|
7c8dd2a40d | ||
|
|
0bbe110888 | ||
|
|
b0f2293c3d | ||
|
|
e1e2bfeaaf | ||
|
|
8fd1f4997c | ||
|
|
95bffc909f | ||
|
|
c978954597 | ||
|
|
5b91e80ee9 | ||
|
|
599c9f4265 | ||
|
|
bd3f479188 | ||
|
|
e282c38bad | ||
|
|
870c6c4dba | ||
|
|
4cd5f720b1 | ||
|
|
88024e5aa4 | ||
|
|
0c42885255 | ||
|
|
6f3d2e63a9 | ||
|
|
82b4c46a06 | ||
|
|
2f41abfbe3 | ||
|
|
5c653ddab9 | ||
|
|
ee54ba5aa1 | ||
|
|
0b6558d052 | ||
|
|
f3ce66c80c | ||
|
|
e317dab76a | ||
|
|
db269beda4 | ||
|
|
d0be77a38c | ||
|
|
e661fce02d | ||
|
|
83c94bab29 | ||
|
|
d5577c7a9c | ||
|
|
3a8074179a | ||
|
|
1d272e5ce4 | ||
|
|
684d4bcc6b |
@@ -1,3 +1,28 @@
|
||||
2014-04-24 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
2014-01-29 Nick Clifton <nickc@redhat.com>
|
||||
PR build/16873
|
||||
* bfd-in.h (bfd_set_section_vma): Delete.
|
||||
(bfd_set_section_alignment): Delete.
|
||||
(bfd_set_section_userdata): Delete.
|
||||
(bfd_set_cacheable): Delete.
|
||||
* bfd.c (bfd_set_cacheable): New static inline function.
|
||||
* section.c (bfd_set_section_userdata): Likewise.
|
||||
(bfd_set_section_vma): Likewise.
|
||||
(bfd_set_section_alignment): Likewise.
|
||||
* bfd-in2.h: Regenerate.
|
||||
|
||||
2014-03-12 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/16696
|
||||
* rs6000-core.c (rs6000coff_core_p): Cast pointers to bfd_vma
|
||||
through ptr_to_uint instead of through long.
|
||||
|
||||
2014-02-17 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR build/16550
|
||||
* cache.c (bfd_cache_max_open): Cast RLIM_INFINITY to rlim_t.
|
||||
|
||||
2014-01-07 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* elf32-xtensa.c (vsprint_msg): Don't use old VA_* compatibility
|
||||
|
||||
@@ -292,9 +292,6 @@ typedef struct bfd_section *sec_ptr;
|
||||
|
||||
#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
|
||||
|
||||
#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE)
|
||||
#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE)
|
||||
#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
|
||||
/* Find the address one past the end of SEC. */
|
||||
#define bfd_get_section_limit(bfd, sec) \
|
||||
(((bfd)->direction != write_direction && (sec)->rawsize != 0 \
|
||||
@@ -517,8 +514,6 @@ extern void warn_deprecated (const char *, const char *, int, const char *);
|
||||
|
||||
#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
|
||||
|
||||
#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
|
||||
|
||||
extern bfd_boolean bfd_cache_close
|
||||
(bfd *abfd);
|
||||
/* NB: This declaration should match the autogenerated one in libbfd.h. */
|
||||
|
||||
@@ -299,9 +299,6 @@ typedef struct bfd_section *sec_ptr;
|
||||
|
||||
#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
|
||||
|
||||
#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE)
|
||||
#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE)
|
||||
#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
|
||||
/* Find the address one past the end of SEC. */
|
||||
#define bfd_get_section_limit(bfd, sec) \
|
||||
(((bfd)->direction != write_direction && (sec)->rawsize != 0 \
|
||||
@@ -524,8 +521,6 @@ extern void warn_deprecated (const char *, const char *, int, const char *);
|
||||
|
||||
#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
|
||||
|
||||
#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
|
||||
|
||||
extern bfd_boolean bfd_cache_close
|
||||
(bfd *abfd);
|
||||
/* NB: This declaration should match the autogenerated one in libbfd.h. */
|
||||
@@ -1029,7 +1024,7 @@ bfd *bfd_openr (const char *filename, const char *target);
|
||||
|
||||
bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
|
||||
|
||||
bfd *bfd_openstreamr (const char *, const char *, void *);
|
||||
bfd *bfd_openstreamr (const char * filename, const char * target, void * stream);
|
||||
|
||||
bfd *bfd_openr_iovec (const char *filename, const char *target,
|
||||
void *(*open_func) (struct bfd *nbfd,
|
||||
@@ -1596,6 +1591,32 @@ struct relax_table {
|
||||
int size;
|
||||
};
|
||||
|
||||
/* Note: the following are provided as inline functions rather than macros
|
||||
because not all callers use the return value. A macro implementation
|
||||
would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
|
||||
compilers will complain about comma expressions that have no effect. */
|
||||
static inline bfd_boolean
|
||||
bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
|
||||
{
|
||||
ptr->userdata = val;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline bfd_boolean
|
||||
bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
|
||||
{
|
||||
ptr->vma = ptr->lma = val;
|
||||
ptr->user_set_vma = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline bfd_boolean
|
||||
bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
|
||||
{
|
||||
ptr->alignment_power = val;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* These sections are global, and are managed by BFD. The application
|
||||
and target back end are not permitted to change the values in
|
||||
these sections. */
|
||||
@@ -6415,6 +6436,14 @@ struct bfd
|
||||
unsigned int selective_search : 1;
|
||||
};
|
||||
|
||||
/* See note beside bfd_set_section_userdata. */
|
||||
static inline bfd_boolean
|
||||
bfd_set_cacheable (bfd * abfd, bfd_boolean val)
|
||||
{
|
||||
abfd->cacheable = val;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef enum bfd_error
|
||||
{
|
||||
bfd_error_no_error = 0,
|
||||
|
||||
@@ -311,6 +311,14 @@ CODE_FRAGMENT
|
||||
. unsigned int selective_search : 1;
|
||||
.};
|
||||
.
|
||||
.{* See note beside bfd_set_section_userdata. *}
|
||||
.static inline bfd_boolean
|
||||
.bfd_set_cacheable (bfd * abfd, bfd_boolean val)
|
||||
.{
|
||||
. abfd->cacheable = val;
|
||||
. return TRUE;
|
||||
.}
|
||||
.
|
||||
*/
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
@@ -82,7 +82,7 @@ bfd_cache_max_open (void)
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
struct rlimit rlim;
|
||||
if (getrlimit (RLIMIT_NOFILE, &rlim) == 0
|
||||
&& rlim.rlim_cur != RLIM_INFINITY)
|
||||
&& rlim.rlim_cur != (rlim_t) RLIM_INFINITY)
|
||||
max = rlim.rlim_cur / 8;
|
||||
else
|
||||
#endif /* HAVE_GETRLIMIT */
|
||||
|
||||
@@ -585,7 +585,7 @@ rs6000coff_core_p (bfd *abfd)
|
||||
{
|
||||
ldi_core = ldinfo.l32.ldinfo_core;
|
||||
ldi_datasize = ldinfo.l32.ldinfo_datasize;
|
||||
ldi_dataorg = (bfd_vma) (long) ldinfo.l32.ldinfo_dataorg;
|
||||
ldi_dataorg = (bfd_vma) (ptr_to_uint) ldinfo.l32.ldinfo_dataorg;
|
||||
ldi_next = ldinfo.l32.ldinfo_next;
|
||||
}
|
||||
|
||||
@@ -627,7 +627,7 @@ rs6000coff_core_p (bfd *abfd)
|
||||
}
|
||||
else
|
||||
{
|
||||
vminfo_addr = (bfd_vma) (long) vminfo.old.vminfo_addr;
|
||||
vminfo_addr = (bfd_vma) (ptr_to_uint) vminfo.old.vminfo_addr;
|
||||
vminfo_size = vminfo.old.vminfo_size;
|
||||
vminfo_offset = vminfo.old.vminfo_offset;
|
||||
}
|
||||
|
||||
@@ -542,6 +542,32 @@ CODE_FRAGMENT
|
||||
. int size;
|
||||
.};
|
||||
.
|
||||
.{* Note: the following are provided as inline functions rather than macros
|
||||
. because not all callers use the return value. A macro implementation
|
||||
. would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
|
||||
. compilers will complain about comma expressions that have no effect. *}
|
||||
.static inline bfd_boolean
|
||||
.bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
|
||||
.{
|
||||
. ptr->userdata = val;
|
||||
. return TRUE;
|
||||
.}
|
||||
.
|
||||
.static inline bfd_boolean
|
||||
.bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
|
||||
.{
|
||||
. ptr->vma = ptr->lma = val;
|
||||
. ptr->user_set_vma = TRUE;
|
||||
. return TRUE;
|
||||
.}
|
||||
.
|
||||
.static inline bfd_boolean
|
||||
.bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
|
||||
.{
|
||||
. ptr->alignment_power = val;
|
||||
. return TRUE;
|
||||
.}
|
||||
.
|
||||
.{* These sections are global, and are managed by BFD. The application
|
||||
. and target back end are not permitted to change the values in
|
||||
. these sections. *}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define BFD_VERSION_DATE 20140206
|
||||
#define BFD_VERSION_DATE 20140505
|
||||
#define BFD_VERSION @bfd_version@
|
||||
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
|
||||
#define REPORT_BUGS_TO @report_bugs_to@
|
||||
|
||||
@@ -1,3 +1,80 @@
|
||||
2014-05-05 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.7.1.
|
||||
|
||||
2014-04-19 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
PR gdb/14018
|
||||
* windows-nat.c (thread_rec): Don't display a warning when
|
||||
SuspendThread fails with ERROR_ACCESS_DENIED. If SuspendThread
|
||||
fails for any reason, set th->suspended to -1, so that we don't
|
||||
try to resume such a thread. Also, don't return NULL in these
|
||||
cases, to avoid completely ruin the session due to "PC register is
|
||||
not available" error.
|
||||
(do_windows_fetch_inferior_registers): Check errors in
|
||||
GetThreadContext call.
|
||||
(windows_continue): Accept an additional argument KILLED; if not
|
||||
zero, ignore errors in the SetThreadContext call, since the
|
||||
inferior was killed and is shutting down.
|
||||
(windows_resume, get_windows_debug_event)
|
||||
(windows_create_inferior, windows_mourn_inferior)
|
||||
(windows_kill_inferior): All callers of windows_continue changed
|
||||
to adjust to its new calling sequence.
|
||||
|
||||
2014-04-11 Pierre Langlois <pierre.langlois@embecosm.com>
|
||||
|
||||
PR backtrace/16721
|
||||
PR backtrace/16832
|
||||
* avr-tdep.c (struct gdbarch_tdep): Mention avrxmega in the comment.
|
||||
(avr_gdbarch_init): Add xmega architectures given by bfd_architecture
|
||||
when setting the size of call_length.
|
||||
(avr_scan_prologue): Accept push r1 instruction for small stack
|
||||
allocation.
|
||||
* MAINTAINERS (Write After Approval): Add "Pierre Langlois".
|
||||
|
||||
2014-03-05 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/16575
|
||||
* dcache.c (dcache_poke_byte): Constify ptr parameter. Return
|
||||
void. Update comment.
|
||||
(dcache_xfer_memory): Delete.
|
||||
(dcache_read_memory_partial): New, based on the read bits of
|
||||
dcache_xfer_memory.
|
||||
(dcache_update): Add status parameter. Use ULONGEST for len, and
|
||||
adjust. Discard cache lines if the reason for the update was
|
||||
error.
|
||||
* dcache.h (dcache_xfer_memory): Delete declaration.
|
||||
(dcache_read_memory_partial): New declaration.
|
||||
(dcache_update): Update prototype.
|
||||
* target.c (raw_memory_xfer_partial): Update the dcache here.
|
||||
(memory_xfer_partial_1): Don't handle dcache writes here.
|
||||
|
||||
2014-02-26 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR breakpoints/16292
|
||||
* infrun.c (handle_signal_stop) <signal arrives while stepping
|
||||
over a breakpoint>: Switch back to the stepping thread.
|
||||
|
||||
2014-02-25 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
PR gdb/16626
|
||||
* auto-load.c (auto_load_objfile_script_1): Change filename to
|
||||
debugfile.
|
||||
|
||||
2014-02-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Fix Python stack corruption.
|
||||
* python/py-linetable.c (ltpy_get_pcs_for_line, ltpy_has_line): Use
|
||||
gdb_py_longest.
|
||||
|
||||
2014-02-06 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.7.0.DATE-cvs.
|
||||
|
||||
2014-02-06 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 7.7 released.
|
||||
|
||||
2014-02-06 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.7.
|
||||
|
||||
@@ -546,6 +546,7 @@ Jim Kingdon kingdon@panix.com
|
||||
Paul Koning paul_koning@dell.com
|
||||
Jan Kratochvil jan.kratochvil@redhat.com
|
||||
Maxim Kuvyrkov maxim@kugelworks.com
|
||||
Pierre Langlois pierre.langlois@embecosm.com
|
||||
Jonathan Larmour jifl@ecoscentric.com
|
||||
Jeff Law law@redhat.com
|
||||
Justin Lebar justin.lebar@gmail.com
|
||||
|
||||
@@ -791,17 +791,17 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
|
||||
make_cleanup_fclose (input);
|
||||
|
||||
is_safe
|
||||
= file_is_auto_load_safe (filename,
|
||||
= file_is_auto_load_safe (debugfile,
|
||||
_("auto-load: Loading %s script \"%s\""
|
||||
" by extension for objfile \"%s\".\n"),
|
||||
language->name, filename,
|
||||
language->name, debugfile,
|
||||
objfile_name (objfile));
|
||||
|
||||
/* Add this script to the hash table too so
|
||||
"info auto-load ${lang}-scripts" can print it. */
|
||||
pspace_info
|
||||
= get_auto_load_pspace_data_for_loading (current_program_space);
|
||||
maybe_add_script (pspace_info, is_safe, filename, filename, language);
|
||||
maybe_add_script (pspace_info, is_safe, debugfile, debugfile, language);
|
||||
|
||||
/* To preserve existing behaviour we don't check for whether the
|
||||
script was already in the table, and always load it.
|
||||
|
||||
@@ -179,7 +179,7 @@ struct avr_unwind_cache
|
||||
struct gdbarch_tdep
|
||||
{
|
||||
/* Number of bytes stored to the stack by call instructions.
|
||||
2 bytes for avr1-5, 3 bytes for avr6. */
|
||||
2 bytes for avr1-5 and avrxmega1-5, 3 bytes for avr6 and avrxmega6-7. */
|
||||
int call_length;
|
||||
|
||||
/* Type for void. */
|
||||
@@ -719,7 +719,7 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
|
||||
info->size += gdbarch_tdep (gdbarch)->call_length;
|
||||
vpc += 2;
|
||||
}
|
||||
else if (insn == 0x920f) /* push r0 */
|
||||
else if (insn == 0x920f || insn == 0x921f) /* push r0 or push r1 */
|
||||
{
|
||||
info->size += 1;
|
||||
vpc += 2;
|
||||
@@ -1355,14 +1355,21 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
switch (info.bfd_arch_info->mach)
|
||||
{
|
||||
case bfd_mach_avr1:
|
||||
case bfd_mach_avrxmega1:
|
||||
case bfd_mach_avr2:
|
||||
case bfd_mach_avrxmega2:
|
||||
case bfd_mach_avr3:
|
||||
case bfd_mach_avrxmega3:
|
||||
case bfd_mach_avr4:
|
||||
case bfd_mach_avrxmega4:
|
||||
case bfd_mach_avr5:
|
||||
case bfd_mach_avrxmega5:
|
||||
default:
|
||||
call_length = 2;
|
||||
break;
|
||||
case bfd_mach_avr6:
|
||||
case bfd_mach_avrxmega6:
|
||||
case bfd_mach_avrxmega7:
|
||||
call_length = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
88
gdb/dcache.c
88
gdb/dcache.c
@@ -413,24 +413,20 @@ dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr)
|
||||
|
||||
/* Write the byte at PTR into ADDR in the data cache.
|
||||
|
||||
The caller is responsible for also promptly writing the data
|
||||
through to target memory.
|
||||
The caller should have written the data through to target memory
|
||||
already.
|
||||
|
||||
If addr is not in cache, this function does nothing; writing to
|
||||
an area of memory which wasn't present in the cache doesn't cause
|
||||
it to be loaded in.
|
||||
If ADDR is not in cache, this function does nothing; writing to an
|
||||
area of memory which wasn't present in the cache doesn't cause it
|
||||
to be loaded in. */
|
||||
|
||||
Always return 1 (meaning success) to simplify dcache_xfer_memory. */
|
||||
|
||||
static int
|
||||
dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr)
|
||||
static void
|
||||
dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, const gdb_byte *ptr)
|
||||
{
|
||||
struct dcache_block *db = dcache_hit (dcache, addr);
|
||||
|
||||
if (db)
|
||||
db->data[XFORM (dcache, addr)] = *ptr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -467,26 +463,16 @@ dcache_init (void)
|
||||
}
|
||||
|
||||
|
||||
/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
|
||||
to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
|
||||
nonzero.
|
||||
|
||||
Return the number of bytes actually transfered, or -1 if the
|
||||
transfer is not supported or otherwise fails. Return of a non-negative
|
||||
value less than LEN indicates that no further transfer is possible.
|
||||
NOTE: This is different than the to_xfer_partial interface, in which
|
||||
positive values less than LEN mean further transfers may be possible. */
|
||||
/* Read LEN bytes from dcache memory at MEMADDR, transferring to
|
||||
debugger address MYADDR. If the data is presently cached, this
|
||||
fills the cache. Arguments/return are like the target_xfer_partial
|
||||
interface. */
|
||||
|
||||
int
|
||||
dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache,
|
||||
CORE_ADDR memaddr, gdb_byte *myaddr,
|
||||
int len, int should_write)
|
||||
dcache_read_memory_partial (struct target_ops *ops, DCACHE *dcache,
|
||||
CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len)
|
||||
{
|
||||
int i;
|
||||
int res;
|
||||
int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr);
|
||||
|
||||
xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
|
||||
ULONGEST i;
|
||||
|
||||
/* If this is a different inferior from what we've recorded,
|
||||
flush the cache. */
|
||||
@@ -497,35 +483,18 @@ dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache,
|
||||
dcache->ptid = inferior_ptid;
|
||||
}
|
||||
|
||||
/* Do write-through first, so that if it fails, we don't write to
|
||||
the cache at all. */
|
||||
|
||||
if (should_write)
|
||||
{
|
||||
res = target_write (ops, TARGET_OBJECT_RAW_MEMORY,
|
||||
NULL, myaddr, memaddr, len);
|
||||
if (res <= 0)
|
||||
return res;
|
||||
/* Update LEN to what was actually written. */
|
||||
len = res;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (!xfunc (dcache, memaddr + i, myaddr + i))
|
||||
if (!dcache_peek_byte (dcache, memaddr + i, myaddr + i))
|
||||
{
|
||||
/* That failed. Discard its cache line so we don't have a
|
||||
partially read line. */
|
||||
dcache_invalidate_line (dcache, memaddr + i);
|
||||
/* If we're writing, we still wrote LEN bytes. */
|
||||
if (should_write)
|
||||
return len;
|
||||
else
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
return i == 0 ? -1 : i;
|
||||
}
|
||||
|
||||
/* FIXME: There would be some benefit to making the cache write-back and
|
||||
@@ -537,17 +506,26 @@ dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache,
|
||||
"logically" connected but not actually a single call to one of the
|
||||
memory transfer functions. */
|
||||
|
||||
/* Just update any cache lines which are already present. This is called
|
||||
by memory_xfer_partial in cases where the access would otherwise not go
|
||||
through the cache. */
|
||||
/* Just update any cache lines which are already present. This is
|
||||
called by the target_xfer_partial machinery when writing raw
|
||||
memory. */
|
||||
|
||||
void
|
||||
dcache_update (DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr, int len)
|
||||
dcache_update (DCACHE *dcache, int status,
|
||||
CORE_ADDR memaddr, const gdb_byte *myaddr,
|
||||
ULONGEST len)
|
||||
{
|
||||
int i;
|
||||
ULONGEST i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dcache_poke_byte (dcache, memaddr + i, myaddr + i);
|
||||
if (status > 0)
|
||||
dcache_poke_byte (dcache, memaddr + i, myaddr + i);
|
||||
else
|
||||
{
|
||||
/* Discard the whole cache line so we don't have a partially
|
||||
valid line. */
|
||||
dcache_invalidate_line (dcache, memaddr + i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print DCACHE line INDEX. */
|
||||
|
||||
12
gdb/dcache.h
12
gdb/dcache.h
@@ -32,12 +32,12 @@ DCACHE *dcache_init (void);
|
||||
/* Free a DCACHE. */
|
||||
void dcache_free (DCACHE *);
|
||||
|
||||
/* Simple to call from <remote>_xfer_memory. */
|
||||
int dcache_read_memory_partial (struct target_ops *ops, DCACHE *dcache,
|
||||
CORE_ADDR memaddr, gdb_byte *myaddr,
|
||||
ULONGEST len);
|
||||
|
||||
int dcache_xfer_memory (struct target_ops *ops, DCACHE *cache, CORE_ADDR mem,
|
||||
gdb_byte *my, int len, int should_write);
|
||||
|
||||
void dcache_update (DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr,
|
||||
int len);
|
||||
void dcache_update (DCACHE *dcache, int status,
|
||||
CORE_ADDR memaddr, const gdb_byte *myaddr,
|
||||
ULONGEST len);
|
||||
|
||||
#endif /* DCACHE_H */
|
||||
|
||||
@@ -4379,7 +4379,11 @@ handle_signal_stop (struct execution_control_state *ecs)
|
||||
ecs->event_thread->step_after_step_resume_breakpoint = 1;
|
||||
/* Reset trap_expected to ensure breakpoints are re-inserted. */
|
||||
ecs->event_thread->control.trap_expected = 0;
|
||||
keep_going (ecs);
|
||||
|
||||
/* If we were nexting/stepping some other thread, switch to
|
||||
it, so that we don't continue it, losing control. */
|
||||
if (!switch_back_to_stepped_thread (ecs))
|
||||
keep_going (ecs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ static PyObject *
|
||||
ltpy_get_pcs_for_line (PyObject *self, PyObject *args)
|
||||
{
|
||||
struct symtab *symtab;
|
||||
int py_line;
|
||||
gdb_py_longest py_line;
|
||||
struct linetable_entry *best_entry = NULL;
|
||||
linetable_entry_object *result;
|
||||
VEC (CORE_ADDR) *pcs = NULL;
|
||||
@@ -200,7 +200,7 @@ static PyObject *
|
||||
ltpy_has_line (PyObject *self, PyObject *args)
|
||||
{
|
||||
struct symtab *symtab;
|
||||
int py_line;
|
||||
gdb_py_longest py_line;
|
||||
int index;
|
||||
|
||||
LTPY_REQUIRE_VALID (self, symtab);
|
||||
|
||||
49
gdb/target.c
49
gdb/target.c
@@ -1418,6 +1418,23 @@ raw_memory_xfer_partial (struct target_ops *ops, void *readbuf,
|
||||
}
|
||||
while (ops != NULL);
|
||||
|
||||
/* The cache works at the raw memory level. Make sure the cache
|
||||
gets updated with raw contents no matter what kind of memory
|
||||
object was originally being written. Note we do write-through
|
||||
first, so that if it fails, we don't write to the cache contents
|
||||
that never made it to the target. */
|
||||
if (writebuf != NULL
|
||||
&& !ptid_equal (inferior_ptid, null_ptid)
|
||||
&& target_dcache_init_p ()
|
||||
&& (stack_cache_enabled_p () || code_cache_enabled_p ()))
|
||||
{
|
||||
DCACHE *dcache = target_dcache_get ();
|
||||
|
||||
/* Note that writing to an area of memory which wasn't present
|
||||
in the cache doesn't cause it to be loaded in. */
|
||||
dcache_update (dcache, res, memaddr, writebuf, len);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1565,6 +1582,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
|
||||
inf = NULL;
|
||||
|
||||
if (inf != NULL
|
||||
&& readbuf != NULL
|
||||
/* The dcache reads whole cache lines; that doesn't play well
|
||||
with reading from a trace buffer, because reading outside of
|
||||
the collected memory range fails. */
|
||||
@@ -1575,18 +1593,8 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
|
||||
{
|
||||
DCACHE *dcache = target_dcache_get_or_init ();
|
||||
|
||||
if (readbuf != NULL)
|
||||
res = dcache_xfer_memory (ops, dcache, memaddr, readbuf, reg_len, 0);
|
||||
else
|
||||
/* FIXME drow/2006-08-09: If we're going to preserve const
|
||||
correctness dcache_xfer_memory should take readbuf and
|
||||
writebuf. */
|
||||
res = dcache_xfer_memory (ops, dcache, memaddr, (void *) writebuf,
|
||||
reg_len, 1);
|
||||
if (res <= 0)
|
||||
return -1;
|
||||
else
|
||||
return res;
|
||||
return dcache_read_memory_partial (ops, dcache, memaddr, readbuf,
|
||||
reg_len);
|
||||
}
|
||||
|
||||
/* If none of those methods found the memory we wanted, fall back
|
||||
@@ -1597,23 +1605,6 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
|
||||
object which can be read from more than one valid target. */
|
||||
res = raw_memory_xfer_partial (ops, readbuf, writebuf, memaddr, reg_len);
|
||||
|
||||
/* Make sure the cache gets updated no matter what - if we are writing
|
||||
to the stack. Even if this write is not tagged as such, we still need
|
||||
to update the cache. */
|
||||
|
||||
if (res > 0
|
||||
&& inf != NULL
|
||||
&& writebuf != NULL
|
||||
&& target_dcache_init_p ()
|
||||
&& !region->attrib.cache
|
||||
&& ((stack_cache_enabled_p () && object != TARGET_OBJECT_STACK_MEMORY)
|
||||
|| (code_cache_enabled_p () && object != TARGET_OBJECT_CODE_MEMORY)))
|
||||
{
|
||||
DCACHE *dcache = target_dcache_get ();
|
||||
|
||||
dcache_update (dcache, memaddr, (void *) writebuf, res);
|
||||
}
|
||||
|
||||
/* If we still haven't got anything, return the last error. We
|
||||
give up. */
|
||||
return res;
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
2014-03-05 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/16575
|
||||
* gdb.base/breakpoint-shadow.exp (compare_disassembly): New
|
||||
procedure.
|
||||
(top level): Adjust to use it. Add tests that exercise breakpoint
|
||||
interaction with the code-cache.
|
||||
|
||||
2014-02-26 Pedro Alves <pedro@codesourcery.com>
|
||||
Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR breakpoints/16292
|
||||
* gdb.threads/signal-while-stepping-over-bp-other-thread.c: New
|
||||
file.
|
||||
* gdb.threads/signal-while-stepping-over-bp-other-thread.exp: New
|
||||
file.
|
||||
|
||||
2014-02-25 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
PR gdb/16626
|
||||
* gdb.base/auto-load-script: New file.
|
||||
* gdb.base/auto-load.c: New file.
|
||||
* gdb.base/auto-load.exp: New file.
|
||||
|
||||
PR gdb/16626
|
||||
* gdb.base/auto-load.exp: Fix out-of-srctree run.
|
||||
|
||||
2014-02-05 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* gdb.trace/report.exp (use_collected_data): Test the output
|
||||
|
||||
17
gdb/testsuite/gdb.base/auto-load-script
Normal file
17
gdb/testsuite/gdb.base/auto-load-script
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright 2014 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/>.
|
||||
|
||||
echo script_loaded\n
|
||||
set $script_loaded=42
|
||||
22
gdb/testsuite/gdb.base/auto-load.c
Normal file
22
gdb/testsuite/gdb.base/auto-load.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2014 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/>. */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
41
gdb/testsuite/gdb.base/auto-load.exp
Normal file
41
gdb/testsuite/gdb.base/auto-load.exp
Normal file
@@ -0,0 +1,41 @@
|
||||
# Copyright 2014 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/>.
|
||||
|
||||
standard_testfile
|
||||
|
||||
if [is_remote host] {
|
||||
return 0
|
||||
}
|
||||
|
||||
set targetdir "${binfile}.dir"
|
||||
set sourcescript "${srcdir}/${subdir}/${testfile}-script"
|
||||
set targetscriptdir "${targetdir}/[file dirname ${binfile}]"
|
||||
set targetscript "${targetscriptdir}/${testfile}-gdb.gdb"
|
||||
|
||||
remote_exec host "rm -rf ${targetdir}"
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
remote_exec host "mkdir -p ${targetscriptdir}"
|
||||
remote_exec host "cp ${sourcescript} ${targetscript}"
|
||||
|
||||
gdb_test_no_output "set auto-load scripts-directory ${targetdir}" "set auto-load scripts-directory"
|
||||
gdb_test_no_output "set auto-load safe-path ${targetscript}" "set auto-load safe-path"
|
||||
|
||||
gdb_load ${binfile}
|
||||
|
||||
gdb_test {print $script_loaded} " = 42"
|
||||
@@ -44,14 +44,36 @@ gdb_test_multiple "disass main" $test {
|
||||
gdb_test "b [gdb_get_line_number "break-first"]" "Breakpoint \[0-9\] at .*" "First breakpoint placed"
|
||||
gdb_test "b [gdb_get_line_number "break-second"]" "Breakpoint \[0-9\] at .*" "Second breakpoint placed"
|
||||
|
||||
set test "disassembly with breakpoints"
|
||||
gdb_test_multiple "disass main" $test {
|
||||
-re $match {
|
||||
set got $expect_out(1,string)
|
||||
if [string equal -nocase $orig $got] {
|
||||
pass $test
|
||||
} else {
|
||||
fail $test
|
||||
# Disassemble main, and compare the output to the original output
|
||||
# before breakpoints were inserted. TEST is used as test message.
|
||||
|
||||
proc test_disassembly {test} {
|
||||
global match orig
|
||||
|
||||
gdb_test_multiple "disass main" $test {
|
||||
-re $match {
|
||||
set got $expect_out(1,string)
|
||||
if [string equal -nocase $orig $got] {
|
||||
pass $test
|
||||
} else {
|
||||
fail $test
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_disassembly "disassembly with breakpoints"
|
||||
|
||||
# Now check the interaction between the code cache and breakpoint
|
||||
# always-inserted mode.
|
||||
|
||||
# Recreate the code cache when breakpoints are already inserted.
|
||||
gdb_test_no_output "set code-cache off"
|
||||
gdb_test_no_output "set code-cache on"
|
||||
|
||||
test_disassembly "disassembly with breakpoints, fresh code cache"
|
||||
|
||||
# Delete breakpoints. This should update the code cache as well.
|
||||
delete_breakpoints
|
||||
|
||||
test_disassembly "disassembly without breakpoints, no stale breakpoints"
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2009-2014 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 <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
unsigned int args[2];
|
||||
|
||||
pid_t pid;
|
||||
pthread_barrier_t barrier;
|
||||
pthread_t child_thread_2, child_thread_3;
|
||||
|
||||
void
|
||||
handler (int signo)
|
||||
{
|
||||
/* so that thread 3 is sure to run, in case the bug is present. */
|
||||
usleep (10);
|
||||
}
|
||||
|
||||
void
|
||||
callme (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
block_signals (void)
|
||||
{
|
||||
sigset_t mask;
|
||||
|
||||
sigfillset (&mask);
|
||||
sigprocmask (SIG_BLOCK, &mask, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
unblock_signals (void)
|
||||
{
|
||||
sigset_t mask;
|
||||
|
||||
sigfillset (&mask);
|
||||
sigprocmask (SIG_UNBLOCK, &mask, NULL);
|
||||
}
|
||||
|
||||
void *
|
||||
child_function_3 (void *arg)
|
||||
{
|
||||
int my_number = (long) arg;
|
||||
volatile int *myp = (int *) &args[my_number];
|
||||
|
||||
pthread_barrier_wait (&barrier);
|
||||
|
||||
while (*myp > 0)
|
||||
{
|
||||
(*myp) ++; /* set breakpoint child_two here */
|
||||
callme ();
|
||||
}
|
||||
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
void *
|
||||
child_function_2 (void *arg)
|
||||
{
|
||||
int my_number = (long) arg;
|
||||
volatile int *myp = (int *) &args[my_number];
|
||||
|
||||
unblock_signals ();
|
||||
|
||||
pthread_barrier_wait (&barrier);
|
||||
|
||||
while (*myp > 0)
|
||||
{
|
||||
(*myp) ++;
|
||||
callme (); /* set breakpoint child_one here */
|
||||
}
|
||||
|
||||
*myp = 1;
|
||||
while (*myp > 0)
|
||||
{
|
||||
(*myp) ++;
|
||||
callme ();
|
||||
}
|
||||
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int res;
|
||||
long i;
|
||||
|
||||
/* Block signals in all threads but one, so that we're sure which
|
||||
thread gets the signal we send from the command line. */
|
||||
block_signals ();
|
||||
|
||||
signal (SIGUSR1, handler);
|
||||
|
||||
/* Call these early so that PLTs for these are resolved soon,
|
||||
instead of in the threads. RTLD_NOW should work as well. */
|
||||
usleep (0);
|
||||
pthread_barrier_init (&barrier, NULL, 1);
|
||||
pthread_barrier_wait (&barrier);
|
||||
|
||||
pthread_barrier_init (&barrier, NULL, 2);
|
||||
|
||||
/* The test uses this global to know where to send the signal
|
||||
to. */
|
||||
pid = getpid ();
|
||||
|
||||
i = 0;
|
||||
args[i] = 1;
|
||||
res = pthread_create (&child_thread_2,
|
||||
NULL, child_function_2, (void *) i);
|
||||
pthread_barrier_wait (&barrier);
|
||||
callme (); /* set wait-thread-2 breakpoint here */
|
||||
|
||||
i = 1;
|
||||
args[i] = 1;
|
||||
res = pthread_create (&child_thread_3,
|
||||
NULL, child_function_3, (void *) i);
|
||||
pthread_barrier_wait (&barrier);
|
||||
callme (); /* set wait-thread-3 breakpoint here */
|
||||
|
||||
pthread_join (child_thread_2, NULL);
|
||||
pthread_join (child_thread_3, NULL);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
# Copyright (C) 2011-2014 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/>.
|
||||
|
||||
# Test that GDB doesn't inadvertently resume the stepped thread when a
|
||||
# signal arrives while stepping over the breakpoint that last caused a
|
||||
# stop, when the thread that hit that breakpoint is not the stepped
|
||||
# thread.
|
||||
|
||||
standard_testfile
|
||||
set executable ${testfile}
|
||||
|
||||
if [target_info exists gdb,nosignals] {
|
||||
verbose "Skipping ${testfile}.exp because of nosignals."
|
||||
return -1
|
||||
}
|
||||
|
||||
# Test uses host "kill".
|
||||
if { [is_remote target] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
|
||||
executable [list debug "incdir=${objdir}"]] != "" } {
|
||||
return -1
|
||||
}
|
||||
|
||||
proc get_value {var test} {
|
||||
global expect_out
|
||||
global gdb_prompt
|
||||
global decimal
|
||||
|
||||
set value -1
|
||||
gdb_test_multiple "print $var" "$test" {
|
||||
-re ".*= ($decimal).*\r\n$gdb_prompt $" {
|
||||
set value $expect_out(1,string)
|
||||
pass "$test"
|
||||
}
|
||||
}
|
||||
return ${value}
|
||||
}
|
||||
|
||||
# Start with a fresh gdb.
|
||||
|
||||
clean_restart $executable
|
||||
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "set wait-thread-2 breakpoint here"]
|
||||
gdb_continue_to_breakpoint "run to wait-thread-2 breakpoint"
|
||||
gdb_test "info threads" "" "info threads with thread 2"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "set wait-thread-3 breakpoint here"]
|
||||
gdb_continue_to_breakpoint "run to breakpoint"
|
||||
gdb_test "info threads" "" "info threads with thread 3"
|
||||
|
||||
set testpid [get_value "pid" "get pid of inferior"]
|
||||
|
||||
gdb_test "set scheduler-locking on"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "set breakpoint child_two here"]
|
||||
gdb_breakpoint [gdb_get_line_number "set breakpoint child_one here"]
|
||||
|
||||
gdb_test "thread 3" "" "switch to thread 3 to run to its breakpoint"
|
||||
gdb_continue_to_breakpoint "run to breakpoint in thread 3"
|
||||
|
||||
gdb_test "thread 2" "" "switch to thread 2 to run to its breakpoint"
|
||||
gdb_continue_to_breakpoint "run to breakpoint in thread 2"
|
||||
|
||||
delete_breakpoints
|
||||
|
||||
gdb_test "b *\$pc" "" "set breakpoint to be stepped over"
|
||||
# Make sure the first loop breaks without hitting the breakpoint
|
||||
# again.
|
||||
gdb_test "p *myp = 0" " = 0" "force loop break in thread 2"
|
||||
|
||||
# We want "print" to make sure the target reports the signal to the
|
||||
# core.
|
||||
gdb_test "handle SIGUSR1 print nostop pass" "" ""
|
||||
|
||||
# Queue a signal in thread 2.
|
||||
remote_exec host "kill -SIGUSR1 ${testpid}"
|
||||
|
||||
gdb_test "thread 3" "" "switch to thread 3 for stepping"
|
||||
set my_number [get_value "my_number" "get my_number"]
|
||||
set cnt_before [get_value "args\[$my_number\]" "get count before step"]
|
||||
gdb_test "set scheduler-locking off"
|
||||
|
||||
# Make sure we're exercising the paths we want to.
|
||||
gdb_test "set debug infrun 1"
|
||||
|
||||
gdb_test \
|
||||
"step" \
|
||||
".*prepare_to_proceed \\(step=1\\), switched to.*signal arrived while stepping over breakpoint.*switching back to stepped thread.*stepped to a different line.*callme.*" \
|
||||
"step"
|
||||
|
||||
set cnt_after [get_value "args\[$my_number\]" "get count after step"]
|
||||
|
||||
# Test that GDB doesn't inadvertently resume the stepped thread when a
|
||||
# signal arrives while stepping over a breakpoint in another thread.
|
||||
|
||||
set test "stepped thread under control"
|
||||
if { $cnt_before + 1 == $cnt_after } {
|
||||
pass $test
|
||||
} else {
|
||||
fail $test
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
7.7
|
||||
7.7.1
|
||||
|
||||
@@ -310,12 +310,18 @@ thread_rec (DWORD id, int get_context)
|
||||
{
|
||||
DWORD err = GetLastError ();
|
||||
|
||||
warning (_("SuspendThread (tid=0x%x) failed."
|
||||
" (winerr %u)"),
|
||||
(unsigned) id, (unsigned) err);
|
||||
return NULL;
|
||||
/* We get Access Denied (5) when trying to suspend
|
||||
threads that Windows started on behalf of the
|
||||
debuggee, usually when those threads are just
|
||||
about to exit. */
|
||||
if (err != ERROR_ACCESS_DENIED)
|
||||
warning (_("SuspendThread (tid=0x%x) failed."
|
||||
" (winerr %u)"),
|
||||
(unsigned) id, (unsigned) err);
|
||||
th->suspended = -1;
|
||||
}
|
||||
th->suspended = 1;
|
||||
else
|
||||
th->suspended = 1;
|
||||
}
|
||||
else if (get_context < 0)
|
||||
th->suspended = -1;
|
||||
@@ -445,7 +451,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
|
||||
{
|
||||
thread_info *th = current_thread;
|
||||
th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
|
||||
GetThreadContext (th->h, &th->context);
|
||||
CHECK (GetThreadContext (th->h, &th->context));
|
||||
/* Copy dr values from that thread.
|
||||
But only if there were not modified since last stop.
|
||||
PR gdb/2388 */
|
||||
@@ -1266,10 +1272,12 @@ handle_exception (struct target_waitstatus *ourstatus)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Resume all artificially suspended threads if we are continuing
|
||||
execution. */
|
||||
/* Resume thread specified by ID, or all artificially suspended
|
||||
threads, if we are continuing execution. KILLED non-zero means we
|
||||
have killed the inferior, so we should ignore weird errors due to
|
||||
threads shutting down. */
|
||||
static BOOL
|
||||
windows_continue (DWORD continue_status, int id)
|
||||
windows_continue (DWORD continue_status, int id, int killed)
|
||||
{
|
||||
int i;
|
||||
thread_info *th;
|
||||
@@ -1297,7 +1305,16 @@ windows_continue (DWORD continue_status, int id)
|
||||
}
|
||||
if (th->context.ContextFlags)
|
||||
{
|
||||
CHECK (SetThreadContext (th->h, &th->context));
|
||||
DWORD ec = 0;
|
||||
|
||||
if (GetExitCodeThread (th->h, &ec)
|
||||
&& ec == STILL_ACTIVE)
|
||||
{
|
||||
BOOL status = SetThreadContext (th->h, &th->context);
|
||||
|
||||
if (!killed)
|
||||
CHECK (status);
|
||||
}
|
||||
th->context.ContextFlags = 0;
|
||||
}
|
||||
if (th->suspended > 0)
|
||||
@@ -1425,9 +1442,9 @@ windows_resume (struct target_ops *ops,
|
||||
Otherwise complain. */
|
||||
|
||||
if (resume_all)
|
||||
windows_continue (continue_status, -1);
|
||||
windows_continue (continue_status, -1, 0);
|
||||
else
|
||||
windows_continue (continue_status, ptid_get_tid (ptid));
|
||||
windows_continue (continue_status, ptid_get_tid (ptid), 0);
|
||||
}
|
||||
|
||||
/* Ctrl-C handler used when the inferior is not run in the same console. The
|
||||
@@ -1645,7 +1662,7 @@ get_windows_debug_event (struct target_ops *ops,
|
||||
if (continue_status == -1)
|
||||
windows_resume (ops, minus_one_ptid, 0, 1);
|
||||
else
|
||||
CHECK (windows_continue (continue_status, -1));
|
||||
CHECK (windows_continue (continue_status, -1, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2382,13 +2399,13 @@ windows_create_inferior (struct target_ops *ops, char *exec_file,
|
||||
|
||||
do_initial_windows_stuff (ops, pi.dwProcessId, 0);
|
||||
|
||||
/* windows_continue (DBG_CONTINUE, -1); */
|
||||
/* windows_continue (DBG_CONTINUE, -1, 0); */
|
||||
}
|
||||
|
||||
static void
|
||||
windows_mourn_inferior (struct target_ops *ops)
|
||||
{
|
||||
(void) windows_continue (DBG_CONTINUE, -1);
|
||||
(void) windows_continue (DBG_CONTINUE, -1, 0);
|
||||
i386_cleanup_dregs();
|
||||
if (open_process_used)
|
||||
{
|
||||
@@ -2456,7 +2473,7 @@ windows_kill_inferior (struct target_ops *ops)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!windows_continue (DBG_CONTINUE, -1))
|
||||
if (!windows_continue (DBG_CONTINUE, -1, 1))
|
||||
break;
|
||||
if (!WaitForDebugEvent (¤t_event, INFINITE))
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user