mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
86 Commits
users/palv
...
gdb-8.0-re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f1c02597c | ||
|
|
3b25c87591 | ||
|
|
e8d1908802 | ||
|
|
6a388aee37 | ||
|
|
e53803fa24 | ||
|
|
ce3dd59c3d | ||
|
|
704f06fe08 | ||
|
|
1e4004c976 | ||
|
|
0da1884895 | ||
|
|
d65c730fce | ||
|
|
c6ef7a7284 | ||
|
|
69ffd77d9e | ||
|
|
65af931864 | ||
|
|
65b939518c | ||
|
|
fefc936892 | ||
|
|
afa9a51c56 | ||
|
|
a527ec51ea | ||
|
|
f9e9e7ee55 | ||
|
|
7976ea601c | ||
|
|
958f7437a8 | ||
|
|
718b5430a7 | ||
|
|
ebb258e955 | ||
|
|
814385bb25 | ||
|
|
a1cc26f6c3 | ||
|
|
958d57d02d | ||
|
|
db9a604024 | ||
|
|
d75154f33d | ||
|
|
f864c7e853 | ||
|
|
c00cbd93ff | ||
|
|
efaba6bc8f | ||
|
|
69e9e8a0d5 | ||
|
|
b6486c1f82 | ||
|
|
d05228c1bb | ||
|
|
18c0a7cd22 | ||
|
|
fb0fab03a5 | ||
|
|
81aeac9bbd | ||
|
|
f35e662d82 | ||
|
|
6aad91250d | ||
|
|
bf10e6acf9 | ||
|
|
c5d422588d | ||
|
|
c11c7feaf3 | ||
|
|
ecf4983a0f | ||
|
|
d2556b2d60 | ||
|
|
3b258c371f | ||
|
|
3d3620493b | ||
|
|
572a45ac68 | ||
|
|
dd924a5f0f | ||
|
|
65ea01b592 | ||
|
|
a5a72f67fd | ||
|
|
893df71e62 | ||
|
|
6261be5615 | ||
|
|
1332b4fa37 | ||
|
|
ac7d85722a | ||
|
|
5b2f026c0d | ||
|
|
d76700e0a4 | ||
|
|
7dce57d1b5 | ||
|
|
26597c93ac | ||
|
|
ee53a929a4 | ||
|
|
d4c682630c | ||
|
|
80297efd14 | ||
|
|
c2449d01b7 | ||
|
|
05e4d87859 | ||
|
|
8b44d08f47 | ||
|
|
712e80a004 | ||
|
|
19a1ccea89 | ||
|
|
e453f191a5 | ||
|
|
d41089194f | ||
|
|
c6767e625c | ||
|
|
6f43fe1508 | ||
|
|
16de50a5e2 | ||
|
|
9b81aa9a8b | ||
|
|
f99ef213bc | ||
|
|
597a1845d1 | ||
|
|
f7cc213124 | ||
|
|
8e93ae6831 | ||
|
|
bea550569a | ||
|
|
ffb401b866 | ||
|
|
46144c47a7 | ||
|
|
b2e445cf19 | ||
|
|
7ddd642597 | ||
|
|
a484616b31 | ||
|
|
c877c09620 | ||
|
|
24b03ea864 | ||
|
|
e7668ff7fe | ||
|
|
2e341fefa9 | ||
|
|
c2d00ab3a3 |
@@ -1,3 +1,7 @@
|
||||
2017-04-17 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* development.sh (development): Set to false.
|
||||
|
||||
2017-04-13 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* coffcode.h: Wrap some overly long _bfd_error_handler args.
|
||||
|
||||
@@ -16,4 +16,4 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Controls whether to enable development-mode features by default.
|
||||
development=true
|
||||
development=false
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define BFD_VERSION_DATE 20170415
|
||||
#define BFD_VERSION_DATE 20170604
|
||||
#define BFD_VERSION @bfd_version@
|
||||
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
|
||||
#define REPORT_BUGS_TO @report_bugs_to@
|
||||
|
||||
258
gdb/ChangeLog
258
gdb/ChangeLog
@@ -1,3 +1,261 @@
|
||||
2017-06-04 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 8.0.
|
||||
* PROBLEMS: Likewise.
|
||||
|
||||
2017-05-30 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* NEWS (Changes in GDB 8.0): Remove extra empty line. Move
|
||||
"Removed targets and native configurations" up. Merge duplicate
|
||||
"New commands" sub-sections. Add "New options" sub-sections.
|
||||
|
||||
2017-05-26 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* cli/cli-script.c (user_args::insert_args): Call gdb::to_string.
|
||||
|
||||
* common/common-utils.h (REPLACE_TO_STRING) [__MINGW32__]: Define
|
||||
to 1 if std::to_string is not available.
|
||||
(gdb::to_string) [REPLACE_TO_STRING]: Provide a replacement
|
||||
implementation for std::string.
|
||||
|
||||
2017-05-19 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR tui/21482
|
||||
* gdb_curses.h (NOMACROS): Define.
|
||||
(NCURSES_NOMACROS): Define.
|
||||
|
||||
2017-05-19 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR tui/21482
|
||||
* tui/tui-windata.c (tui_erase_data_content): Cast last mvwaddstr
|
||||
arg to char *.
|
||||
* tui/tui-wingeneral.c (box_win): Likewise.
|
||||
* tui/tui-winsource.c (tui_erase_source_content): Likewise.
|
||||
(tui_show_source_line): Likewise.
|
||||
(tui_show_exec_info_content): Likewise.
|
||||
|
||||
2017-05-13 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* tui/tui.c (tui_enable): Cast "unknown" to 'char *' to avoid a
|
||||
C++ compiler warning.
|
||||
|
||||
2017-05-17 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* cli/cli-decode.c (add_alias_cmd): New function.
|
||||
* command.h (add_alias_cmd): Declare.
|
||||
* infcmd.c (_initialize_infcmd): Don't call add_com_alias,
|
||||
instead call add_alias_cmd.
|
||||
|
||||
2017-05-12 Tom Tromey <tom@tromey.com>
|
||||
|
||||
PR rust/21483:
|
||||
* rust-lang.c (rust_evaluate_subexp) <STRUCTOP_STRUCT>: Don't
|
||||
recurse, just call value_struct_elt directly.
|
||||
|
||||
2017-05-12 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* rust-lang.c (rust_dump_subexp_body) <STRUCTOP_ANONYMOUS,
|
||||
OP_RUST_ARRAY>: Fix.
|
||||
|
||||
2017-05-12 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* rust-lang.c (rust_print_subexp): Replace "return" with "break".
|
||||
|
||||
2017-05-15 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* procfs.c (procfs_create_inferior): Change prototype to match
|
||||
definition.
|
||||
|
||||
2017-05-04 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.99.91.DATE-git.
|
||||
* PROBLEMS: Likewise.
|
||||
|
||||
2017-05-04 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 7.99.91 released.
|
||||
|
||||
2017-05-04 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.99.91.
|
||||
* PROBLEMS: Likewise.
|
||||
|
||||
2017-05-04 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* NEWS: Rename the "Changes since GDB 7.12" section into
|
||||
"Changes in GDB 8.0".
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* Makefile.in (SUBDIR_PYTHON_OBS): Add py-instruction.o.
|
||||
(SUBDIR_PYTHON_SRCS): Add py-instruction.c.
|
||||
* python/py-instruction.c, python/py-instruction.h: New file.
|
||||
* python/py-record.c: Add py-instruction.h include.
|
||||
(gdbpy_initialize_record): Make gdb.Instruction a super class of
|
||||
gdb.RecordInstruction.
|
||||
* python/python-internal.h: Add gdbpy_initialize_instruction
|
||||
declaration.
|
||||
* python/python.c (do_start_initialization): Add
|
||||
gdbpy_initialize_instruction.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python/py-record-btrace.c (BTPY_REQUIRE_VALID_CALL, btpy_call_type):
|
||||
Remove.
|
||||
(btrace_func_from_recpy_func): New function.
|
||||
(btpy_call_new, btpy_number, btpy_hash, btpy_richcompare): Remove.
|
||||
(btpy_call_level, btpy_call_symbol, btpy_call_instructions,
|
||||
btpy_call_up, btpy_call_prev_sibling, btpy_call_next_sibling): Rename to ...
|
||||
(recpy_bt_func_level, recpy_bt_func_symbol, recpy_bt_func_instructions,
|
||||
recpy_bt_func_up, recpy_bt_func_prev, recpy_bt_func_next): This.
|
||||
Also, use new helper functions.
|
||||
(btpy_list_item): Use new helper functions.
|
||||
(recpy_bt_function_call_history): Use new type name.
|
||||
(btpy_call_getset): Remove.
|
||||
(gdbpy_initialize_btrace): Remove code to initialize
|
||||
gdb.BtraceFunctionCall.
|
||||
* python/py-record-btrace.h (recpy_bt_func_number, recpy_btb_func_level,
|
||||
recpy_btb_func_symbol, recpy_bt_func_instructions, recpy_bt_func_up,
|
||||
recpy_bt_func_prev, recpy_bt_func_next): New export.
|
||||
* python/py-record.c (recpy_func_type): New static object.
|
||||
(recpy_func_new, recpy_func_level, recpy_func_symbol,
|
||||
recpy_func_instructions, recpy_func_up, recpy_func_prev,
|
||||
recpy_func_next): New function.
|
||||
(recpy_element_hash, recpy_element_richcompare): Updated comment.
|
||||
(recpy_func_getset): New static object.
|
||||
(gdbpy_initialize_record): Add code to initialize gdb.RecordInstruction.
|
||||
* python/py-record.h (recpy_func_type, recpy_func_new): New export.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python/py-record-btrace.c (BTPY_REQUIRE_VALID_INSN): Remove.
|
||||
(btpy_object, btpy_insn_type, btpy_new): Remove.
|
||||
(btpy_list_object): Use gdb.RecordInstruction type instead of
|
||||
gdb.BtraceInstruction type.
|
||||
(btrace_insn_from_recpy_insn): New function.
|
||||
(btpy_insn_or_gap_new): Adjust comment. Use recpy_insn_new instead of
|
||||
btpy_new.
|
||||
(btpy_call_new, btpy_list_item): Do not use btpy_new anymore.
|
||||
(btpy_number, btpy_hash, btpy_call_level, btpy_call_symbol,
|
||||
btpy_call_instructions, btpy_call_up, btpy_call_prev_sibling,
|
||||
btpy_call_next_sibling, btpy_richcompare): Use recpy_element_object
|
||||
instead of btpy_object.
|
||||
(btpy_insn_sal, btpy_insn_pc, btpy_insn_size, btpy_insn_is_speculative,
|
||||
btpy_insn_data, btpy_insn_decode): Rename to ...
|
||||
(recpy_bt_insn_sal, recpy_bt_insn_pc, recpy_bt_insn_size,
|
||||
recpy_bt_insn_is_speculative, recpy_bt_insn_data,
|
||||
recpy_bt_insn_decode): This. Also, use new helper functions.
|
||||
(btpy_list_position, recpy_bt_goto): Use recpy_element_object and
|
||||
recpy_insn_type.
|
||||
(btpy_insn_getset): Remove.
|
||||
(gdbpy_initialize_btrace): Remove code to initialize
|
||||
gdb.BtraceInstruction. Use recpy_element_object.
|
||||
* python/py-record-btrace.h (recpy_bt_insn_number, recpy_bt_insn_sal,
|
||||
recpy_bt_insn_pc, recpy_bt_insn_data, recpy_bt_insn_decoded,
|
||||
recpy_bt_insn_size, recpy_bt_insn_is_speculative): New export.
|
||||
* python/py-record.c (recpy_insn_type): New static object.
|
||||
(recpy_insn_new, recpy_insn_sal, recpy_insn_pc, recpy_insn_data,
|
||||
recpy_insn_decoded, recpy_insn_size, recpy_insn_is_speculative,
|
||||
recpy_element_number, recpy_element_hash, recpy_element_richcompare):
|
||||
New function.
|
||||
(recpy_insn_getset): New static object.
|
||||
(gdbpy_initialize_record): Initialize gdb.RecordInstruction.
|
||||
* python/py-record.h (recpy_element_object): New typedef.
|
||||
(recpy_insn_type, recpy_insn_new): New export.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* py-record-btrace.c (btpy_insn_new): Removed.
|
||||
(btpy_insn_or_gap_new): New function.
|
||||
(btpy_insn_error): Removed.
|
||||
(btpy_insn_sal, btpy_insn_pc, btpy_insn_size, btpy_insn_is_speculative,
|
||||
btpy_insn_data, btpy_insn_decode): Remove code path for gaps.
|
||||
(recpy_bt_replay_position, recpy_bt_begin, recpy_bt_end): Call
|
||||
btpy_insn_or_gap_new instead of btpy_insn_new.
|
||||
(btpy_insn_getset): Remove btpy_insn_error.
|
||||
* py-record.c (recpy_gap_type): New static object.
|
||||
(recpy_gap_object): New typedef.
|
||||
(recpy_gap_new, recpy_gap_number, recpy_gap_reason_code,
|
||||
recpy_gap_reason_string): New function.
|
||||
(recpy_gap_getset): New static object.
|
||||
(gdbpy_initialize_record): Initialize gdb.RecordGap type.
|
||||
* py-record.h (recpy_gap_new): New export.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python/py-record.c (recpy_ptid): Remove.
|
||||
(recpy_record_getset): Remove recpy_ptid.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* btrace.c (btrace_fetch): Set inferior_ptid.
|
||||
* python/py-record-btrace.c: Add "py-record.h" include.
|
||||
(recpy_bt_format, recpy_bt_replay_position, recpy_bt_begin,
|
||||
recpy_bt_end, recpy_bt_instruction_history,
|
||||
recpy_bt_function_call_history, recpy_bt_goto): Use ptid stored
|
||||
in gdb.Record object instead of current ptid.
|
||||
* python/py-record.c: Include new "py-record.h" file.
|
||||
(recpy_record_object): Moved to py-record.h.
|
||||
* python/py-record.h: New file.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python/py-record-btrace.c (BTPY_REQUIRE_VALID_INSN,
|
||||
BTPY_REQUIRE_VALID_CALL, recpy_bt_function_call_history): Fix
|
||||
indentation.
|
||||
|
||||
2017-04-28 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* mips-linux-nat.c (mips_linux_new_thread): Use ptid method
|
||||
lwp instead of ptid_get_lwp.
|
||||
|
||||
2017-04-28 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* mips-linux-nat.c (mips_linux_new_thread): Get lwpid from
|
||||
lwp_info instead of getting from inferior_ptid.
|
||||
|
||||
2017-04-27 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* gdbtypes.c (LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS)
|
||||
DIFFERENT_REFERENCE_TYPE_BADNESS): Remove.
|
||||
(CV_CONVERSION_BADNESS): Define.
|
||||
(rank_one_type): Remove overly restrictive rvalue reference
|
||||
rank checks.
|
||||
Add cv-qualifier checks and subranks for type equality.
|
||||
* gdbtypes.h (REFERENCE_CONVERSION_RVALUE,
|
||||
REFERENCE_CONVERSION_CONST_LVALUE, CV_CONVERSION_BADNESS,
|
||||
CV_CONVERSION_CONST, CV_CONVERSION_VOLATILE): Declare.
|
||||
|
||||
2017-04-27 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* python/py-inferior.c (inferior_to_inferior_object): Increment reference
|
||||
count when creating the object.
|
||||
|
||||
2017-04-25 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* aarch64-tdep.c (aarch64_gdbarch_init): Don't call
|
||||
set_gdbarch_wchar_bit.
|
||||
* arm-tdep.c (arm_gdbarch_init): Likewise.
|
||||
|
||||
2017-04-21 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* aarch64-tdep.c (selftests::aarch64_process_record_test): Make it #if
|
||||
GDB_SELF_TEST.
|
||||
* arm-tdep.c (selftests::arm_record_test): Likewise.
|
||||
|
||||
2017-04-18 John Baldwin <jhb@FreeBSD.org>
|
||||
|
||||
PR threads/20743
|
||||
* fbsd-nat.c (resume_one_thread_cb): Remove.
|
||||
(resume_all_threads_cb): Remove.
|
||||
(fbsd_resume): Use ALL_NON_EXITED_THREADS instead of
|
||||
iterate_over_threads.
|
||||
|
||||
2017-04-17 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 8.0 branch created (725bf5cf125783c2a7ca4ab63d3768e220bab2db):
|
||||
* version.in: Bump version to 7.99.90.DATE-git.
|
||||
|
||||
2017-04-13 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
|
||||
PR gdb/21385
|
||||
|
||||
@@ -453,6 +453,7 @@ SUBDIR_PYTHON_OBS = \
|
||||
py-inferior.o \
|
||||
py-infevents.o \
|
||||
py-infthread.o \
|
||||
py-instruction.o \
|
||||
py-lazy-string.o \
|
||||
py-linetable.o \
|
||||
py-newobjfileevent.o \
|
||||
@@ -496,6 +497,7 @@ SUBDIR_PYTHON_SRCS = \
|
||||
python/py-inferior.c \
|
||||
python/py-infevents.c \
|
||||
python/py-infthread.c \
|
||||
python/py-instruction.c \
|
||||
python/py-lazy-string.c \
|
||||
python/py-linetable.c \
|
||||
python/py-newobjfileevent.c \
|
||||
|
||||
39
gdb/NEWS
39
gdb/NEWS
@@ -1,7 +1,7 @@
|
||||
What has changed in GDB?
|
||||
(Organized release by release)
|
||||
|
||||
*** Changes since GDB 7.12
|
||||
*** Changes in GDB 8.0
|
||||
|
||||
* GDB now supports access to the PKU register on GNU/Linux. The register is
|
||||
added by the Memory Protection Keys for Userspace feature which will be
|
||||
@@ -70,17 +70,34 @@
|
||||
|
||||
FreeBSD/mips mips*-*-freebsd
|
||||
|
||||
|
||||
* New targets
|
||||
|
||||
Synopsys ARC arc*-*-elf32
|
||||
FreeBSD/mips mips*-*-freebsd
|
||||
|
||||
* Removed targets and native configurations
|
||||
|
||||
Alpha running FreeBSD alpha*-*-freebsd*
|
||||
Alpha running GNU/kFreeBSD alpha*-*-kfreebsd*-gnu
|
||||
|
||||
* New commands
|
||||
|
||||
flash-erase
|
||||
Erases all the flash memory regions reported by the target.
|
||||
|
||||
maint print arc arc-instruction address
|
||||
Print internal disassembler information about instruction at a given address.
|
||||
|
||||
* New options
|
||||
|
||||
set disassembler-options
|
||||
show disassembler-options
|
||||
Controls the passing of target specific information to the disassembler.
|
||||
If it is necessary to specify more than one disassembler option then
|
||||
multiple options can be placed together into a comma separated list.
|
||||
The default value is the empty string. Currently, the only supported
|
||||
targets are ARM, PowerPC and S/390.
|
||||
|
||||
* New MI commands
|
||||
|
||||
-target-flash-erase
|
||||
@@ -91,24 +108,6 @@ flash-erase
|
||||
List the shared libraries in the program. This is
|
||||
equivalent to the CLI command "info shared".
|
||||
|
||||
* New commands
|
||||
|
||||
set disassembler-options
|
||||
show disassembler-options
|
||||
Controls the passing of target specific information to the disassembler.
|
||||
If it is necessary to specify more than one disassembler option then
|
||||
multiple options can be placed together into a comma separated list.
|
||||
The default value is the empty string. Currently, the only supported
|
||||
targets are ARM, PowerPC and S/390.
|
||||
|
||||
maint print arc arc-instruction address
|
||||
Print internal disassembler information about instruction at a given address.
|
||||
|
||||
* Removed targets and native configurations
|
||||
|
||||
Alpha running FreeBSD alpha*-*-freebsd*
|
||||
Alpha running GNU/kFreeBSD alpha*-*-kfreebsd*-gnu
|
||||
|
||||
*** Changes in GDB 7.12
|
||||
|
||||
* GDB and GDBserver now build with a C++ compiler by default.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
Known problems in GDB 7.2.50
|
||||
Known problems in GDB 8.0
|
||||
|
||||
See also: http://www.gnu.org/software/gdb/bugs/
|
||||
|
||||
|
||||
@@ -2977,7 +2977,6 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
set_gdbarch_long_long_bit (gdbarch, 64);
|
||||
set_gdbarch_ptr_bit (gdbarch, 64);
|
||||
set_gdbarch_char_signed (gdbarch, 0);
|
||||
set_gdbarch_wchar_bit (gdbarch, 64);
|
||||
set_gdbarch_wchar_signed (gdbarch, 0);
|
||||
set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
|
||||
set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
|
||||
@@ -3040,10 +3039,12 @@ aarch64_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
paddress (gdbarch, tdep->lowest_pc));
|
||||
}
|
||||
|
||||
#if GDB_SELF_TEST
|
||||
namespace selftests
|
||||
{
|
||||
static void aarch64_process_record_test (void);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Suppress warning from -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_aarch64_tdep;
|
||||
|
||||
@@ -9409,7 +9409,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
set_gdbarch_wchar_signed (gdbarch, 0);
|
||||
else
|
||||
set_gdbarch_wchar_signed (gdbarch, 1);
|
||||
set_gdbarch_wchar_bit (gdbarch, 32);
|
||||
|
||||
/* Note: for displaced stepping, this includes the breakpoint, and one word
|
||||
of additional scratch space. This setting isn't used for anything beside
|
||||
@@ -9596,10 +9595,12 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
(unsigned long) tdep->lowest_pc);
|
||||
}
|
||||
|
||||
#if GDB_SELF_TEST
|
||||
namespace selftests
|
||||
{
|
||||
static void arm_record_test (void);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern initialize_file_ftype _initialize_arm_tdep; /* -Wmissing-prototypes */
|
||||
|
||||
|
||||
@@ -1797,11 +1797,17 @@ btrace_fetch (struct thread_info *tp)
|
||||
if (btinfo->replay != NULL)
|
||||
return;
|
||||
|
||||
/* With CLI usage, TP->PTID always equals INFERIOR_PTID here. Now that we
|
||||
can store a gdb.Record object in Python referring to a different thread
|
||||
than the current one, temporarily set INFERIOR_PTID. */
|
||||
cleanup = save_inferior_ptid ();
|
||||
inferior_ptid = tp->ptid;
|
||||
|
||||
/* We should not be called on running or exited threads. */
|
||||
gdb_assert (can_access_registers_ptid (tp->ptid));
|
||||
|
||||
btrace_data_init (&btrace);
|
||||
cleanup = make_cleanup_btrace_data (&btrace);
|
||||
make_cleanup_btrace_data (&btrace);
|
||||
|
||||
/* Let's first try to extend the trace we already have. */
|
||||
if (btinfo->end != NULL)
|
||||
|
||||
@@ -284,16 +284,10 @@ deprecate_cmd (struct cmd_list_element *cmd, const char *replacement)
|
||||
}
|
||||
|
||||
struct cmd_list_element *
|
||||
add_alias_cmd (const char *name, const char *oldname, enum command_class theclass,
|
||||
int abbrev_flag, struct cmd_list_element **list)
|
||||
add_alias_cmd (const char *name, cmd_list_element *old,
|
||||
enum command_class theclass, int abbrev_flag,
|
||||
struct cmd_list_element **list)
|
||||
{
|
||||
const char *tmp;
|
||||
struct cmd_list_element *old;
|
||||
struct cmd_list_element *c;
|
||||
|
||||
tmp = oldname;
|
||||
old = lookup_cmd (&tmp, *list, "", 1, 1);
|
||||
|
||||
if (old == 0)
|
||||
{
|
||||
struct cmd_list_element *prehook, *prehookee, *posthook, *posthookee;
|
||||
@@ -307,7 +301,7 @@ add_alias_cmd (const char *name, const char *oldname, enum command_class theclas
|
||||
return 0;
|
||||
}
|
||||
|
||||
c = add_cmd (name, theclass, NULL, old->doc, list);
|
||||
struct cmd_list_element *c = add_cmd (name, theclass, NULL, old->doc, list);
|
||||
|
||||
/* If OLD->DOC can be freed, we should make another copy. */
|
||||
if (old->doc_allocated)
|
||||
@@ -330,6 +324,21 @@ add_alias_cmd (const char *name, const char *oldname, enum command_class theclas
|
||||
return c;
|
||||
}
|
||||
|
||||
struct cmd_list_element *
|
||||
add_alias_cmd (const char *name, const char *oldname,
|
||||
enum command_class theclass, int abbrev_flag,
|
||||
struct cmd_list_element **list)
|
||||
{
|
||||
const char *tmp;
|
||||
struct cmd_list_element *old;
|
||||
|
||||
tmp = oldname;
|
||||
old = lookup_cmd (&tmp, *list, "", 1, 1);
|
||||
|
||||
return add_alias_cmd (name, old, theclass, abbrev_flag, list);
|
||||
}
|
||||
|
||||
|
||||
/* Like add_cmd but adds an element for a command prefix: a name that
|
||||
should be followed by a subcommand to be looked up in another
|
||||
command list. PREFIXLIST should be the address of the variable
|
||||
|
||||
@@ -806,7 +806,7 @@ user_args::insert_args (const char *line) const
|
||||
|
||||
if (p[4] == 'c')
|
||||
{
|
||||
new_line += std::to_string (m_args.size ());
|
||||
new_line += gdb::to_string (m_args.size ());
|
||||
line = p + 5;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -141,6 +141,12 @@ extern struct cmd_list_element *add_alias_cmd (const char *, const char *,
|
||||
enum command_class, int,
|
||||
struct cmd_list_element **);
|
||||
|
||||
extern struct cmd_list_element *add_alias_cmd (const char *,
|
||||
cmd_list_element *,
|
||||
enum command_class, int,
|
||||
struct cmd_list_element **);
|
||||
|
||||
|
||||
extern struct cmd_list_element *add_prefix_cmd (const char *, enum command_class,
|
||||
cmd_cfunc_ftype *fun,
|
||||
const char *,
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
/* If possible, define FUNCTION_NAME, a macro containing the name of
|
||||
the function being defined. Since this macro may not always be
|
||||
@@ -63,6 +64,47 @@ int xsnprintf (char *str, size_t size, const char *format, ...)
|
||||
std::string string_printf (const char* fmt, ...)
|
||||
ATTRIBUTE_PRINTF (1, 2);
|
||||
|
||||
/* Returns a string representation of VAL. Replacement for C++11
|
||||
std::to_string for hosts that lack it. */
|
||||
|
||||
namespace gdb {
|
||||
|
||||
#define REPLACE_TO_STRING 0
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* mingw.org's MinGW runtime before version 5.0 needs the replacement
|
||||
below. Tested with mingwrt-3.22.2 and mingwrt-5.0, and with
|
||||
libstdc++ included with MinGW GCC 5.3.0. */
|
||||
# include <_mingw.h>
|
||||
/* We test __MINGW64_VERSION_MAJOR to exclude MinGW64, which doesn't
|
||||
need this replacement. */
|
||||
# if !defined __MINGW64_VERSION_MAJOR && !defined _GLIBCXX_USE_C99
|
||||
# undef REPLACE_TO_STRING
|
||||
# define REPLACE_TO_STRING 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if REPLACE_TO_STRING
|
||||
|
||||
template <class T>
|
||||
inline std::string
|
||||
to_string (const T &val)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << val;
|
||||
return ss.str ();
|
||||
}
|
||||
|
||||
#else /* !REPLACE_TO_STRING */
|
||||
|
||||
using std::to_string;
|
||||
|
||||
#endif
|
||||
|
||||
#undef REPLACE_TO_STRING
|
||||
}
|
||||
|
||||
/* Make a copy of the string at PTR with LEN characters
|
||||
(and add a null character at the end in the copy).
|
||||
Uses malloc to get the space. Returns the address of the copy. */
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python.texi (Recording in Python): Factor out the documentation of
|
||||
gdb.RecordInstruction's super class.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python.texi (Recording in Python): Replace gdb.BtraceFunction with
|
||||
gdb.RecordFunctionSegment. Rename prev_sibling and next_sibling to
|
||||
prev and next.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python.texi (Recording in Python): Replace gdb.BtraceInstruction with
|
||||
gdb.RecordInstruction
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python.texi (Recording in Python): Add documentation for
|
||||
gdb.RecordGap and remove documentation of special cases for
|
||||
gdb.BtraceInstruction.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* python.texi (Recording in Python): Remove Record.ptid defvar.
|
||||
|
||||
2017-03-28 Anton Kolesov <anton.kolesov@synopsys.com>
|
||||
|
||||
* gdb.texinfo (Synopsys ARC): Document "set debug arc 2".
|
||||
|
||||
@@ -3110,13 +3110,6 @@ currently active. All record objects become invalid after this call.
|
||||
|
||||
A @code{gdb.Record} object has the following attributes:
|
||||
|
||||
@defvar Record.ptid
|
||||
ID of the thread associated with this object as a tuple of three integers. The
|
||||
first is the Process ID (PID); the second is the Lightweight Process ID (LWPID),
|
||||
and the third is the Thread ID (TID). Either the LWPID or TID may be 0, which
|
||||
indicates that the operating system does not use that identifier.
|
||||
@end defvar
|
||||
|
||||
@defvar Record.method
|
||||
A string with the current recording method, e.g.@: @code{full} or
|
||||
@code{btrace}.
|
||||
@@ -3156,96 +3149,99 @@ A @code{gdb.Record} object has the following methods:
|
||||
Move the replay position to the given @var{instruction}.
|
||||
@end defun
|
||||
|
||||
The attributes and methods of instruction objects depend on the current
|
||||
recording method. Currently, only btrace instructions are supported.
|
||||
The common @code{gdb.Instruction} class that recording method specific
|
||||
instruction objects inherit from, has the following attributes:
|
||||
|
||||
A @code{gdb.BtraceInstruction} object has the following attributes:
|
||||
@defvar Instruction.pc
|
||||
An integer representing this instruction's address.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceInstruction.number
|
||||
An integer identifying this instruction. @var{number} corresponds to
|
||||
@defvar Instruction.data
|
||||
A buffer with the raw instruction data. In Python 3, the return value is a
|
||||
@code{memoryview} object.
|
||||
@end defvar
|
||||
|
||||
@defvar Instruction.decoded
|
||||
A human readable string with the disassembled instruction.
|
||||
@end defvar
|
||||
|
||||
@defvar Instruction.size
|
||||
The size of the instruction in bytes.
|
||||
@end defvar
|
||||
|
||||
Additionally @code{gdb.RecordInstruction} has the following attributes:
|
||||
|
||||
@defvar RecordInstruction.number
|
||||
An integer identifying this instruction. @code{number} corresponds to
|
||||
the numbers seen in @code{record instruction-history}
|
||||
(@pxref{Process Record and Replay}).
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceInstruction.error
|
||||
An integer identifying the error code for gaps in the history.
|
||||
@code{None} for regular instructions.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceInstruction.sal
|
||||
@defvar RecordInstruction.sal
|
||||
A @code{gdb.Symtab_and_line} object representing the associated symtab
|
||||
and line of this instruction. May be @code{None} if the instruction
|
||||
is a gap.
|
||||
and line of this instruction. May be @code{None} if no debug information is
|
||||
available.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceInstruction.pc
|
||||
An integer representing this instruction's address. May be @code{None}
|
||||
if the instruction is a gap or the debug symbols could not be read.
|
||||
@defvar RecordInstruction.is_speculative
|
||||
A boolean indicating whether the instruction was executed speculatively.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceInstruction.data
|
||||
A buffer with the raw instruction data. May be @code{None} if the
|
||||
instruction is a gap. In Python 3, the return value is a @code{memoryview}
|
||||
object.
|
||||
If an error occured during recording or decoding a recording, this error is
|
||||
represented by a @code{gdb.RecordGap} object in the instruction list. It has
|
||||
the following attributes:
|
||||
|
||||
@defvar RecordGap.number
|
||||
An integer identifying this gap. @code{number} corresponds to the numbers seen
|
||||
in @code{record instruction-history} (@pxref{Process Record and Replay}).
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceInstruction.decoded
|
||||
A human readable string with the disassembled instruction. Contains the
|
||||
error message for gaps.
|
||||
@defvar RecordGap.error_code
|
||||
A numerical representation of the reason for the gap. The value is specific to
|
||||
the current recording method.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceInstruction.size
|
||||
The size of the instruction in bytes. Will be @code{None} if the
|
||||
instruction is a gap.
|
||||
@defvar RecordGap.error_string
|
||||
A human readable string with the reason for the gap.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceInstruction.is_speculative
|
||||
A boolean indicating whether the instruction was executed
|
||||
speculatively. Will be @code{None} for gaps.
|
||||
@end defvar
|
||||
A @code{gdb.RecordFunctionSegment} object has the following attributes:
|
||||
|
||||
The attributes and methods of function call objects depend on the
|
||||
current recording format. Currently, only btrace function calls are
|
||||
supported.
|
||||
|
||||
A @code{gdb.BtraceFunctionCall} object has the following attributes:
|
||||
|
||||
@defvar BtraceFunctionCall.number
|
||||
An integer identifying this function call. @var{number} corresponds to
|
||||
@defvar RecordFunctionSegment.number
|
||||
An integer identifying this function segment. @code{number} corresponds to
|
||||
the numbers seen in @code{record function-call-history}
|
||||
(@pxref{Process Record and Replay}).
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceFunctionCall.symbol
|
||||
@defvar RecordFunctionSegment.symbol
|
||||
A @code{gdb.Symbol} object representing the associated symbol. May be
|
||||
@code{None} if the function call is a gap or the debug symbols could
|
||||
not be read.
|
||||
@code{None} if no debug information is available.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceFunctionCall.level
|
||||
@defvar RecordFunctionSegment.level
|
||||
An integer representing the function call's stack level. May be
|
||||
@code{None} if the function call is a gap.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceFunctionCall.instructions
|
||||
A list of @code{gdb.BtraceInstruction} objects associated with this function
|
||||
call.
|
||||
@defvar RecordFunctionSegment.instructions
|
||||
A list of @code{gdb.RecordInstruction} or @code{gdb.RecordGap} objects
|
||||
associated with this function call.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceFunctionCall.up
|
||||
A @code{gdb.BtraceFunctionCall} object representing the caller's
|
||||
@defvar RecordFunctionSegment.up
|
||||
A @code{gdb.RecordFunctionSegment} object representing the caller's
|
||||
function segment. If the call has not been recorded, this will be the
|
||||
function segment to which control returns. If neither the call nor the
|
||||
return have been recorded, this will be @code{None}.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceFunctionCall.prev_sibling
|
||||
A @code{gdb.BtraceFunctionCall} object representing the previous
|
||||
@defvar RecordFunctionSegment.prev
|
||||
A @code{gdb.RecordFunctionSegment} object representing the previous
|
||||
segment of this function call. May be @code{None}.
|
||||
@end defvar
|
||||
|
||||
@defvar BtraceFunctionCall.next_sibling
|
||||
A @code{gdb.BtraceFunctionCall} object representing the next segment of
|
||||
@defvar RecordFunctionSegment.next
|
||||
A @code{gdb.RecordFunctionSegment} object representing the next segment of
|
||||
this function call. May be @code{None}.
|
||||
@end defvar
|
||||
|
||||
|
||||
@@ -653,38 +653,6 @@ fbsd_next_vfork_done (void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int
|
||||
resume_one_thread_cb (struct thread_info *tp, void *data)
|
||||
{
|
||||
ptid_t *ptid = (ptid_t *) data;
|
||||
int request;
|
||||
|
||||
if (ptid_get_pid (tp->ptid) != ptid_get_pid (*ptid))
|
||||
return 0;
|
||||
|
||||
if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (*ptid))
|
||||
request = PT_RESUME;
|
||||
else
|
||||
request = PT_SUSPEND;
|
||||
|
||||
if (ptrace (request, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
|
||||
perror_with_name (("ptrace"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
resume_all_threads_cb (struct thread_info *tp, void *data)
|
||||
{
|
||||
ptid_t *filter = (ptid_t *) data;
|
||||
|
||||
if (!ptid_match (tp->ptid, *filter))
|
||||
return 0;
|
||||
|
||||
if (ptrace (PT_RESUME, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
|
||||
perror_with_name (("ptrace"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Implement the "to_resume" target_ops method. */
|
||||
|
||||
static void
|
||||
@@ -711,13 +679,37 @@ fbsd_resume (struct target_ops *ops,
|
||||
if (ptid_lwp_p (ptid))
|
||||
{
|
||||
/* If ptid is a specific LWP, suspend all other LWPs in the process. */
|
||||
iterate_over_threads (resume_one_thread_cb, &ptid);
|
||||
struct thread_info *tp;
|
||||
int request;
|
||||
|
||||
ALL_NON_EXITED_THREADS (tp)
|
||||
{
|
||||
if (ptid_get_pid (tp->ptid) != ptid_get_pid (ptid))
|
||||
continue;
|
||||
|
||||
if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (ptid))
|
||||
request = PT_RESUME;
|
||||
else
|
||||
request = PT_SUSPEND;
|
||||
|
||||
if (ptrace (request, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
|
||||
perror_with_name (("ptrace"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If ptid is a wildcard, resume all matching threads (they won't run
|
||||
until the process is continued however). */
|
||||
iterate_over_threads (resume_all_threads_cb, &ptid);
|
||||
struct thread_info *tp;
|
||||
|
||||
ALL_NON_EXITED_THREADS (tp)
|
||||
{
|
||||
if (!ptid_match (tp->ptid, ptid))
|
||||
continue;
|
||||
|
||||
if (ptrace (PT_RESUME, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
|
||||
perror_with_name (("ptrace"));
|
||||
}
|
||||
ptid = inferior_ptid;
|
||||
}
|
||||
super_resume (ops, ptid, step, signo);
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
#undef KEY_EVENT
|
||||
#endif
|
||||
|
||||
/* On Solaris and probably other SysVr4 derived systems, we need to define
|
||||
NOMACROS so the native <curses.h> doesn't define clear which interferes
|
||||
with the clear member of class string_file. ncurses potentially has a
|
||||
similar problem and fix. */
|
||||
#define NOMACROS
|
||||
#define NCURSES_NOMACROS
|
||||
|
||||
#if defined (HAVE_NCURSES_NCURSES_H)
|
||||
#include <ncurses/ncurses.h>
|
||||
#elif defined (HAVE_NCURSES_H)
|
||||
|
||||
106
gdb/gdbtypes.c
106
gdb/gdbtypes.c
@@ -51,6 +51,7 @@ const struct rank EXACT_MATCH_BADNESS = {0,0};
|
||||
const struct rank INTEGER_PROMOTION_BADNESS = {1,0};
|
||||
const struct rank FLOAT_PROMOTION_BADNESS = {1,0};
|
||||
const struct rank BASE_PTR_CONVERSION_BADNESS = {1,0};
|
||||
const struct rank CV_CONVERSION_BADNESS = {1, 0};
|
||||
const struct rank INTEGER_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank FLOAT_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank INT_FLOAT_CONVERSION_BADNESS = {2,0};
|
||||
@@ -58,8 +59,6 @@ const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank BOOL_CONVERSION_BADNESS = {3,0};
|
||||
const struct rank BASE_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS = {5,0};
|
||||
const struct rank DIFFERENT_REFERENCE_TYPE_BADNESS = {6,0};
|
||||
const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
|
||||
const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
|
||||
const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
|
||||
@@ -3619,57 +3618,51 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
|
||||
if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
|
||||
arg = check_typedef (arg);
|
||||
|
||||
if (value != NULL)
|
||||
if (TYPE_IS_REFERENCE (parm) && value != NULL)
|
||||
{
|
||||
/* An rvalue argument cannot be bound to a non-const lvalue
|
||||
reference parameter... */
|
||||
if (VALUE_LVAL (value) == not_lval
|
||||
&& TYPE_CODE (parm) == TYPE_CODE_REF
|
||||
&& !TYPE_CONST (parm->main_type->target_type))
|
||||
return INCOMPATIBLE_TYPE_BADNESS;
|
||||
|
||||
/* ... and an lvalue argument cannot be bound to an rvalue
|
||||
reference parameter. [C++ 13.3.3.1.4p3] */
|
||||
if (VALUE_LVAL (value) != not_lval
|
||||
&& TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
|
||||
return INCOMPATIBLE_TYPE_BADNESS;
|
||||
if (VALUE_LVAL (value) == not_lval)
|
||||
{
|
||||
/* Rvalues should preferably bind to rvalue references or const
|
||||
lvalue references. */
|
||||
if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
|
||||
rank.subrank = REFERENCE_CONVERSION_RVALUE;
|
||||
else if (TYPE_CONST (TYPE_TARGET_TYPE (parm)))
|
||||
rank.subrank = REFERENCE_CONVERSION_CONST_LVALUE;
|
||||
else
|
||||
return INCOMPATIBLE_TYPE_BADNESS;
|
||||
return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lvalues should prefer lvalue overloads. */
|
||||
if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
|
||||
{
|
||||
rank.subrank = REFERENCE_CONVERSION_RVALUE;
|
||||
return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (types_equal (parm, arg))
|
||||
return EXACT_MATCH_BADNESS;
|
||||
|
||||
/* An lvalue reference to a function should get higher priority than an
|
||||
rvalue reference to a function. */
|
||||
|
||||
if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF
|
||||
&& TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC)
|
||||
{
|
||||
return (sum_ranks (rank_one_type (parm,
|
||||
lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL),
|
||||
DIFFERENT_REFERENCE_TYPE_BADNESS));
|
||||
}
|
||||
struct type *t1 = parm;
|
||||
struct type *t2 = arg;
|
||||
|
||||
/* If a conversion to one type of reference is an identity conversion, and a
|
||||
conversion to the second type of reference is a non-identity conversion,
|
||||
choose the first type. */
|
||||
/* For pointers and references, compare target type. */
|
||||
if (TYPE_CODE (parm) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (parm))
|
||||
{
|
||||
t1 = TYPE_TARGET_TYPE (parm);
|
||||
t2 = TYPE_TARGET_TYPE (arg);
|
||||
}
|
||||
|
||||
if (value != NULL && TYPE_IS_REFERENCE (parm) && TYPE_IS_REFERENCE (arg)
|
||||
&& TYPE_CODE (parm) != TYPE_CODE (arg))
|
||||
{
|
||||
return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm),
|
||||
TYPE_TARGET_TYPE (arg), NULL), DIFFERENT_REFERENCE_TYPE_BADNESS));
|
||||
}
|
||||
|
||||
/* An rvalue should be first tried to bind to an rvalue reference, and then to
|
||||
an lvalue reference. */
|
||||
|
||||
if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF
|
||||
&& VALUE_LVAL (value) == not_lval)
|
||||
{
|
||||
if (TYPE_IS_REFERENCE (arg))
|
||||
arg = TYPE_TARGET_TYPE (arg);
|
||||
return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
|
||||
LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS));
|
||||
/* Make sure they are CV equal, too. */
|
||||
if (TYPE_CONST (t1) != TYPE_CONST (t2))
|
||||
rank.subrank |= CV_CONVERSION_CONST;
|
||||
if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
|
||||
rank.subrank |= CV_CONVERSION_VOLATILE;
|
||||
if (rank.subrank != 0)
|
||||
return sum_ranks (CV_CONVERSION_BADNESS, rank);
|
||||
return EXACT_MATCH_BADNESS;
|
||||
}
|
||||
|
||||
/* See through references, since we can almost make non-references
|
||||
@@ -3711,10 +3704,23 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
|
||||
|
||||
return INCOMPATIBLE_TYPE_BADNESS;
|
||||
case TYPE_CODE_ARRAY:
|
||||
if (types_equal (TYPE_TARGET_TYPE (parm),
|
||||
TYPE_TARGET_TYPE (arg)))
|
||||
return EXACT_MATCH_BADNESS;
|
||||
return INCOMPATIBLE_TYPE_BADNESS;
|
||||
{
|
||||
struct type *t1 = TYPE_TARGET_TYPE (parm);
|
||||
struct type *t2 = TYPE_TARGET_TYPE (arg);
|
||||
|
||||
if (types_equal (t1, t2))
|
||||
{
|
||||
/* Make sure they are CV equal. */
|
||||
if (TYPE_CONST (t1) != TYPE_CONST (t2))
|
||||
rank.subrank |= CV_CONVERSION_CONST;
|
||||
if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
|
||||
rank.subrank |= CV_CONVERSION_VOLATILE;
|
||||
if (rank.subrank != 0)
|
||||
return sum_ranks (CV_CONVERSION_BADNESS, rank);
|
||||
return EXACT_MATCH_BADNESS;
|
||||
}
|
||||
return INCOMPATIBLE_TYPE_BADNESS;
|
||||
}
|
||||
case TYPE_CODE_FUNC:
|
||||
return rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL);
|
||||
case TYPE_CODE_INT:
|
||||
|
||||
@@ -1891,10 +1891,21 @@ extern const struct rank VOID_PTR_CONVERSION_BADNESS;
|
||||
extern const struct rank BOOL_CONVERSION_BADNESS;
|
||||
/* * Badness of converting derived to base class. */
|
||||
extern const struct rank BASE_CONVERSION_BADNESS;
|
||||
/* * Badness of converting from non-reference to reference. */
|
||||
/* * Badness of converting from non-reference to reference. Subrank
|
||||
is the type of reference conversion being done. */
|
||||
extern const struct rank REFERENCE_CONVERSION_BADNESS;
|
||||
/* * Conversion to rvalue reference. */
|
||||
#define REFERENCE_CONVERSION_RVALUE 1
|
||||
/* * Conversion to const lvalue reference. */
|
||||
#define REFERENCE_CONVERSION_CONST_LVALUE 2
|
||||
|
||||
/* * Badness of converting integer 0 to NULL pointer. */
|
||||
extern const struct rank NULL_POINTER_CONVERSION;
|
||||
/* * Badness of cv-conversion. Subrank is a flag describing the conversions
|
||||
being done. */
|
||||
extern const struct rank CV_CONVERSION_BADNESS;
|
||||
#define CV_CONVERSION_CONST 1
|
||||
#define CV_CONVERSION_VOLATILE 2
|
||||
|
||||
/* Non-standard conversions allowed by the debugger */
|
||||
|
||||
|
||||
@@ -3229,7 +3229,10 @@ is restored."),
|
||||
set_inferior_tty_command,
|
||||
show_inferior_tty_command,
|
||||
&setlist, &showlist);
|
||||
add_com_alias ("tty", "set inferior-tty", class_alias, 0);
|
||||
cmd_name = "inferior-tty";
|
||||
c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
|
||||
gdb_assert (c != NULL);
|
||||
add_alias_cmd ("tty", c, class_alias, 0, &cmdlist);
|
||||
|
||||
cmd_name = "args";
|
||||
add_setshow_string_noescape_cmd (cmd_name, class_run,
|
||||
|
||||
@@ -624,14 +624,13 @@ write_watchpoint_regs (void)
|
||||
static void
|
||||
mips_linux_new_thread (struct lwp_info *lp)
|
||||
{
|
||||
int tid;
|
||||
long tid = lp->ptid.lwp ();
|
||||
|
||||
if (!mips_linux_read_watch_registers (ptid_get_lwp (inferior_ptid),
|
||||
if (!mips_linux_read_watch_registers (tid,
|
||||
&watch_readback,
|
||||
&watch_readback_valid, 0))
|
||||
return;
|
||||
|
||||
tid = ptid_get_lwp (lp->ptid);
|
||||
if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror, NULL) == -1)
|
||||
perror_with_name (_("Couldn't write debug register"));
|
||||
}
|
||||
|
||||
@@ -122,8 +122,8 @@ static void procfs_pass_signals (struct target_ops *self,
|
||||
int, unsigned char *);
|
||||
static void procfs_kill_inferior (struct target_ops *ops);
|
||||
static void procfs_mourn_inferior (struct target_ops *ops);
|
||||
static void procfs_create_inferior (struct target_ops *, char *,
|
||||
char *, char **, int);
|
||||
static void procfs_create_inferior (struct target_ops *, const char *,
|
||||
const std::string &, char **, int);
|
||||
static ptid_t procfs_wait (struct target_ops *,
|
||||
ptid_t, struct target_waitstatus *, int);
|
||||
static enum target_xfer_status procfs_xfer_memory (gdb_byte *,
|
||||
|
||||
@@ -223,11 +223,14 @@ inferior_to_inferior_object (struct inferior *inferior)
|
||||
inf_obj->threads = NULL;
|
||||
inf_obj->nthreads = 0;
|
||||
|
||||
/* PyObject_New initializes the new object with a refcount of 1. This
|
||||
counts for the reference we are keeping in the inferior data. */
|
||||
set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
|
||||
|
||||
}
|
||||
else
|
||||
Py_INCREF ((PyObject *)inf_obj);
|
||||
|
||||
/* We are returning a new reference. */
|
||||
Py_INCREF ((PyObject *)inf_obj);
|
||||
|
||||
return (PyObject *) inf_obj;
|
||||
}
|
||||
|
||||
67
gdb/python/py-instruction.c
Normal file
67
gdb/python/py-instruction.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/* Python interface to instruction objects.
|
||||
|
||||
Copyright 2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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 "defs.h"
|
||||
#include "py-instruction.h"
|
||||
|
||||
/* See py-instruction.h. */
|
||||
|
||||
PyTypeObject py_insn_type = {
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
};
|
||||
|
||||
/* Python instruction object. */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
} py_insn_obj;
|
||||
|
||||
/* Getter function for gdb.Instruction attributes. */
|
||||
|
||||
static PyObject *
|
||||
py_insn_getter (PyObject *self, void *closure)
|
||||
{
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Instruction members. */
|
||||
|
||||
static gdb_PyGetSetDef py_insn_getset[] =
|
||||
{
|
||||
{ "pc", py_insn_getter, NULL, "instruction address", NULL},
|
||||
{ "data", py_insn_getter, NULL, "instruction memory", NULL},
|
||||
{ "decoded", py_insn_getter, NULL, "decoded instruction", NULL},
|
||||
{ "size", py_insn_getter, NULL, "instruction size in bytes", NULL},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* Sets up the gdb.Instruction type. */
|
||||
|
||||
int
|
||||
gdbpy_initialize_instruction (void)
|
||||
{
|
||||
py_insn_type.tp_new = PyType_GenericNew;
|
||||
py_insn_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
py_insn_type.tp_basicsize = sizeof (py_insn_obj);
|
||||
py_insn_type.tp_name = "gdb.Instruction";
|
||||
py_insn_type.tp_doc = "GDB instruction object";
|
||||
py_insn_type.tp_getset = py_insn_getset;
|
||||
|
||||
return PyType_Ready (&py_insn_type);
|
||||
}
|
||||
30
gdb/python/py-instruction.h
Normal file
30
gdb/python/py-instruction.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Python interface to instruction objects.
|
||||
|
||||
Copyright 2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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/>. */
|
||||
|
||||
#ifndef GDB_PY_INSTRUCTION_H
|
||||
#define GDB_PY_INSTRUCTION_H
|
||||
|
||||
#include "python-internal.h"
|
||||
|
||||
/* Python type object for the abstract gdb.Instruction class. This class
|
||||
contains getters for four elements: "pc" (int), "data" (buffer), "decode"
|
||||
(str) and "size" (int) that must be overriden by sub classes. */
|
||||
extern PyTypeObject py_insn_type;
|
||||
|
||||
#endif /* GDB_PY_INSTRUCTION_H */
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "gdbcmd.h"
|
||||
#include "gdbthread.h"
|
||||
#include "btrace.h"
|
||||
#include "py-record.h"
|
||||
#include "py-record-btrace.h"
|
||||
#include "disasm.h"
|
||||
|
||||
@@ -35,40 +36,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
#define BTPY_REQUIRE_VALID_INSN(obj, iter) \
|
||||
do { \
|
||||
struct thread_info *tinfo = find_thread_ptid (obj->ptid); \
|
||||
if (tinfo == NULL || btrace_is_empty (tinfo)) \
|
||||
return PyErr_Format (gdbpy_gdb_error, _("Empty branch trace."));\
|
||||
if (0 == btrace_find_insn_by_number (&iter, &tinfo->btrace, \
|
||||
obj->number)) \
|
||||
return PyErr_Format (gdbpy_gdb_error, _("No such instruction."));\
|
||||
} while (0)
|
||||
|
||||
#define BTPY_REQUIRE_VALID_CALL(obj, iter) \
|
||||
do { \
|
||||
struct thread_info *tinfo = find_thread_ptid (obj->ptid); \
|
||||
if (tinfo == NULL || btrace_is_empty (tinfo)) \
|
||||
return PyErr_Format (gdbpy_gdb_error, _("Empty branch trace."));\
|
||||
if (0 == btrace_find_call_by_number (&iter, &tinfo->btrace, \
|
||||
obj->number)) \
|
||||
return PyErr_Format (gdbpy_gdb_error, _("No such call segment."));\
|
||||
} while (0)
|
||||
|
||||
/* This can either be a btrace instruction or a function call segment,
|
||||
depending on the chosen type. */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
/* The thread this object belongs to. */
|
||||
ptid_t ptid;
|
||||
|
||||
/* Instruction number or function call segment number, depending on the type
|
||||
of this object. */
|
||||
Py_ssize_t number;
|
||||
} btpy_object;
|
||||
|
||||
/* Python object for btrace record lists. */
|
||||
|
||||
typedef struct {
|
||||
@@ -86,59 +53,125 @@ typedef struct {
|
||||
/* Stride size. */
|
||||
Py_ssize_t step;
|
||||
|
||||
/* Either &BTPY_CALL_TYPE or &BTPY_INSN_TYPE. */
|
||||
/* Either &BTPY_CALL_TYPE or &RECPY_INSN_TYPE. */
|
||||
PyTypeObject* element_type;
|
||||
} btpy_list_object;
|
||||
|
||||
/* Python type for btrace instructions. */
|
||||
|
||||
static PyTypeObject btpy_insn_type = {
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
};
|
||||
|
||||
/* Python type for btrace function-calls. */
|
||||
|
||||
static PyTypeObject btpy_call_type = {
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
};
|
||||
|
||||
/* Python type for btrace lists. */
|
||||
|
||||
static PyTypeObject btpy_list_type = {
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
};
|
||||
|
||||
/* Create a new gdb.BtraceInstruction or gdb.BtraceFunctionCall object,
|
||||
depending on TYPE. */
|
||||
/* Returns either a btrace_insn for the given Python gdb.RecordInstruction
|
||||
object or sets an appropriate Python exception and returns NULL. */
|
||||
|
||||
static PyObject *
|
||||
btpy_new (ptid_t ptid, Py_ssize_t number, PyTypeObject* type)
|
||||
static const btrace_insn *
|
||||
btrace_insn_from_recpy_insn (const PyObject * const pyobject)
|
||||
{
|
||||
btpy_object * const obj = PyObject_New (btpy_object, type);
|
||||
const btrace_insn *insn;
|
||||
const recpy_element_object *obj;
|
||||
thread_info *tinfo;
|
||||
btrace_insn_iterator iter;
|
||||
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
if (Py_TYPE (pyobject) != &recpy_insn_type)
|
||||
{
|
||||
PyErr_Format (gdbpy_gdb_error, _("Must be gdb.RecordInstruction"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj->ptid = ptid;
|
||||
obj->number = number;
|
||||
obj = (const recpy_element_object *) pyobject;
|
||||
tinfo = find_thread_ptid (obj->ptid);
|
||||
|
||||
return (PyObject *) obj;
|
||||
if (tinfo == NULL || btrace_is_empty (tinfo))
|
||||
{
|
||||
PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (btrace_find_insn_by_number (&iter, &tinfo->btrace, obj->number) == 0)
|
||||
{
|
||||
PyErr_Format (gdbpy_gdb_error, _("No such instruction."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
insn = btrace_insn_get (&iter);
|
||||
if (insn == NULL)
|
||||
{
|
||||
PyErr_Format (gdbpy_gdb_error, _("Not a valid instruction."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return insn;
|
||||
}
|
||||
|
||||
/* Create a new gdb.BtraceInstruction object. */
|
||||
/* Returns either a btrace_function for the given Python
|
||||
gdb.RecordFunctionSegment object or sets an appropriate Python exception and
|
||||
returns NULL. */
|
||||
|
||||
static PyObject *
|
||||
btpy_insn_new (ptid_t ptid, Py_ssize_t number)
|
||||
static const btrace_function *
|
||||
btrace_func_from_recpy_func (const PyObject * const pyobject)
|
||||
{
|
||||
return btpy_new (ptid, number, &btpy_insn_type);
|
||||
const btrace_function *func;
|
||||
const recpy_element_object *obj;
|
||||
thread_info *tinfo;
|
||||
btrace_call_iterator iter;
|
||||
|
||||
if (Py_TYPE (pyobject) != &recpy_func_type)
|
||||
{
|
||||
PyErr_Format (gdbpy_gdb_error, _("Must be gdb.RecordFunctionSegment"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = (const recpy_element_object *) pyobject;
|
||||
tinfo = find_thread_ptid (obj->ptid);
|
||||
|
||||
if (tinfo == NULL || btrace_is_empty (tinfo))
|
||||
{
|
||||
PyErr_Format (gdbpy_gdb_error, _("No such function segment."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (btrace_find_call_by_number (&iter, &tinfo->btrace, obj->number) == 0)
|
||||
{
|
||||
PyErr_Format (gdbpy_gdb_error, _("No such function segment."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
func = btrace_call_get (&iter);
|
||||
if (func == NULL)
|
||||
{
|
||||
PyErr_Format (gdbpy_gdb_error, _("Not a valid function segment."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/* Create a new gdb.BtraceFunctionCall object. */
|
||||
/* Looks at the recorded item with the number NUMBER and create a
|
||||
gdb.RecordInstruction or gdb.RecordGap object for it accordingly. */
|
||||
|
||||
static PyObject *
|
||||
btpy_call_new (ptid_t ptid, Py_ssize_t number)
|
||||
btpy_insn_or_gap_new (const thread_info *tinfo, Py_ssize_t number)
|
||||
{
|
||||
return btpy_new (ptid, number, &btpy_call_type);
|
||||
btrace_insn_iterator iter;
|
||||
int err_code;
|
||||
|
||||
btrace_find_insn_by_number (&iter, &tinfo->btrace, number);
|
||||
err_code = btrace_insn_get_error (&iter);
|
||||
|
||||
if (err_code != 0)
|
||||
{
|
||||
const btrace_config *config;
|
||||
const char *err_string;
|
||||
|
||||
config = btrace_conf (&tinfo->btrace);
|
||||
err_string = btrace_decode_error (config->format, err_code);
|
||||
|
||||
return recpy_gap_new (err_code, err_string, number);
|
||||
}
|
||||
|
||||
return recpy_insn_new (tinfo->ptid, RECORD_METHOD_BTRACE, number);
|
||||
}
|
||||
|
||||
/* Create a new gdb.BtraceList object. */
|
||||
@@ -162,64 +195,17 @@ btpy_list_new (ptid_t ptid, Py_ssize_t first, Py_ssize_t last, Py_ssize_t step,
|
||||
return (PyObject *) obj;
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.number [int] and
|
||||
BtraceFunctionCall.number [int]. */
|
||||
/* Implementation of RecordInstruction.sal [gdb.Symtab_and_line] for btrace.
|
||||
Returns the SAL associated with this instruction. */
|
||||
|
||||
static PyObject *
|
||||
btpy_number (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_insn_sal (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
|
||||
return PyInt_FromSsize_t (obj->number);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.__hash__ () -> int and
|
||||
BtraceFunctionCall.__hash__ () -> int. */
|
||||
|
||||
static Py_hash_t
|
||||
btpy_hash (PyObject *self)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
|
||||
return obj->number;
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.error [int]. Returns the
|
||||
error code for gaps. */
|
||||
|
||||
static PyObject *
|
||||
btpy_insn_error (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
struct btrace_insn_iterator iter;
|
||||
int error;
|
||||
|
||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
||||
|
||||
error = btrace_insn_get_error (&iter);
|
||||
|
||||
if (error == 0)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
return PyInt_FromLong (error);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.sal [gdb.Symtab_and_line].
|
||||
Return the SAL associated with this instruction. */
|
||||
|
||||
static PyObject *
|
||||
btpy_insn_sal (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_insn *insn;
|
||||
struct btrace_insn_iterator iter;
|
||||
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||
PyObject *result = NULL;
|
||||
|
||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
||||
|
||||
insn = btrace_insn_get (&iter);
|
||||
if (insn == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
TRY
|
||||
{
|
||||
@@ -234,59 +220,44 @@ btpy_insn_sal (PyObject *self, void *closure)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.pc [int]. Returns
|
||||
the instruction address. */
|
||||
/* Implementation of RecordInstruction.pc [int] for btrace.
|
||||
Returns the instruction address. */
|
||||
|
||||
static PyObject *
|
||||
btpy_insn_pc (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_insn_pc (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_insn *insn;
|
||||
struct btrace_insn_iterator iter;
|
||||
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||
|
||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
||||
|
||||
insn = btrace_insn_get (&iter);
|
||||
if (insn == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
return gdb_py_long_from_ulongest (insn->pc);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.size [int]. Returns
|
||||
the instruction size. */
|
||||
/* Implementation of RecordInstruction.size [int] for btrace.
|
||||
Returns the instruction size. */
|
||||
|
||||
static PyObject *
|
||||
btpy_insn_size (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_insn_size (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_insn *insn;
|
||||
struct btrace_insn_iterator iter;
|
||||
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||
|
||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
||||
|
||||
insn = btrace_insn_get (&iter);
|
||||
if (insn == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
return PyInt_FromLong (insn->size);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.is_speculative [bool].
|
||||
/* Implementation of RecordInstruction.is_speculative [bool] for btrace.
|
||||
Returns if this instruction was executed speculatively. */
|
||||
|
||||
static PyObject *
|
||||
btpy_insn_is_speculative (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_insn_is_speculative (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_insn *insn;
|
||||
struct btrace_insn_iterator iter;
|
||||
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||
|
||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
||||
|
||||
insn = btrace_insn_get (&iter);
|
||||
if (insn == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
if (insn->flags & BTRACE_INSN_FLAG_SPECULATIVE)
|
||||
Py_RETURN_TRUE;
|
||||
@@ -294,23 +265,18 @@ btpy_insn_is_speculative (PyObject *self, void *closure)
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.data [buffer].
|
||||
/* Implementation of RecordInstruction.data [buffer] for btrace.
|
||||
Returns raw instruction data. */
|
||||
|
||||
static PyObject *
|
||||
btpy_insn_data (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_insn_data (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_insn *insn;
|
||||
struct btrace_insn_iterator iter;
|
||||
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||
gdb_byte *buffer = NULL;
|
||||
PyObject *object;
|
||||
|
||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
||||
|
||||
insn = btrace_insn_get (&iter);
|
||||
if (insn == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
TRY
|
||||
{
|
||||
@@ -338,29 +304,17 @@ btpy_insn_data (PyObject *self, void *closure)
|
||||
|
||||
}
|
||||
|
||||
/* Implementation of BtraceInstruction.decode [str]. Returns
|
||||
the instruction as human readable string. */
|
||||
/* Implementation of RecordInstruction.decoded [str] for btrace.
|
||||
Returns the instruction as human readable string. */
|
||||
|
||||
static PyObject *
|
||||
btpy_insn_decode (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_insn_decoded (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_insn *insn;
|
||||
struct btrace_insn_iterator iter;
|
||||
const btrace_insn * const insn = btrace_insn_from_recpy_insn (self);
|
||||
string_file strfile;
|
||||
|
||||
BTPY_REQUIRE_VALID_INSN (obj, iter);
|
||||
|
||||
insn = btrace_insn_get (&iter);
|
||||
if (insn == NULL)
|
||||
{
|
||||
int error_code = btrace_insn_get_error (&iter);
|
||||
const struct btrace_config *config;
|
||||
|
||||
config = btrace_conf (&find_thread_ptid (obj->ptid)->btrace);
|
||||
return PyBytes_FromString (btrace_decode_error (config->format,
|
||||
error_code));
|
||||
}
|
||||
return NULL;
|
||||
|
||||
TRY
|
||||
{
|
||||
@@ -377,40 +331,32 @@ btpy_insn_decode (PyObject *self, void *closure)
|
||||
return PyBytes_FromString (strfile.string ().c_str ());
|
||||
}
|
||||
|
||||
/* Implementation of BtraceFunctionCall.level [int]. Returns the
|
||||
call level. */
|
||||
/* Implementation of RecordFunctionSegment.level [int] for btrace.
|
||||
Returns the call level. */
|
||||
|
||||
static PyObject *
|
||||
btpy_call_level (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_func_level (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_function *func;
|
||||
struct btrace_call_iterator iter;
|
||||
const btrace_function * const func = btrace_func_from_recpy_func (self);
|
||||
thread_info *tinfo;
|
||||
|
||||
BTPY_REQUIRE_VALID_CALL (obj, iter);
|
||||
|
||||
func = btrace_call_get (&iter);
|
||||
if (func == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
return PyInt_FromLong (iter.btinfo->level + func->level);
|
||||
tinfo = find_thread_ptid (((recpy_element_object *) self)->ptid);
|
||||
return PyInt_FromLong (tinfo->btrace.level + func->level);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceFunctionCall.symbol [gdb.Symbol]. Returns
|
||||
the symbol associated with this function call. */
|
||||
/* Implementation of RecordFunctionSegment.symbol [gdb.Symbol] for btrace.
|
||||
Returns the symbol associated with this function call. */
|
||||
|
||||
static PyObject *
|
||||
btpy_call_symbol (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_func_symbol (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_function *func;
|
||||
struct btrace_call_iterator iter;
|
||||
const btrace_function * const func = btrace_func_from_recpy_func (self);
|
||||
|
||||
BTPY_REQUIRE_VALID_CALL (obj, iter);
|
||||
|
||||
func = btrace_call_get (&iter);
|
||||
if (func == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
if (func->sym == NULL)
|
||||
Py_RETURN_NONE;
|
||||
@@ -418,22 +364,17 @@ btpy_call_symbol (PyObject *self, void *closure)
|
||||
return symbol_to_symbol_object (func->sym);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceFunctionCall.instructions [list].
|
||||
Return the list of instructions that belong to this function call. */
|
||||
/* Implementation of RecordFunctionSegment.instructions [list] for btrace.
|
||||
Returns the list of instructions that belong to this function call. */
|
||||
|
||||
static PyObject *
|
||||
btpy_call_instructions (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_func_instructions (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_function *func;
|
||||
struct btrace_call_iterator iter;
|
||||
const btrace_function * const func = btrace_func_from_recpy_func (self);
|
||||
unsigned int len;
|
||||
|
||||
BTPY_REQUIRE_VALID_CALL (obj, iter);
|
||||
|
||||
func = btrace_call_get (&iter);
|
||||
if (func == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
len = VEC_length (btrace_insn_s, func->insn);
|
||||
|
||||
@@ -441,111 +382,63 @@ btpy_call_instructions (PyObject *self, void *closure)
|
||||
if (len == 0)
|
||||
len = 1;
|
||||
|
||||
return btpy_list_new (obj->ptid, func->insn_offset, func->insn_offset + len,
|
||||
1, &btpy_insn_type);
|
||||
return btpy_list_new (((recpy_element_object *) self)->ptid,
|
||||
func->insn_offset, func->insn_offset + len, 1,
|
||||
&recpy_insn_type);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceFunctionCall.up [gdb.BtraceRecordCall].
|
||||
Return the caller / returnee of this function. */
|
||||
/* Implementation of RecordFunctionSegment.up [RecordFunctionSegment] for
|
||||
btrace. Returns the caller / returnee of this function. */
|
||||
|
||||
static PyObject *
|
||||
btpy_call_up (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_func_up (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_function *func;
|
||||
struct btrace_call_iterator iter;
|
||||
const btrace_function * const func = btrace_func_from_recpy_func (self);
|
||||
|
||||
BTPY_REQUIRE_VALID_CALL (obj, iter);
|
||||
|
||||
func = btrace_call_get (&iter);
|
||||
if (func == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
if (func->up == NULL)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
return btpy_call_new (obj->ptid, func->up->number);
|
||||
return recpy_func_new (((recpy_element_object *) self)->ptid,
|
||||
RECORD_METHOD_BTRACE, func->up->number);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceFunctionCall.prev_sibling [BtraceFunctionCall].
|
||||
Return a previous segment of this function. */
|
||||
/* Implementation of RecordFunctionSegment.prev [RecordFunctionSegment] for
|
||||
btrace. Returns a previous segment of this function. */
|
||||
|
||||
static PyObject *
|
||||
btpy_call_prev_sibling (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_func_prev (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_function *func;
|
||||
struct btrace_call_iterator iter;
|
||||
const btrace_function * const func = btrace_func_from_recpy_func (self);
|
||||
|
||||
BTPY_REQUIRE_VALID_CALL (obj, iter);
|
||||
|
||||
func = btrace_call_get (&iter);
|
||||
if (func == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
if (func->segment.prev == NULL)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
return btpy_call_new (obj->ptid, func->segment.prev->number);
|
||||
return recpy_func_new (((recpy_element_object *) self)->ptid,
|
||||
RECORD_METHOD_BTRACE, func->segment.prev->number);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceFunctionCall.next_sibling [BtraceFunctionCall].
|
||||
Return a following segment of this function. */
|
||||
/* Implementation of RecordFunctionSegment.next [RecordFunctionSegment] for
|
||||
btrace. Returns a following segment of this function. */
|
||||
|
||||
static PyObject *
|
||||
btpy_call_next_sibling (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_func_next (PyObject *self, void *closure)
|
||||
{
|
||||
const btpy_object * const obj = (btpy_object *) self;
|
||||
const struct btrace_function *func;
|
||||
struct btrace_call_iterator iter;
|
||||
const btrace_function * const func = btrace_func_from_recpy_func (self);
|
||||
|
||||
BTPY_REQUIRE_VALID_CALL (obj, iter);
|
||||
|
||||
func = btrace_call_get (&iter);
|
||||
if (func == NULL)
|
||||
Py_RETURN_NONE;
|
||||
return NULL;
|
||||
|
||||
if (func->segment.next == NULL)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
return btpy_call_new (obj->ptid, func->segment.next->number);
|
||||
}
|
||||
|
||||
/* Python rich compare function to allow for equality and inequality checks
|
||||
in Python. */
|
||||
|
||||
static PyObject *
|
||||
btpy_richcompare (PyObject *self, PyObject *other, int op)
|
||||
{
|
||||
const btpy_object * const obj1 = (btpy_object *) self;
|
||||
const btpy_object * const obj2 = (btpy_object *) other;
|
||||
|
||||
if (Py_TYPE (self) != Py_TYPE (other))
|
||||
{
|
||||
Py_INCREF (Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case Py_EQ:
|
||||
if (ptid_equal (obj1->ptid, obj2->ptid) && obj1->number == obj2->number)
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
|
||||
case Py_NE:
|
||||
if (!ptid_equal (obj1->ptid, obj2->ptid) || obj1->number != obj2->number)
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Py_INCREF (Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
return recpy_func_new (((recpy_element_object *) self)->ptid,
|
||||
RECORD_METHOD_BTRACE, func->segment.next->number);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceList.__len__ (self) -> int. */
|
||||
@@ -572,13 +465,18 @@ btpy_list_item (PyObject *self, Py_ssize_t index)
|
||||
{
|
||||
const btpy_list_object * const obj = (btpy_list_object *) self;
|
||||
struct thread_info * const tinfo = find_thread_ptid (obj->ptid);
|
||||
Py_ssize_t number;
|
||||
|
||||
if (index < 0 || index >= btpy_list_length (self))
|
||||
return PyErr_Format (PyExc_IndexError, _("Index out of range: %zd."),
|
||||
index);
|
||||
|
||||
return btpy_new (obj->ptid, obj->first + (obj->step * index),
|
||||
obj->element_type);
|
||||
number = obj->first + (obj->step * index);
|
||||
|
||||
if (obj->element_type == &recpy_insn_type)
|
||||
return recpy_insn_new (obj->ptid, RECORD_METHOD_BTRACE, number);
|
||||
else
|
||||
return recpy_func_new (obj->ptid, RECORD_METHOD_BTRACE, number);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceList.__getitem__ (self, slice) -> BtraceList. */
|
||||
@@ -620,7 +518,7 @@ static LONGEST
|
||||
btpy_list_position (PyObject *self, PyObject *value)
|
||||
{
|
||||
const btpy_list_object * const list_obj = (btpy_list_object *) self;
|
||||
const btpy_object * const obj = (btpy_object *) value;
|
||||
const recpy_element_object * const obj = (const recpy_element_object *) value;
|
||||
Py_ssize_t index = obj->number;
|
||||
|
||||
if (list_obj->element_type != Py_TYPE (value))
|
||||
@@ -734,7 +632,8 @@ recpy_bt_method (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_format (PyObject *self, void *closure)
|
||||
{
|
||||
const struct thread_info * const tinfo = find_thread_ptid (inferior_ptid);
|
||||
const recpy_record_object * const record = (recpy_record_object *) self;
|
||||
const struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
||||
const struct btrace_config * config;
|
||||
|
||||
if (tinfo == NULL)
|
||||
@@ -754,7 +653,8 @@ recpy_bt_format (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_replay_position (PyObject *self, void *closure)
|
||||
{
|
||||
const struct thread_info * const tinfo = find_thread_ptid (inferior_ptid);
|
||||
const recpy_record_object * const record = (recpy_record_object *) self;
|
||||
const struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
||||
|
||||
if (tinfo == NULL)
|
||||
Py_RETURN_NONE;
|
||||
@@ -762,8 +662,8 @@ recpy_bt_replay_position (PyObject *self, void *closure)
|
||||
if (tinfo->btrace.replay == NULL)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
return btpy_insn_new (inferior_ptid,
|
||||
btrace_insn_number (tinfo->btrace.replay));
|
||||
return btpy_insn_or_gap_new (tinfo,
|
||||
btrace_insn_number (tinfo->btrace.replay));
|
||||
}
|
||||
|
||||
/* Implementation of
|
||||
@@ -772,7 +672,8 @@ recpy_bt_replay_position (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_begin (PyObject *self, void *closure)
|
||||
{
|
||||
struct thread_info * const tinfo = find_thread_ptid (inferior_ptid);
|
||||
const recpy_record_object * const record = (recpy_record_object *) self;
|
||||
struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
||||
struct btrace_insn_iterator iterator;
|
||||
|
||||
if (tinfo == NULL)
|
||||
@@ -784,7 +685,7 @@ recpy_bt_begin (PyObject *self, void *closure)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
btrace_insn_begin (&iterator, &tinfo->btrace);
|
||||
return btpy_insn_new (inferior_ptid, btrace_insn_number (&iterator));
|
||||
return btpy_insn_or_gap_new (tinfo, btrace_insn_number (&iterator));
|
||||
}
|
||||
|
||||
/* Implementation of
|
||||
@@ -793,7 +694,8 @@ recpy_bt_begin (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_end (PyObject *self, void *closure)
|
||||
{
|
||||
struct thread_info * const tinfo = find_thread_ptid (inferior_ptid);
|
||||
const recpy_record_object * const record = (recpy_record_object *) self;
|
||||
struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
||||
struct btrace_insn_iterator iterator;
|
||||
|
||||
if (tinfo == NULL)
|
||||
@@ -805,7 +707,7 @@ recpy_bt_end (PyObject *self, void *closure)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
btrace_insn_end (&iterator, &tinfo->btrace);
|
||||
return btpy_insn_new (inferior_ptid, btrace_insn_number (&iterator));
|
||||
return btpy_insn_or_gap_new (tinfo, btrace_insn_number (&iterator));
|
||||
}
|
||||
|
||||
/* Implementation of
|
||||
@@ -814,7 +716,8 @@ recpy_bt_end (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_instruction_history (PyObject *self, void *closure)
|
||||
{
|
||||
struct thread_info * const tinfo = find_thread_ptid (inferior_ptid);
|
||||
const recpy_record_object * const record = (recpy_record_object *) self;
|
||||
struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
||||
struct btrace_insn_iterator iterator;
|
||||
unsigned long first = 0;
|
||||
unsigned long last = 0;
|
||||
@@ -833,7 +736,7 @@ recpy_bt_instruction_history (PyObject *self, void *closure)
|
||||
btrace_insn_end (&iterator, &tinfo->btrace);
|
||||
last = btrace_insn_number (&iterator);
|
||||
|
||||
return btpy_list_new (inferior_ptid, first, last, 1, &btpy_insn_type);
|
||||
return btpy_list_new (record->ptid, first, last, 1, &recpy_insn_type);
|
||||
}
|
||||
|
||||
/* Implementation of
|
||||
@@ -842,26 +745,27 @@ recpy_bt_instruction_history (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_function_call_history (PyObject *self, void *closure)
|
||||
{
|
||||
struct thread_info * const tinfo = find_thread_ptid (inferior_ptid);
|
||||
struct btrace_call_iterator iterator;
|
||||
unsigned long first = 0;
|
||||
unsigned long last = 0;
|
||||
const recpy_record_object * const record = (recpy_record_object *) self;
|
||||
struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
||||
struct btrace_call_iterator iterator;
|
||||
unsigned long first = 0;
|
||||
unsigned long last = 0;
|
||||
|
||||
if (tinfo == NULL)
|
||||
Py_RETURN_NONE;
|
||||
if (tinfo == NULL)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
btrace_fetch (tinfo);
|
||||
btrace_fetch (tinfo);
|
||||
|
||||
if (btrace_is_empty (tinfo))
|
||||
Py_RETURN_NONE;
|
||||
if (btrace_is_empty (tinfo))
|
||||
Py_RETURN_NONE;
|
||||
|
||||
btrace_call_begin (&iterator, &tinfo->btrace);
|
||||
first = btrace_call_number (&iterator);
|
||||
btrace_call_begin (&iterator, &tinfo->btrace);
|
||||
first = btrace_call_number (&iterator);
|
||||
|
||||
btrace_call_end (&iterator, &tinfo->btrace);
|
||||
last = btrace_call_number (&iterator);
|
||||
btrace_call_end (&iterator, &tinfo->btrace);
|
||||
last = btrace_call_number (&iterator);
|
||||
|
||||
return btpy_list_new (inferior_ptid, first, last, 1, &btpy_call_type);
|
||||
return btpy_list_new (record->ptid, first, last, 1, &recpy_func_type);
|
||||
}
|
||||
|
||||
/* Implementation of BtraceRecord.goto (self, BtraceInstruction) -> None. */
|
||||
@@ -869,8 +773,9 @@ recpy_bt_function_call_history (PyObject *self, void *closure)
|
||||
PyObject *
|
||||
recpy_bt_goto (PyObject *self, PyObject *args)
|
||||
{
|
||||
struct thread_info * const tinfo = find_thread_ptid (inferior_ptid);
|
||||
const btpy_object *obj;
|
||||
const recpy_record_object * const record = (recpy_record_object *) self;
|
||||
struct thread_info * const tinfo = find_thread_ptid (record->ptid);
|
||||
const recpy_element_object *obj;
|
||||
|
||||
if (tinfo == NULL || btrace_is_empty (tinfo))
|
||||
return PyErr_Format (gdbpy_gdb_error, _("Empty branch trace."));
|
||||
@@ -878,7 +783,7 @@ recpy_bt_goto (PyObject *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple (args, "O", &obj))
|
||||
return NULL;
|
||||
|
||||
if (Py_TYPE (obj) != &btpy_insn_type)
|
||||
if (Py_TYPE (obj) != &recpy_insn_type)
|
||||
return PyErr_Format (PyExc_TypeError, _("Argument must be instruction."));
|
||||
|
||||
TRY
|
||||
@@ -901,40 +806,6 @@ recpy_bt_goto (PyObject *self, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* BtraceInstruction members. */
|
||||
|
||||
struct gdb_PyGetSetDef btpy_insn_getset[] =
|
||||
{
|
||||
{ "number", btpy_number, NULL, "instruction number", NULL},
|
||||
{ "error", btpy_insn_error, NULL, "error number for gaps", NULL},
|
||||
{ "sal", btpy_insn_sal, NULL, "associated symbol and line", NULL},
|
||||
{ "pc", btpy_insn_pc, NULL, "instruction address", NULL},
|
||||
{ "data", btpy_insn_data, NULL, "raw instruction data", NULL},
|
||||
{ "decoded", btpy_insn_decode, NULL, "decoded instruction or error message \
|
||||
if the instruction is a gap", NULL},
|
||||
{ "size", btpy_insn_size, NULL, "instruction size in byte", NULL},
|
||||
{ "is_speculative", btpy_insn_is_speculative, NULL, "if the instruction was \
|
||||
executed speculatively", NULL},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* BtraceFunctionCall members. */
|
||||
|
||||
static gdb_PyGetSetDef btpy_call_getset[] =
|
||||
{
|
||||
{ "number", btpy_number, NULL, "function call number", NULL},
|
||||
{ "level", btpy_call_level, NULL, "call stack level", NULL},
|
||||
{ "symbol", btpy_call_symbol, NULL, "associated line and symbol", NULL},
|
||||
{ "instructions", btpy_call_instructions, NULL, "list of instructions in \
|
||||
this function segment", NULL},
|
||||
{ "up", btpy_call_up, NULL, "caller or returned-to function segment", NULL},
|
||||
{ "prev_sibling", btpy_call_prev_sibling, NULL, "previous segment of this \
|
||||
function", NULL},
|
||||
{ "next_sibling", btpy_call_next_sibling, NULL, "next segment of this \
|
||||
function", NULL},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* BtraceList methods. */
|
||||
|
||||
struct PyMethodDef btpy_list_methods[] =
|
||||
@@ -963,24 +834,6 @@ static PyMappingMethods btpy_list_mapping_methods =
|
||||
int
|
||||
gdbpy_initialize_btrace (void)
|
||||
{
|
||||
btpy_insn_type.tp_new = PyType_GenericNew;
|
||||
btpy_insn_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
btpy_insn_type.tp_basicsize = sizeof (btpy_object);
|
||||
btpy_insn_type.tp_name = "gdb.BtraceInstruction";
|
||||
btpy_insn_type.tp_doc = "GDB btrace instruction object";
|
||||
btpy_insn_type.tp_getset = btpy_insn_getset;
|
||||
btpy_insn_type.tp_richcompare = btpy_richcompare;
|
||||
btpy_insn_type.tp_hash = btpy_hash;
|
||||
|
||||
btpy_call_type.tp_new = PyType_GenericNew;
|
||||
btpy_call_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
btpy_call_type.tp_basicsize = sizeof (btpy_object);
|
||||
btpy_call_type.tp_name = "gdb.BtraceFunctionCall";
|
||||
btpy_call_type.tp_doc = "GDB btrace call object";
|
||||
btpy_call_type.tp_getset = btpy_call_getset;
|
||||
btpy_call_type.tp_richcompare = btpy_richcompare;
|
||||
btpy_call_type.tp_hash = btpy_hash;
|
||||
|
||||
btpy_list_type.tp_new = PyType_GenericNew;
|
||||
btpy_list_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
btpy_list_type.tp_basicsize = sizeof (btpy_list_object);
|
||||
@@ -997,10 +850,5 @@ gdbpy_initialize_btrace (void)
|
||||
|
||||
btpy_list_mapping_methods.mp_subscript = btpy_list_slice;
|
||||
|
||||
if (PyType_Ready (&btpy_insn_type) < 0
|
||||
|| PyType_Ready (&btpy_call_type) < 0
|
||||
|| PyType_Ready (&btpy_list_type) < 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
return PyType_Ready (&btpy_list_type);
|
||||
}
|
||||
|
||||
@@ -46,4 +46,46 @@ extern PyObject *recpy_bt_begin (PyObject *self, void *closure);
|
||||
/* Implementation of record.end [instruction]. */
|
||||
extern PyObject *recpy_bt_end (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordInstruction.number [int]. */
|
||||
extern PyObject *recpy_bt_insn_number (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordInstruction.sal [gdb.Symtab_and_line]. */
|
||||
extern PyObject *recpy_bt_insn_sal (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordInstruction.pc [int]. */
|
||||
extern PyObject *recpy_bt_insn_pc (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordInstruction.data [buffer]. */
|
||||
extern PyObject *recpy_bt_insn_data (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordInstruction.decoded [str]. */
|
||||
extern PyObject *recpy_bt_insn_decoded (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordInstruction.size [int]. */
|
||||
extern PyObject *recpy_bt_insn_size (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordInstruction.is_speculative [bool]. */
|
||||
extern PyObject *recpy_bt_insn_is_speculative (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordFunctionSegment.number [int]. */
|
||||
extern PyObject *recpy_bt_func_number (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordFunctionSegment.number [int]. */
|
||||
extern PyObject *recpy_bt_func_level (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordFunctionSegment.symbol [gdb.Symbol]. */
|
||||
extern PyObject *recpy_bt_func_symbol (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordFunctionSegment.instructions [list]. */
|
||||
extern PyObject *recpy_bt_func_instructions (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordFunctionSegment.up [RecordFunctionSegment]. */
|
||||
extern PyObject *recpy_bt_func_up (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordFunctionSegment.prev [RecordFunctionSegment]. */
|
||||
extern PyObject *recpy_bt_func_prev (PyObject *self, void *closure);
|
||||
|
||||
/* Implementation of RecordFunctionSegment.next [RecordFunctionSegment]. */
|
||||
extern PyObject *recpy_bt_func_next (PyObject *self, void *closure);
|
||||
|
||||
#endif /* GDB_PY_RECORD_BTRACE_H */
|
||||
|
||||
@@ -18,41 +18,50 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "record.h"
|
||||
#include "python-internal.h"
|
||||
#include "py-instruction.h"
|
||||
#include "py-record.h"
|
||||
#include "py-record-btrace.h"
|
||||
#include "py-record-full.h"
|
||||
#include "target.h"
|
||||
|
||||
/* Python Record object. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD
|
||||
|
||||
/* The ptid this object refers to. */
|
||||
ptid_t ptid;
|
||||
|
||||
/* The current recording method. */
|
||||
enum record_method method;
|
||||
} recpy_record_object;
|
||||
|
||||
/* Python Record type. */
|
||||
|
||||
static PyTypeObject recpy_record_type = {
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
};
|
||||
|
||||
/* Implementation of record.ptid. */
|
||||
/* Python RecordInstruction type. */
|
||||
|
||||
static PyObject *
|
||||
recpy_ptid (PyObject *self, void* closure)
|
||||
PyTypeObject recpy_insn_type = {
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
};
|
||||
|
||||
/* Python RecordFunctionSegment type. */
|
||||
|
||||
PyTypeObject recpy_func_type = {
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
};
|
||||
|
||||
/* Python RecordGap type. */
|
||||
|
||||
PyTypeObject recpy_gap_type = {
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
};
|
||||
|
||||
/* Python RecordGap object. */
|
||||
typedef struct
|
||||
{
|
||||
const recpy_record_object * const obj = (recpy_record_object *) self;
|
||||
PyObject_HEAD
|
||||
|
||||
return gdbpy_create_ptid_object (obj->ptid);
|
||||
}
|
||||
/* Reason code. */
|
||||
int reason_code;
|
||||
|
||||
/* Reason message. */
|
||||
const char *reason_string;
|
||||
|
||||
/* Element number. */
|
||||
Py_ssize_t number;
|
||||
} recpy_gap_object;
|
||||
|
||||
/* Implementation of record.method. */
|
||||
|
||||
@@ -164,6 +173,309 @@ recpy_end (PyObject *self, void* closure)
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Create a new gdb.RecordInstruction object. */
|
||||
|
||||
PyObject *
|
||||
recpy_insn_new (ptid_t ptid, enum record_method method, Py_ssize_t number)
|
||||
{
|
||||
recpy_element_object * const obj = PyObject_New (recpy_element_object,
|
||||
&recpy_insn_type);
|
||||
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
|
||||
obj->ptid = ptid;
|
||||
obj->method = method;
|
||||
obj->number = number;
|
||||
|
||||
return (PyObject *) obj;
|
||||
}
|
||||
|
||||
/* Implementation of RecordInstruction.sal [gdb.Symtab_and_line]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_insn_sal (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_insn_sal (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordInstruction.pc [int]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_insn_pc (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_insn_pc (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordInstruction.data [buffer]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_insn_data (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_insn_data (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordInstruction.decoded [str]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_insn_decoded (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_insn_decoded (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordInstruction.size [int]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_insn_size (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_insn_size (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordInstruction.is_speculative [bool]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_insn_is_speculative (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_insn_is_speculative (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Create a new gdb.RecordFunctionSegment object. */
|
||||
|
||||
PyObject *
|
||||
recpy_func_new (ptid_t ptid, enum record_method method, Py_ssize_t number)
|
||||
{
|
||||
recpy_element_object * const obj = PyObject_New (recpy_element_object,
|
||||
&recpy_func_type);
|
||||
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
|
||||
obj->ptid = ptid;
|
||||
obj->method = method;
|
||||
obj->number = number;
|
||||
|
||||
return (PyObject *) obj;
|
||||
}
|
||||
|
||||
/* Implementation of RecordFunctionSegment.level [int]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_func_level (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_func_level (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordFunctionSegment.symbol [gdb.Symbol]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_func_symbol (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_func_symbol (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordFunctionSegment.instructions [list]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_func_instructions (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_func_instructions (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordFunctionSegment.up [RecordFunctionSegment]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_func_up (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_func_up (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordFunctionSegment.prev [RecordFunctionSegment]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_func_prev (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_func_prev (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordFunctionSegment.next [RecordFunctionSegment]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_func_next (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
if (obj->method == RECORD_METHOD_BTRACE)
|
||||
return recpy_bt_func_next (self, closure);
|
||||
|
||||
return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
|
||||
}
|
||||
|
||||
/* Implementation of RecordInstruction.number [int] and
|
||||
RecordFunctionSegment.number [int]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_element_number (PyObject *self, void* closure)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
return PyInt_FromSsize_t (obj->number);
|
||||
}
|
||||
|
||||
/* Implementation of RecordInstruction.__hash__ [int] and
|
||||
RecordFunctionSegment.__hash__ [int]. */
|
||||
|
||||
static Py_hash_t
|
||||
recpy_element_hash (PyObject *self)
|
||||
{
|
||||
const recpy_element_object * const obj = (recpy_element_object *) self;
|
||||
|
||||
return obj->number;
|
||||
}
|
||||
|
||||
/* Implementation of operator == and != of RecordInstruction and
|
||||
RecordFunctionSegment. */
|
||||
|
||||
static PyObject *
|
||||
recpy_element_richcompare (PyObject *self, PyObject *other, int op)
|
||||
{
|
||||
const recpy_element_object * const obj1 = (recpy_element_object *) self;
|
||||
const recpy_element_object * const obj2 = (recpy_element_object *) other;
|
||||
|
||||
if (Py_TYPE (self) != Py_TYPE (other))
|
||||
{
|
||||
Py_INCREF (Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case Py_EQ:
|
||||
if (ptid_equal (obj1->ptid, obj2->ptid)
|
||||
&& obj1->method == obj2->method
|
||||
&& obj1->number == obj2->number)
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
|
||||
case Py_NE:
|
||||
if (!ptid_equal (obj1->ptid, obj2->ptid)
|
||||
|| obj1->method != obj2->method
|
||||
|| obj1->number != obj2->number)
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Py_INCREF (Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
|
||||
/* Create a new gdb.RecordGap object. */
|
||||
|
||||
PyObject *
|
||||
recpy_gap_new (int reason_code, const char *reason_string, Py_ssize_t number)
|
||||
{
|
||||
recpy_gap_object * const obj = PyObject_New (recpy_gap_object,
|
||||
&recpy_gap_type);
|
||||
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
|
||||
obj->reason_code = reason_code;
|
||||
obj->reason_string = reason_string;
|
||||
obj->number = number;
|
||||
|
||||
return (PyObject *) obj;
|
||||
}
|
||||
|
||||
/* Implementation of RecordGap.number [int]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_gap_number (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_gap_object * const obj = (const recpy_gap_object *) self;
|
||||
|
||||
return PyInt_FromSsize_t (obj->number);
|
||||
}
|
||||
|
||||
/* Implementation of RecordGap.error_code [int]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_gap_reason_code (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_gap_object * const obj = (const recpy_gap_object *) self;
|
||||
|
||||
return PyInt_FromLong (obj->reason_code);
|
||||
}
|
||||
|
||||
/* Implementation of RecordGap.error_string [str]. */
|
||||
|
||||
static PyObject *
|
||||
recpy_gap_reason_string (PyObject *self, void *closure)
|
||||
{
|
||||
const recpy_gap_object * const obj = (const recpy_gap_object *) self;
|
||||
|
||||
return PyString_FromString (obj->reason_string);
|
||||
}
|
||||
|
||||
/* Record method list. */
|
||||
|
||||
static PyMethodDef recpy_record_methods[] = {
|
||||
@@ -176,7 +488,6 @@ Rewind to given location."},
|
||||
/* Record member list. */
|
||||
|
||||
static gdb_PyGetSetDef recpy_record_getset[] = {
|
||||
{ "ptid", recpy_ptid, NULL, "Current thread.", NULL },
|
||||
{ "method", recpy_method, NULL, "Current recording method.", NULL },
|
||||
{ "format", recpy_format, NULL, "Current recording format.", NULL },
|
||||
{ "replay_position", recpy_replay_position, NULL, "Current replay position.",
|
||||
@@ -193,6 +504,43 @@ the current instruction and is used for e.g. record.goto (record.end).", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* RecordInstruction member list. */
|
||||
|
||||
static gdb_PyGetSetDef recpy_insn_getset[] = {
|
||||
{ "number", recpy_element_number, NULL, "instruction number", NULL},
|
||||
{ "sal", recpy_insn_sal, NULL, "associated symbol and line", NULL},
|
||||
{ "pc", recpy_insn_pc, NULL, "instruction address", NULL},
|
||||
{ "data", recpy_insn_data, NULL, "raw instruction data", NULL},
|
||||
{ "decoded", recpy_insn_decoded, NULL, "decoded instruction", NULL},
|
||||
{ "size", recpy_insn_size, NULL, "instruction size in byte", NULL},
|
||||
{ "is_speculative", recpy_insn_is_speculative, NULL, "if the instruction was \
|
||||
executed speculatively", NULL},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* RecordFunctionSegment member list. */
|
||||
|
||||
static gdb_PyGetSetDef recpy_func_getset[] = {
|
||||
{ "number", recpy_element_number, NULL, "function segment number", NULL},
|
||||
{ "level", recpy_func_level, NULL, "call stack level", NULL},
|
||||
{ "symbol", recpy_func_symbol, NULL, "associated line and symbol", NULL},
|
||||
{ "instructions", recpy_func_instructions, NULL, "list of instructions in \
|
||||
this function segment", NULL},
|
||||
{ "up", recpy_func_up, NULL, "caller or returned-to function segment", NULL},
|
||||
{ "prev", recpy_func_prev, NULL, "previous segment of this function", NULL},
|
||||
{ "next", recpy_func_next, NULL, "next segment of this function", NULL},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* RecordGap member list. */
|
||||
|
||||
static gdb_PyGetSetDef recpy_gap_getset[] = {
|
||||
{ "number", recpy_gap_number, NULL, "element number", NULL},
|
||||
{ "reason_code", recpy_gap_reason_code, NULL, "reason code", NULL},
|
||||
{ "reason_string", recpy_gap_reason_string, NULL, "reason string", NULL},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* Sets up the record API in the gdb module. */
|
||||
|
||||
int
|
||||
@@ -206,7 +554,39 @@ gdbpy_initialize_record (void)
|
||||
recpy_record_type.tp_methods = recpy_record_methods;
|
||||
recpy_record_type.tp_getset = recpy_record_getset;
|
||||
|
||||
return PyType_Ready (&recpy_record_type);
|
||||
recpy_insn_type.tp_new = PyType_GenericNew;
|
||||
recpy_insn_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
recpy_insn_type.tp_basicsize = sizeof (recpy_element_object);
|
||||
recpy_insn_type.tp_name = "gdb.RecordInstruction";
|
||||
recpy_insn_type.tp_doc = "GDB recorded instruction object";
|
||||
recpy_insn_type.tp_getset = recpy_insn_getset;
|
||||
recpy_insn_type.tp_richcompare = recpy_element_richcompare;
|
||||
recpy_insn_type.tp_hash = recpy_element_hash;
|
||||
recpy_insn_type.tp_base = &py_insn_type;
|
||||
|
||||
recpy_func_type.tp_new = PyType_GenericNew;
|
||||
recpy_func_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
recpy_func_type.tp_basicsize = sizeof (recpy_element_object);
|
||||
recpy_func_type.tp_name = "gdb.RecordFunctionSegment";
|
||||
recpy_func_type.tp_doc = "GDB record function segment object";
|
||||
recpy_func_type.tp_getset = recpy_func_getset;
|
||||
recpy_func_type.tp_richcompare = recpy_element_richcompare;
|
||||
recpy_func_type.tp_hash = recpy_element_hash;
|
||||
|
||||
recpy_gap_type.tp_new = PyType_GenericNew;
|
||||
recpy_gap_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||
recpy_gap_type.tp_basicsize = sizeof (recpy_gap_object);
|
||||
recpy_gap_type.tp_name = "gdb.RecordGap";
|
||||
recpy_gap_type.tp_doc = "GDB recorded gap object";
|
||||
recpy_gap_type.tp_getset = recpy_gap_getset;
|
||||
|
||||
if (PyType_Ready (&recpy_record_type) < 0
|
||||
|| PyType_Ready (&recpy_insn_type) < 0
|
||||
|| PyType_Ready (&recpy_func_type) < 0
|
||||
|| PyType_Ready (&recpy_gap_type) < 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Implementation of gdb.start_recording (method) -> gdb.Record. */
|
||||
|
||||
74
gdb/python/py-record.h
Normal file
74
gdb/python/py-record.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* Python interface to record targets.
|
||||
|
||||
Copyright 2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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/>. */
|
||||
|
||||
#ifndef GDB_PY_RECORD_H
|
||||
#define GDB_PY_RECORD_H
|
||||
|
||||
#include "inferior.h"
|
||||
#include "python-internal.h"
|
||||
#include "record.h"
|
||||
|
||||
/* Python Record object. */
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD
|
||||
|
||||
/* The ptid this object refers to. */
|
||||
ptid_t ptid;
|
||||
|
||||
/* The current recording method. */
|
||||
enum record_method method;
|
||||
} recpy_record_object;
|
||||
|
||||
/* Python recorded element object. This is generic enough to represent
|
||||
recorded instructions as well as recorded function call segments, hence the
|
||||
generic name. */
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD
|
||||
|
||||
/* The ptid this object refers to. */
|
||||
ptid_t ptid;
|
||||
|
||||
/* The current recording method. */
|
||||
enum record_method method;
|
||||
|
||||
/* Element number. */
|
||||
Py_ssize_t number;
|
||||
} recpy_element_object;
|
||||
|
||||
/* Python RecordInstruction type. */
|
||||
extern PyTypeObject recpy_insn_type;
|
||||
|
||||
/* Python RecordFunctionSegment type. */
|
||||
extern PyTypeObject recpy_func_type;
|
||||
|
||||
/* Create a new gdb.RecordInstruction object. */
|
||||
extern PyObject *recpy_insn_new (ptid_t ptid, enum record_method method,
|
||||
Py_ssize_t number);
|
||||
|
||||
/* Create a new gdb.RecordFunctionSegment object. */
|
||||
extern PyObject *recpy_func_new (ptid_t ptid, enum record_method method,
|
||||
Py_ssize_t number);
|
||||
|
||||
/* Create a new gdb.RecordGap object. */
|
||||
extern PyObject *recpy_gap_new (int reason_code, const char *reason_string,
|
||||
Py_ssize_t number);
|
||||
|
||||
#endif /* GDB_PY_RECORD_H */
|
||||
@@ -562,6 +562,8 @@ int gdbpy_initialize_values (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_frames (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_instruction (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_btrace (void)
|
||||
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
|
||||
int gdbpy_initialize_record (void)
|
||||
|
||||
@@ -1626,6 +1626,7 @@ do_start_initialization ()
|
||||
|| gdbpy_initialize_values () < 0
|
||||
|| gdbpy_initialize_frames () < 0
|
||||
|| gdbpy_initialize_commands () < 0
|
||||
|| gdbpy_initialize_instruction () < 0
|
||||
|| gdbpy_initialize_record () < 0
|
||||
|| gdbpy_initialize_btrace () < 0
|
||||
|| gdbpy_initialize_symbols () < 0
|
||||
|
||||
@@ -1762,7 +1762,7 @@ tuple structs, and tuple-like enum variants"));
|
||||
|
||||
case STRUCTOP_STRUCT:
|
||||
{
|
||||
struct value* lhs;
|
||||
struct value *lhs;
|
||||
struct type *type;
|
||||
int tem, pc;
|
||||
|
||||
@@ -1771,16 +1771,14 @@ tuple structs, and tuple-like enum variants"));
|
||||
(*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
|
||||
lhs = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
||||
|
||||
const char *field_name = &exp->elts[pc + 2].string;
|
||||
type = value_type (lhs);
|
||||
if (TYPE_CODE (type) == TYPE_CODE_UNION
|
||||
&& !rust_union_is_untagged (type))
|
||||
{
|
||||
int i, start;
|
||||
struct disr_info disr;
|
||||
struct type* variant_type;
|
||||
char* field_name;
|
||||
|
||||
field_name = &exp->elts[pc + 2].string;
|
||||
struct type *variant_type;
|
||||
|
||||
disr = rust_get_disr_info (type, value_contents (lhs),
|
||||
value_embedded_offset (lhs),
|
||||
@@ -1817,9 +1815,10 @@ which has only anonymous fields"),
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Field access in structs and untagged unions works like C. */
|
||||
*pos = pc;
|
||||
result = evaluate_subexp_standard (expect_type, exp, pos, noside);
|
||||
result = value_struct_elt (&lhs, NULL, field_name, NULL,
|
||||
"structure");
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
result = value_zero (value_type (result), VALUE_LVAL (result));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1951,14 +1950,15 @@ rust_dump_subexp_body (struct expression *exp, struct ui_file *stream,
|
||||
{
|
||||
int field_number;
|
||||
|
||||
field_number = longest_to_int (exp->elts[elt].longconst);
|
||||
field_number = longest_to_int (exp->elts[elt + 1].longconst);
|
||||
|
||||
fprintf_filtered (stream, "Field number: %d", field_number);
|
||||
elt = dump_subexp (exp, stream, elt + 2);
|
||||
elt = dump_subexp (exp, stream, elt + 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_RUST_ARRAY:
|
||||
++elt;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2021,7 +2021,7 @@ rust_print_subexp (struct expression *exp, int *pos, struct ui_file *stream,
|
||||
print_subexp (exp, pos, stream, PREC_SUFFIX);
|
||||
fprintf_filtered (stream, ".%d", tem);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
case OP_RUST_ARRAY:
|
||||
++*pos;
|
||||
|
||||
@@ -1,3 +1,54 @@
|
||||
2017-05-18 Thomas Preud'homme <thomas.preudhomme@arm.com>
|
||||
|
||||
* gdb.base/float.exp: Expect GDB prompt for targets without FPU.
|
||||
|
||||
2017-05-17 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* gdb.base/set-inferior-tty.exp (test_set_inferior_tty): Add
|
||||
argument command.
|
||||
(top-level): Invoke test_set_inferior_tty.
|
||||
|
||||
2017-05-04 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* gdb.python/py-record-btrace-threads.exp (check_insn_for_thread):
|
||||
Add parens to print call for Python 3.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* gdb.python/py-record-btrace.exp: Rename prev_sibling and next_sibling
|
||||
to prev and next.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* gdb.python/py-record-btrace.exp: Remove test for
|
||||
gdb.BtraceInstruction.error.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* gdb.python/py-record-btrace.exp: Remove Record.ptid test.
|
||||
|
||||
2017-05-04 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||
|
||||
* gdb.python/py-record-btrace-threads.c: New file.
|
||||
* gdb.python/py-record-btrace-threads.exp: New file.
|
||||
|
||||
2017-05-03 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* gdb.cp/oranking.cc (dummy): New function to grab malloc.
|
||||
(main): Call it.
|
||||
|
||||
2017-04-27 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* gdb.cp/oranking.cc (test15): New function.
|
||||
(main): Call test15 and declare additional variables for testing.
|
||||
* gdb.cp/oranking.exp: Remove kfail status for "p foo4(&a)" and
|
||||
"p foo101('abc')" tests.
|
||||
Add tests for cv qualifier overloads.
|
||||
* gdb.cp/rvalue-ref-overloads.exp: Remove kfail status for
|
||||
"lvalue reference overload" test.
|
||||
* gdb.cp/rvalue-ref-params.exp: Remove kfail status for
|
||||
"print value of f1 on Child&& in f2" test.
|
||||
|
||||
2017-04-12 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/21323
|
||||
|
||||
@@ -50,7 +50,7 @@ if { [is_aarch64_target] } then {
|
||||
# if we have NEON.
|
||||
pass "info float (VFP)"
|
||||
}
|
||||
-re "No floating.point info available for this processor.*" {
|
||||
-re "No floating.point info available for this processor.*$gdb_prompt $" {
|
||||
pass "info float (without FPU)"
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ if { [is_aarch64_target] } then {
|
||||
-re "fp0.*fp1.*fp7.*$gdb_prompt $" {
|
||||
pass "info float (with FPU)"
|
||||
}
|
||||
-re "No floating.point info available for this processor.*" {
|
||||
-re "No floating.point info available for this processor.*$gdb_prompt $" {
|
||||
pass "info float (without FPU)"
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ if { [is_aarch64_target] } then {
|
||||
-re "fd0.*fd3.*$gdb_prompt $" {
|
||||
pass "info float (with FPU)"
|
||||
}
|
||||
-re "No floating.point info available for this processor.*" {
|
||||
-re "No floating.point info available for this processor.*$gdb_prompt $" {
|
||||
pass "info float (without FPU)"
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ if { [is_aarch64_target] } then {
|
||||
-re "f0.*f1.*f31.*fpscr.*$gdb_prompt $" {
|
||||
pass "info float (with FPU)"
|
||||
}
|
||||
-re "No floating.point info available for this processor.*" {
|
||||
-re "No floating.point info available for this processor.*$gdb_prompt $" {
|
||||
pass "info float (without FPU)"
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ if { [is_aarch64_target] } then {
|
||||
-re "fpul.*fr0.*fr1.*fr15.*$gdb_prompt $" {
|
||||
pass "info float (with FPU)"
|
||||
}
|
||||
-re "No floating.point info available for this processor.*" {
|
||||
-re "No floating.point info available for this processor.*$gdb_prompt $" {
|
||||
pass "info float (without FPU)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,20 +21,22 @@ if {[build_executable $testfile.exp $testfile ${srcfile} ${compile_options}] ==
|
||||
return -1
|
||||
}
|
||||
|
||||
proc test_set_inferior_tty { } {
|
||||
proc test_set_inferior_tty { command } {
|
||||
global binfile
|
||||
|
||||
clean_restart ${binfile}
|
||||
|
||||
gdb_test_no_output "set inferior-tty hello" "set inferior-tty to hello"
|
||||
gdb_test_no_output "$command hello" "set inferior-tty to hello"
|
||||
gdb_test "show inferior-tty" \
|
||||
"Terminal for future runs of program being debugged is \"hello\"." \
|
||||
"show inferior-tty shows hello"
|
||||
|
||||
gdb_test_no_output "set inferior-tty" "set inferior-tty to empty"
|
||||
gdb_test_no_output "$command" "set inferior-tty to empty"
|
||||
gdb_test "show inferior-tty" \
|
||||
"Terminal for future runs of program being debugged is \"\"." \
|
||||
"show inferior-tty shows empty"
|
||||
}
|
||||
|
||||
test_set_inferior_tty
|
||||
foreach_with_prefix command {"set inferior-tty" "tty"} {
|
||||
test_set_inferior_tty $command
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
#include <cstdlib>
|
||||
|
||||
/* Make sure `malloc' is linked into the program. If we don't, tests
|
||||
in the accompanying expect file may fail:
|
||||
|
||||
evaluation of this expression requires the program to have a function
|
||||
"malloc". */
|
||||
|
||||
void
|
||||
dummy ()
|
||||
{
|
||||
void *p = malloc (16);
|
||||
|
||||
free (p);
|
||||
}
|
||||
|
||||
/* 1. A standard covnersion sequence is better than a user-defined sequence
|
||||
which is better than an elipses conversion sequence. */
|
||||
@@ -147,7 +162,26 @@ int test14 (){
|
||||
return foo14(e); // 46
|
||||
}
|
||||
|
||||
/* Test cv qualifier overloads. */
|
||||
int foo15 (char *arg) { return 47; }
|
||||
int foo15 (const char *arg) { return 48; }
|
||||
int foo15 (volatile char *arg) { return 49; }
|
||||
int foo15 (const volatile char *arg) { return 50; }
|
||||
static int
|
||||
test15 ()
|
||||
{
|
||||
char *c = 0;
|
||||
const char *cc = 0;
|
||||
volatile char *vc = 0;
|
||||
const volatile char *cvc = 0;
|
||||
|
||||
// 47 + 48 + 49 + 50 = 194
|
||||
return foo15 (c) + foo15 (cc) + foo15 (vc) + foo15 (cvc);
|
||||
}
|
||||
|
||||
int main() {
|
||||
dummy ();
|
||||
|
||||
B b;
|
||||
foo0(b);
|
||||
foo1(b);
|
||||
@@ -203,5 +237,10 @@ int main() {
|
||||
foo14(e);
|
||||
test14();
|
||||
|
||||
const char *cc = 0;
|
||||
volatile char *vc = 0;
|
||||
const volatile char *cvc = 0;
|
||||
test15 ();
|
||||
|
||||
return 0; // end of main
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ gdb_test "p test3()" "21"
|
||||
gdb_test "p foo3(1.0f)" "21"
|
||||
|
||||
gdb_test "p test4()" "24"
|
||||
setup_kfail "gdb/12098" *-*-*
|
||||
gdb_test "p foo4(&a)" "24"
|
||||
|
||||
gdb_test "p test5()" "26"
|
||||
@@ -71,7 +70,6 @@ setup_kfail "gdb/12098" *-*-*
|
||||
gdb_test "p foo10(amp)" "216"
|
||||
|
||||
gdb_test "p test101()" "218"
|
||||
setup_kfail "gdb/12098" *-*-*
|
||||
gdb_test "p foo101(\"abc\")" "218"
|
||||
|
||||
gdb_test "p test11()" "32"
|
||||
@@ -91,5 +89,8 @@ gdb_test "p test14()" "46"
|
||||
setup_kfail "gdb/12096" *-*-*
|
||||
gdb_test "p foo14(e)" "46"
|
||||
|
||||
|
||||
|
||||
gdb_test "p test15 ()" "194"
|
||||
gdb_test "p foo15 (c)" "47"
|
||||
gdb_test "p foo15 (cc)" "48"
|
||||
gdb_test "p foo15 (vc)" "49"
|
||||
gdb_test "p foo15 (cvc)" "50"
|
||||
|
||||
@@ -60,7 +60,6 @@ gdb_test "print foo_rr_instance1.overload1arg(static_cast<foo&&>(arg))" \
|
||||
"print call overloaded func foo && arg"
|
||||
|
||||
# Test lvalue vs rvalue function overloads
|
||||
setup_kfail "c++/15372" "*-*-*"
|
||||
gdb_test "print f (i)" "= 1" "lvalue reference overload"
|
||||
|
||||
gdb_test "print f (ci)" "= 2" "lvalue reference to const overload"
|
||||
|
||||
@@ -48,7 +48,6 @@ set t "print value of Child&& in f2"
|
||||
gdb_start_again "marker2 here" $t
|
||||
gdb_test "print C" ".*id = 42.*" $t
|
||||
|
||||
setup_kfail "c++/15372" "*-*-*"
|
||||
gdb_test "print f1 (static_cast<Child&&> (C))" ".* = 42.*" \
|
||||
"print value of f1 on Child&& in f2"
|
||||
|
||||
|
||||
58
gdb/testsuite/gdb.python/py-record-btrace-threads.c
Normal file
58
gdb/testsuite/gdb.python/py-record-btrace-threads.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2017 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>
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
static int dummy;
|
||||
|
||||
static void *
|
||||
func1 (void *arg)
|
||||
{
|
||||
pthread_barrier_wait (&barrier);
|
||||
dummy = 1; /* bp1 */
|
||||
pthread_barrier_wait (&barrier);
|
||||
dummy = 1;
|
||||
pthread_barrier_wait (&barrier);
|
||||
return arg;
|
||||
}
|
||||
|
||||
static void *
|
||||
func2 (void *arg)
|
||||
{
|
||||
pthread_barrier_wait (&barrier);
|
||||
dummy = 2;
|
||||
pthread_barrier_wait (&barrier);
|
||||
dummy = 2;
|
||||
pthread_barrier_wait (&barrier); /* bp2 */
|
||||
return arg;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
pthread_t thread;
|
||||
|
||||
pthread_barrier_init (&barrier, NULL, 2);
|
||||
|
||||
pthread_create (&thread, NULL, func2, NULL);
|
||||
func1 (NULL);
|
||||
|
||||
pthread_join (thread, NULL);
|
||||
pthread_barrier_destroy (&barrier);
|
||||
return 0;
|
||||
}
|
||||
81
gdb/testsuite/gdb.python/py-record-btrace-threads.exp
Normal file
81
gdb/testsuite/gdb.python/py-record-btrace-threads.exp
Normal file
@@ -0,0 +1,81 @@
|
||||
# This testcase is part of GDB, the GNU debugger.
|
||||
#
|
||||
# Copyright 2017 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/>.
|
||||
|
||||
# Skip this test if btrace is disabled.
|
||||
|
||||
if { [skip_btrace_tests] } {
|
||||
untested "skipping btrace tests"
|
||||
return -1
|
||||
}
|
||||
|
||||
standard_testfile
|
||||
|
||||
if { [gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {debug} ] != "" } {
|
||||
untested "failed to prepare"
|
||||
return -1
|
||||
}
|
||||
clean_restart $testfile
|
||||
|
||||
# Skip this test if python is disabled.
|
||||
|
||||
load_lib gdb-python.exp
|
||||
if { [skip_python_tests] } {
|
||||
untested "skipping python tests"
|
||||
return -1
|
||||
}
|
||||
|
||||
if { ![runto_main] } {
|
||||
untested "failed to run to main"
|
||||
return -1
|
||||
}
|
||||
|
||||
# set up breakpoints
|
||||
gdb_breakpoint $srcfile:[gdb_get_line_number "bp1" $srcfile]
|
||||
gdb_breakpoint $srcfile:[gdb_get_line_number "bp2" $srcfile]
|
||||
|
||||
# record data
|
||||
gdb_continue_to_breakpoint "cont to bp.1" ".*bp1.*"
|
||||
gdb_test_no_output "record btrace"
|
||||
gdb_continue_to_breakpoint "cont to bp.2" ".*bp2.*"
|
||||
|
||||
# acquire the record objects for thread 1 and thread 2
|
||||
gdb_test "thread 1" ".*"
|
||||
gdb_test "record function-call-history" ".*" "fch thread 1"
|
||||
gdb_test_no_output "python rec1 = gdb.current_recording()"
|
||||
gdb_test "thread 2" ".*"
|
||||
gdb_test "record function-call-history" ".*" "fch thread 2"
|
||||
gdb_test_no_output "python rec2 = gdb.current_recording()"
|
||||
|
||||
# Thread 1 is supposed to call func1 (), thread 2 is supposed to call func2 ().
|
||||
# Check that the function call history for the current thread contains a call
|
||||
# to the right function and does not contain a call to the wrong function.
|
||||
proc check_insn_for_thread { self other } {
|
||||
with_test_prefix "checking thread $self" {
|
||||
gdb_test_no_output "python fch = rec$self.function_call_history"
|
||||
gdb_test_no_output "python f1calls = \{x for x in fch if x.symbol and x.symbol.name == \"func1\"\}"
|
||||
gdb_test_no_output "python f2calls = \{x for x in fch if x.symbol and x.symbol.name == \"func2\"\}"
|
||||
|
||||
gdb_test "python print(not f${self}calls)" "False"
|
||||
gdb_test "python print(not f${other}calls)" "True"
|
||||
}
|
||||
}
|
||||
|
||||
foreach_with_prefix thread { 1 2 } {
|
||||
gdb_test "thread $thread"
|
||||
check_insn_for_thread 1 2
|
||||
check_insn_for_thread 2 1
|
||||
}
|
||||
@@ -59,7 +59,6 @@ with_test_prefix "preopened record btrace" {
|
||||
|
||||
with_test_prefix "prepare record" {
|
||||
gdb_test_no_output "python r = gdb.start_recording(\"btrace\")"
|
||||
gdb_test "python print(len(r.ptid))" "3"
|
||||
gdb_test "python print(r.method)" "btrace"
|
||||
gdb_test "python print(r.format)" "pt|bts"
|
||||
gdb_test "stepi 100" ".*"
|
||||
@@ -82,7 +81,6 @@ with_test_prefix "replay end" {
|
||||
|
||||
with_test_prefix "instruction " {
|
||||
gdb_test "python print(i.number)" "1"
|
||||
gdb_test "python print(i.error)" "None"
|
||||
gdb_test "python print(i.sal)" "symbol and line for .*"
|
||||
gdb_test "python print(i.pc)" "$decimal"
|
||||
if { $gdb_py_is_py3k == 0 } {
|
||||
@@ -101,8 +99,8 @@ with_test_prefix "function call" {
|
||||
gdb_test "python print(c.level)" "$decimal"
|
||||
gdb_test "python print(len(c.instructions))" "$decimal"
|
||||
gdb_test "python print(c.up)" "None"
|
||||
gdb_test "python print(c.prev_sibling)" "None"
|
||||
gdb_test "python print(c == c.next_sibling.prev_sibling)" "True"
|
||||
gdb_test "python print(c.prev)" "None"
|
||||
gdb_test "python print(c == c.next.prev)" "True"
|
||||
}
|
||||
|
||||
with_test_prefix "list" {
|
||||
|
||||
@@ -117,7 +117,7 @@ tui_erase_data_content (const char *prompt)
|
||||
mvwaddstr (TUI_DATA_WIN->generic.handle,
|
||||
(TUI_DATA_WIN->generic.height / 2),
|
||||
x_pos,
|
||||
prompt);
|
||||
(char *) prompt);
|
||||
}
|
||||
wrefresh (TUI_DATA_WIN->generic.handle);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ box_win (struct tui_gen_win_info *win_info,
|
||||
box (win, tui_border_vline, tui_border_hline);
|
||||
#endif
|
||||
if (win_info->title)
|
||||
mvwaddstr (win, 0, 3, win_info->title);
|
||||
mvwaddstr (win, 0, 3, (char *) win_info->title);
|
||||
wattroff (win, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ tui_erase_source_content (struct tui_win_info *win_info,
|
||||
mvwaddstr (win_info->generic.handle,
|
||||
(win_info->generic.height / 2),
|
||||
x_pos,
|
||||
no_src_str);
|
||||
(char *) no_src_str);
|
||||
|
||||
/* elz: Added this function call to set the real contents of
|
||||
the window to what is on the screen, so that later calls
|
||||
@@ -280,7 +280,7 @@ tui_show_source_line (struct tui_win_info *win_info, int lineno)
|
||||
wattron (win_info->generic.handle, A_STANDOUT);
|
||||
|
||||
mvwaddstr (win_info->generic.handle, lineno, 1,
|
||||
line->which_element.source.line);
|
||||
(char *) line->which_element.source.line);
|
||||
if (line->which_element.source.is_exec_point)
|
||||
wattroff (win_info->generic.handle, A_STANDOUT);
|
||||
|
||||
@@ -565,7 +565,8 @@ tui_show_exec_info_content (struct tui_win_info *win_info)
|
||||
mvwaddstr (exec_info->handle,
|
||||
cur_line,
|
||||
0,
|
||||
exec_info->content[cur_line - 1]->which_element.simple_string);
|
||||
(char *) exec_info->content[cur_line - 1]
|
||||
->which_element.simple_string);
|
||||
tui_refresh_win (exec_info);
|
||||
exec_info->content_in_use = TRUE;
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ tui_enable (void)
|
||||
/* The MinGW port of ncurses requires $TERM to be unset in order
|
||||
to activate the Windows console driver. */
|
||||
if (s == NULL)
|
||||
s = newterm ("unknown", stdout, stdin);
|
||||
s = newterm ((char *) "unknown", stdout, stdin);
|
||||
#endif
|
||||
if (s == NULL)
|
||||
{
|
||||
|
||||
@@ -1 +1 @@
|
||||
7.12.50.DATE-git
|
||||
8.0
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
2017-05-31 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* environ.h: Add #ifndef guard.
|
||||
|
||||
2017-04-11 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* opcode/ppc.h (PPC_OPCODE_ALTIVEC2): Delete.
|
||||
|
||||
@@ -27,7 +27,9 @@ Boston, MA 02110-1301, USA. */
|
||||
# include <crt_externs.h>
|
||||
# define environ (*_NSGetEnviron ())
|
||||
# else
|
||||
# ifndef environ
|
||||
extern char **environ;
|
||||
# endif
|
||||
# endif
|
||||
# define HAVE_ENVIRON_DECL
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
2017-05-31 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* configure.ac (strnlen): Add to AC_CHECK_DECLS.
|
||||
* configure: Likewise.
|
||||
* config.in: Add HACE_DECL_STRNLEN.
|
||||
|
||||
2017-05-31 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* waitpid.c (wait) [__MINGW32__]: Define as a macro
|
||||
that calls _cwait, so that this function works on MinGW.
|
||||
|
||||
2017-03-27 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* cp-demint.c (cplus_demangle_fill_component): Handle
|
||||
|
||||
@@ -79,6 +79,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_STRNLEN
|
||||
|
||||
/* Define to 1 if you have the declaration of `strtol', and to 0 if you don't.
|
||||
*/
|
||||
#undef HAVE_DECL_STRTOL
|
||||
|
||||
21
libiberty/configure
vendored
21
libiberty/configure
vendored
@@ -5864,6 +5864,16 @@ fi
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_STRTOULL $ac_have_decl
|
||||
_ACEOF
|
||||
ac_fn_c_check_decl "$LINENO" "strnlen" "ac_cv_have_decl_strnlen" "$ac_includes_default"
|
||||
if test "x$ac_cv_have_decl_strnlen" = x""yes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_STRNLEN $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
|
||||
$as_echo "#define HAVE_SYS_ERRLIST 1" >>confdefs.h
|
||||
@@ -7003,6 +7013,17 @@ fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_STRVERSCMP $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
ac_fn_c_check_decl "$LINENO" "strnlen" "ac_cv_have_decl_strnlen" "$ac_includes_default"
|
||||
if test "x$ac_cv_have_decl_strnlen" = x""yes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_STRNLEN $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether canonicalize_file_name must be declared" >&5
|
||||
|
||||
@@ -416,7 +416,7 @@ if test "x" = "y"; then
|
||||
table times tmpnam \
|
||||
vasprintf vfprintf vprintf vsprintf \
|
||||
wait3 wait4 waitpid)
|
||||
AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf, strtol, strtoul, strtoll, strtoull])
|
||||
AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf, strtol, strtoul, strtoll, strtoull, strnlen])
|
||||
AC_DEFINE(HAVE_SYS_ERRLIST, 1, [Define if you have the sys_errlist variable.])
|
||||
AC_DEFINE(HAVE_SYS_NERR, 1, [Define if you have the sys_nerr variable.])
|
||||
AC_DEFINE(HAVE_SYS_SIGLIST, 1, [Define if you have the sys_siglist variable.])
|
||||
@@ -689,6 +689,7 @@ if test -z "${setobjs}"; then
|
||||
AC_CHECK_DECLS([calloc, getenv, getopt, malloc, realloc, sbrk])
|
||||
AC_CHECK_DECLS([strtol, strtoul, strtoll, strtoull])
|
||||
AC_CHECK_DECLS([strverscmp])
|
||||
AC_CHECK_DECLS([strnlen])
|
||||
libiberty_NEED_DECLARATION(canonicalize_file_name)
|
||||
fi
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@ does the return value. The third argument is unused in @libib{}.
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <process.h>
|
||||
#define wait(s) _cwait(s,pid,_WAIT_CHILD)
|
||||
#endif
|
||||
|
||||
pid_t
|
||||
waitpid (pid_t pid, int *stat_loc, int options ATTRIBUTE_UNUSED)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
2017-05-19 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* input.c [_WIN32]: Include <conio.h> to avoid compiler warning on
|
||||
MinGW.
|
||||
|
||||
2016-09-17 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* util.c: Include rlshell.h.
|
||||
|
||||
@@ -91,6 +91,7 @@ static int rl_gather_tyi PARAMS((void));
|
||||
/* 'isatty' in the Windows runtime returns non-zero for every
|
||||
character device, including the null device. Repair that. */
|
||||
#include <io.h>
|
||||
#include <conio.h>
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user