struct bt_iter_pos *pos;
int i = 0;
enum target_xfer_status res;
+ /* Records the lowest available address of all blocks that
+ intersects the requested range. */
+ ULONGEST low_addr_available = 0;
gdb_assert (ctf_iter != NULL);
/* Save the current position. */
}
}
+ if (offset < maddr && maddr < (offset + len))
+ if (low_addr_available == 0 || low_addr_available > maddr)
+ low_addr_available = maddr;
+
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
break;
}
/* Requested memory is unavailable in the context of traceframes,
and this address falls within a read-only section, fallback
- to reading from executable. */
+ to reading from executable, up to LOW_ADDR_AVAILABLE */
+ if (offset < low_addr_available)
+ len = min (len, low_addr_available - offset);
res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
if (res == TARGET_XFER_OK)
proc gdb_collect_args_test {} {
with_test_prefix "unavailable arguments" {
global gdb_prompt
+ global testfile srcdir subdir binfile
+ global trace_file_targets
prepare_for_trace_test
gdb_test "tfind none" \
"#0 end .*" \
"cease trace debugging"
+
+ set tracefile [standard_output_file ${testfile}]
+ gdb_test "tsave ${tracefile}.args.tfile" \
+ "Trace data saved to file '${tracefile}.args.tfile'\.\\r" \
+ "tsave ${testfile}.args.tfile"
+ gdb_test "tsave -ctf ${tracefile}.args.ctf" \
+ "Trace data saved to directory '${tracefile}.args.ctf'\.\\r" \
+ "save ctf trace file"
+
+ foreach target_name ${trace_file_targets} {
+ # Restart GDB and read the trace data in ${TARGET_NAME} target.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_file_cmd $binfile
+ gdb_test "target ${target_name} ${tracefile}.args.${target_name}" ".*" \
+ "change to ${target_name} target"
+
+ with_test_prefix "${target_name}" {
+ gdb_test "tfind start" "#0 args_test_func .*" \
+ "tfind test frame"
+ gdb_collect_args_test_1
+ }
+ }
}
}
proc gdb_collect_locals_test { func msg } {
with_test_prefix "unavailable locals: $msg" {
global gdb_prompt
+ global testfile srcdir subdir binfile
+ global trace_file_targets
prepare_for_trace_test
gdb_test "tfind none" \
"#0 end .*" \
"cease trace debugging"
+
+ set tracefile [standard_output_file ${testfile}]
+ gdb_test "tsave ${tracefile}.locals.tfile" \
+ "Trace data saved to file '${tracefile}.locals.tfile'\.\\r" \
+ "tsave ${testfile}.locals.tfile"
+ gdb_test "tsave -ctf ${tracefile}.locals.ctf" \
+ "Trace data saved to directory '${tracefile}.locals.ctf'\.\\r" \
+ "save ctf trace file"
+
+ foreach target_name ${trace_file_targets} {
+ # Restart GDB and read the trace data in ${TARGET_NAME} target.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_file_cmd $binfile
+ gdb_test "target ${target_name} ${tracefile}.locals.${target_name}" ".*" \
+ "change to ${target_name} target"
+
+ with_test_prefix "${target_name}" {
+ gdb_test "tfind start" "#0 $func .*" \
+ "tfind test frame"
+ gdb_collect_locals_test_1 $func
+ }
+ }
}
}
proc gdb_unavailable_registers_test { } {
with_test_prefix "unavailable registers" {
+ global testfile srcdir subdir binfile
+ global trace_file_targets
prepare_for_trace_test
gdb_unavailable_registers_test_1
gdb_test "tfind none" "#0 end .*" "cease trace debugging"
+
+ set tracefile [standard_output_file ${testfile}]
+ gdb_test "tsave ${tracefile}.registers.tfile" \
+ "Trace data saved to file '${tracefile}.registers.tfile'\.\\r" \
+ "tsave ${testfile}.registers.tfile"
+ gdb_test "tsave -ctf ${tracefile}.registers.ctf" \
+ "Trace data saved to directory '${tracefile}.registers.ctf'\.\\r" \
+ "save ctf trace file"
+
+ foreach target_name ${trace_file_targets} {
+ # Restart GDB and read the trace data in ${TARGET_NAME} target.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_file_cmd $binfile
+ gdb_test "target ${target_name} ${tracefile}.registers.${target_name}" ".*" \
+ "change to ${target_name} target"
+
+ with_test_prefix "${target_name}" {
+ gdb_test "tfind start" "#0 globals_test_func .*" \
+ "tfind test frame"
+ gdb_unavailable_registers_test_1
+ }
+ }
}
}
proc gdb_unavailable_floats { } {
with_test_prefix "unavailable floats" {
+ global testfile srcdir subdir binfile
+ global trace_file_targets
+
prepare_for_trace_test
# We'll simply re-use the globals_test_function for this test
gdb_unavailable_floats_1
gdb_test "tfind none" "#0 end .*" "cease trace debugging"
+
+ set tracefile [standard_output_file ${testfile}]
+ gdb_test "tsave ${tracefile}.floats.tfile" \
+ "Trace data saved to file '${tracefile}.floats.tfile'\.\\r" \
+ "tsave ${testfile}.floats.tfile"
+ gdb_test "tsave -ctf ${tracefile}.floats.ctf" \
+ "Trace data saved to directory '${tracefile}.floats.ctf'\.\\r" \
+ "save ctf trace file"
+
+ foreach target_name ${trace_file_targets} {
+ # Restart GDB and read the trace data in ${TARGET_NAME} target.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_file_cmd $binfile
+ gdb_test "target ${target_name} ${tracefile}.floats.${target_name}" ".*" \
+ "change to ${target_name} target"
+
+ with_test_prefix "${target_name}" {
+ gdb_test "tfind start" "#0 globals_test_func .*" \
+ "tfind test frame"
+ gdb_unavailable_floats_1
+ }
+ }
}
}
proc gdb_collect_globals_test { } {
with_test_prefix "collect globals" {
+ global testfile binfile srcdir subdir
+ global trace_file_targets
+
prepare_for_trace_test
set testline [gdb_get_line_number "set globals_test_func tracepoint here"]
gdb_test "tfind none" \
"#0 end .*" \
"cease trace debugging"
+
+ set tracefile [standard_output_file ${testfile}]
+ gdb_test "tsave ${tracefile}.globals.tfile" \
+ "Trace data saved to file '${tracefile}.globals.tfile'\.\\r" \
+ "tsave ${testfile}.globals.tfile"
+ gdb_test "tsave -ctf ${tracefile}.globals.ctf" \
+ "Trace data saved to directory '${tracefile}.globals.ctf'\.\\r" \
+ "save ctf trace file"
+
+ foreach target_name ${trace_file_targets} {
+ # Restart GDB and read the trace data in ${TARGET_NAME} target.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_file_cmd $binfile
+ gdb_test "target ${target_name} ${tracefile}.globals.${target_name}" ".*" \
+ "change to ${target_name} target"
+
+ with_test_prefix "${target_name}" {
+ gdb_test "tfind start" "#0 globals_test_func .*" \
+ "tfind test frame"
+ gdb_collect_globals_test_1
+ }
+ }
+
}
}
return 1
}
+set trace_file_targets [list "tfile"]
+gdb_test_multiple "target ctf" "" {
+ -re "Undefined target command: \"ctf\"\. Try \"help target\"\.\r\n$gdb_prompt $" {
+ }
+ -re "No CTF directory specified.*\r\n$gdb_prompt $" {
+ lappend trace_file_targets "ctf"
+ }
+}
+
# Body of test encased in a proc so we can return prematurely.
gdb_trace_collection_test
{
int pos = 0;
enum target_xfer_status res;
+ /* Records the lowest available address of all blocks that
+ intersects the requested range. */
+ ULONGEST low_addr_available = 0;
/* Iterate through the traceframe's blocks, looking for
memory. */
return TARGET_XFER_OK;
}
+ if (offset < maddr && maddr < (offset + len))
+ if (low_addr_available == 0 || low_addr_available > maddr)
+ low_addr_available = maddr;
+
/* Skip over this block. */
pos += (8 + 2 + mlen);
}
/* Requested memory is unavailable in the context of traceframes,
and this address falls within a read-only section, fallback
- to reading from executable. */
+ to reading from executable, up to LOW_ADDR_AVAILABLE. */
+ if (offset < low_addr_available)
+ len = min (len, low_addr_available - offset);
res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
if (res == TARGET_XFER_OK)