Commit Graph

10 Commits

Author SHA1 Message Date
Andrew Burgess 00df30ae1e gdb: New function to open source file and compute line charpos data
Every place that a symtab's line_charpos data is loaded always follows
the same pattern, so create a new function to contain this logic and
make use of it throughout GDB.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* source-cache.c (source_cache::get_plain_source_lines): Use
	open_source_file_with_line_charpos instead of just
	open_source_file, remove call to find_source_lines.
	(source_cache::get_source_lines): Likewise.
	* source.c (find_source_lines): Make static.
	(get_filename_and_charpos): Renamed into...
	(open_source_file_with_line_charpos): ..this along with changes to
	return a scoped_fd, and some other minor clean ups.
	(identify_source_line): Use open_source_file_with_line_charpos.
	(search_command_helper): Use open_source_file_with_line_charpos
	instead of just open_source_file, remove call to
	find_source_lines.
	* source.h (open_source_file_with_line_charpos): Declare new
	function.
	(find_source_lines): Delete declaration.
2019-06-15 21:39:04 +01:00
Philippe Waroquiers 8a522c6cab Have 'thread|frame apply' style their output.
'thread|frame apply CMD' launches CMD so that CMD output goes to a string_file.
This patch ensures that string_file for such CMD output contains
style escape sequences that 'thread|frame apply' will later on
output on the real terminal, so as to have CMD output properly styled.

The idea is to have the class ui_file having overridable methods
to indicate that the output to this ui_file should be done using
'terminal' behaviour such as styling.
Then these methods are overriden in string_file so that a specially
constructed string_file will get output with style escape sequences.

After this patch, the output of CMD by thread|frame apply CMD is styled
similarly as when CMD is launched directly.
Note that string_file (term_out true) could also support wrapping,
but this is not done (yet?).

Tested on debian/amd64.

gdb/ChangeLog
2019-04-27  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	Support style in 'frame|thread apply'

	* gdbcmd.h (execute_command_to_string): New term_out parameter.
	* record.c (record_start, record_stop): Update callers of
	execute_command_to_string with false.
	* ui-file.h (class ui_file): New term_out and can_emit_style_escape
	methods.
	(class string_file): New constructor with term_out parameter.
	Override methods term_out and can_emit_style_escape.  New member
	term_out.
	(class stdio_file): Override can_emit_style_escape.
	(class tee_file): Override term_out and can_emit_style_escape.
	* utils.h (can_emit_style_escape): Remove.
	* utils.c (can_emit_style_escape): Likewise.
	Update all callers of can_emit_style_escape (SOMESTREAM) to
	SOMESTREAM->can_emit_style_escape.
	* source-cache.c (source_cache::get_source_lines): Likewise.
	* stack.c (frame_apply_command_count): Call execute_command_to_string
	passing the term_out characteristic of the current gdb_stdout.
	* thread.c (thr_try_catch_cmd): Likewise.
	* top.c (execute_command_to_string): pass term_out parameter
	to construct the string_file for the command output.
	* ui-file.c (term_cli_styling): New function (most code moved
	from utils.c can_emit_style_escape).
	(string_file::string_file, string_file::can_emit_style_escape,
	stdio_file::can_emit_style_escape, tee_file::term_out,
	tee_file::can_emit_style_escape): New functions.
2019-04-27 14:25:28 +02:00
Simon Marchi 068ef30e9e Fix use-after-free in source_cache::get_source_lines
Commit ab42892fb7 ("Fix vertical scrolling of TUI source window")
introduced a use-after-free in source_cache::get_source_lines.

At the beginning of the method, we get the fullname of the symtab:

    const char *fullname = symtab_to_fullname (s);

fullname points to the string owned by the symtab (s.fullname).  When we
later do

    scoped_fd desc = open_source_file (s);

s.fullname gets reallocated (even though the string contents may not
change).  The fullname local variable now points to freed memory.

To avoid it, refresh the value of fullname after calling
open_source_file.

Here is the ASan report:

$ ./gdb -nx --data-directory=data-directory ./a.out
(gdb) start
Temporary breakpoint 1 at 0x1130: file test.cpp, line 12.
Starting program: /home/simark/build/binutils-gdb/gdb/a.out

Temporary breakpoint 1, main () at test.cpp:12
=================================================================
==26068==ERROR: AddressSanitizer: heap-use-after-free on address 0x6210003d4100 at pc 0x7fed89a34681 bp 0x7ffd8d185d80 sp 0x7ffd8d185528
READ of size 2 at 0x6210003d4100 thread T0
    #0 0x7fed89a34680 in __interceptor_strlen /build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:301
    #1 0x55b6edf6c2f7 in std::char_traits<char>::length(char const*) /usr/include/c++/8.2.1/bits/char_traits.h:320
    #2 0x55b6edf6c9b2 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) /usr/include/c++/8.2.1/bits/basic_string.h:516
    #3 0x55b6ef09121b in source_cache::get_source_lines(symtab*, int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) /home/simark/src/binutils-gdb/gdb/source-cache.c:214
    #4 0x55b6ef0a15cb in print_source_lines_base /home/simark/src/binutils-gdb/gdb/source.c:1340
    #5 0x55b6ef0a2045 in print_source_lines(symtab*, int, int, enum_flags<print_source_lines_flag>) /home/simark/src/binutils-gdb/gdb/source.c:1415
    #6 0x55b6ef112c87 in print_frame_info(frame_info*, int, print_what, int, int) /home/simark/src/binutils-gdb/gdb/stack.c:914
    #7 0x55b6ef10e90d in print_stack_frame(frame_info*, int, print_what, int) /home/simark/src/binutils-gdb/gdb/stack.c:180
    #8 0x55b6ee9592f8 in print_stop_location /home/simark/src/binutils-gdb/gdb/infrun.c:7853
    #9 0x55b6ee95948f in print_stop_event(ui_out*) /home/simark/src/binutils-gdb/gdb/infrun.c:7870
    #10 0x55b6ef34b962 in tui_on_normal_stop /home/simark/src/binutils-gdb/gdb/tui/tui-interp.c:98
    #11 0x55b6ee01a14d in std::_Function_handler<void (bpstats*, int), void (*)(bpstats*, int)>::_M_invoke(std::_Any_data const&, bpstats*&&, int&&) /usr/include/c++/8.2.1/bits/std_function.h:297
    #12 0x55b6ee965415 in std::function<void (bpstats*, int)>::operator()(bpstats*, int) const /usr/include/c++/8.2.1/bits/std_function.h:687
    #13 0x55b6ee962f1b in gdb::observers::observable<bpstats*, int>::notify(bpstats*, int) const /home/simark/src/binutils-gdb/gdb/common/observable.h:106
    #14 0x55b6ee95a6e7 in normal_stop() /home/simark/src/binutils-gdb/gdb/infrun.c:8142
    #15 0x55b6ee93f236 in fetch_inferior_event(void*) /home/simark/src/binutils-gdb/gdb/infrun.c:3782
    #16 0x55b6ee8f2641 in inferior_event_handler(inferior_event_type, void*) /home/simark/src/binutils-gdb/gdb/inf-loop.c:43
    #17 0x55b6eea2a1f0 in handle_target_event /home/simark/src/binutils-gdb/gdb/linux-nat.c:4358
    #18 0x55b6ee7045f1 in handle_file_event /home/simark/src/binutils-gdb/gdb/event-loop.c:733
    #19 0x55b6ee704e89 in gdb_wait_for_event /home/simark/src/binutils-gdb/gdb/event-loop.c:859
    #20 0x55b6ee7027b5 in gdb_do_one_event() /home/simark/src/binutils-gdb/gdb/event-loop.c:322
    #21 0x55b6ee702907 in start_event_loop() /home/simark/src/binutils-gdb/gdb/event-loop.c:371
    #22 0x55b6eeadfc16 in captured_command_loop /home/simark/src/binutils-gdb/gdb/main.c:331
    #23 0x55b6eeae2ef9 in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1174
    #24 0x55b6eeae30c2 in gdb_main(captured_main_args*) /home/simark/src/binutils-gdb/gdb/main.c:1190
    #25 0x55b6edf4fa89 in main /home/simark/src/binutils-gdb/gdb/gdb.c:32
    #26 0x7fed88ad8222 in __libc_start_main (/usr/lib/libc.so.6+0x24222)
    #27 0x55b6edf4f86d in _start (/home/simark/build/binutils-gdb/gdb/gdb+0x197186d)

0x6210003d4100 is located 0 bytes inside of 4096-byte region [0x6210003d4100,0x6210003d5100)
freed by thread T0 here:
    #0 0x7fed89a8ac19 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:66
    #1 0x55b6edfe12df in xfree<char> /home/simark/src/binutils-gdb/gdb/common/common-utils.h:60
    #2 0x55b6edfea675 in gdb::xfree_deleter<char>::operator()(char*) const /home/simark/src/binutils-gdb/gdb/common/gdb_unique_ptr.h:34
    #3 0x55b6edfe532c in std::unique_ptr<char, gdb::xfree_deleter<char> >::reset(char*) /usr/include/c++/8.2.1/bits/unique_ptr.h:382
    #4 0x55b6edfe7329 in std::unique_ptr<char, gdb::xfree_deleter<char> >::operator=(std::unique_ptr<char, gdb::xfree_deleter<char> >&&) /usr/include/c++/8.2.1/bits/unique_ptr.h:289
    #5 0x55b6ef09ec2b in find_and_open_source(char const*, char const*, std::unique_ptr<char, gdb::xfree_deleter<char> >*) /home/simark/src/binutils-gdb/gdb/source.c:990
    #6 0x55b6ef09f56a in open_source_file(symtab*) /home/simark/src/binutils-gdb/gdb/source.c:1069
    #7 0x55b6ef090f78 in source_cache::get_source_lines(symtab*, int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) /home/simark/src/binutils-gdb/gdb/source-cache.c:205
    #8 0x55b6ef0a15cb in print_source_lines_base /home/simark/src/binutils-gdb/gdb/source.c:1340
    #9 0x55b6ef0a2045 in print_source_lines(symtab*, int, int, enum_flags<print_source_lines_flag>) /home/simark/src/binutils-gdb/gdb/source.c:1415
    #10 0x55b6ef112c87 in print_frame_info(frame_info*, int, print_what, int, int) /home/simark/src/binutils-gdb/gdb/stack.c:914
    #11 0x55b6ef10e90d in print_stack_frame(frame_info*, int, print_what, int) /home/simark/src/binutils-gdb/gdb/stack.c:180
    #12 0x55b6ee9592f8 in print_stop_location /home/simark/src/binutils-gdb/gdb/infrun.c:7853
    #13 0x55b6ee95948f in print_stop_event(ui_out*) /home/simark/src/binutils-gdb/gdb/infrun.c:7870
    #14 0x55b6ef34b962 in tui_on_normal_stop /home/simark/src/binutils-gdb/gdb/tui/tui-interp.c:98
    #15 0x55b6ee01a14d in std::_Function_handler<void (bpstats*, int), void (*)(bpstats*, int)>::_M_invoke(std::_Any_data const&, bpstats*&&, int&&) /usr/include/c++/8.2.1/bits/std_function.h:297
    #16 0x55b6ee965415 in std::function<void (bpstats*, int)>::operator()(bpstats*, int) const /usr/include/c++/8.2.1/bits/std_function.h:687
    #17 0x55b6ee962f1b in gdb::observers::observable<bpstats*, int>::notify(bpstats*, int) const /home/simark/src/binutils-gdb/gdb/common/observable.h:106
    #18 0x55b6ee95a6e7 in normal_stop() /home/simark/src/binutils-gdb/gdb/infrun.c:8142
    #19 0x55b6ee93f236 in fetch_inferior_event(void*) /home/simark/src/binutils-gdb/gdb/infrun.c:3782
    #20 0x55b6ee8f2641 in inferior_event_handler(inferior_event_type, void*) /home/simark/src/binutils-gdb/gdb/inf-loop.c:43
    #21 0x55b6eea2a1f0 in handle_target_event /home/simark/src/binutils-gdb/gdb/linux-nat.c:4358
    #22 0x55b6ee7045f1 in handle_file_event /home/simark/src/binutils-gdb/gdb/event-loop.c:733
    #23 0x55b6ee704e89 in gdb_wait_for_event /home/simark/src/binutils-gdb/gdb/event-loop.c:859
    #24 0x55b6ee7027b5 in gdb_do_one_event() /home/simark/src/binutils-gdb/gdb/event-loop.c:322
    #25 0x55b6ee702907 in start_event_loop() /home/simark/src/binutils-gdb/gdb/event-loop.c:371
    #26 0x55b6eeadfc16 in captured_command_loop /home/simark/src/binutils-gdb/gdb/main.c:331
    #27 0x55b6eeae2ef9 in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1174
    #28 0x55b6eeae30c2 in gdb_main(captured_main_args*) /home/simark/src/binutils-gdb/gdb/main.c:1190
    #29 0x55b6edf4fa89 in main /home/simark/src/binutils-gdb/gdb/gdb.c:32

previously allocated by thread T0 here:
    #0 0x7fed89a8b019 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:86
    #1 0x7fed88af983f in realpath@@GLIBC_2.3 (/usr/lib/libc.so.6+0x4583f)
    #2 0x7fed899dbbbc in __interceptor_canonicalize_file_name /build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:3297
    #3 0x55b6ee376a03 in gdb_realpath(char const*) /home/simark/src/binutils-gdb/gdb/common/pathstuff.c:72
    #4 0x55b6ef09ec12 in find_and_open_source(char const*, char const*, std::unique_ptr<char, gdb::xfree_deleter<char> >*) /home/simark/src/binutils-gdb/gdb/source.c:990
    #5 0x55b6ef09f56a in open_source_file(symtab*) /home/simark/src/binutils-gdb/gdb/source.c:1069
    #6 0x55b6ef0a0f12 in print_source_lines_base /home/simark/src/binutils-gdb/gdb/source.c:1270
    #7 0x55b6ef0a2045 in print_source_lines(symtab*, int, int, enum_flags<print_source_lines_flag>) /home/simark/src/binutils-gdb/gdb/source.c:1415
    #8 0x55b6ef112c87 in print_frame_info(frame_info*, int, print_what, int, int) /home/simark/src/binutils-gdb/gdb/stack.c:914
    #9 0x55b6ef10e90d in print_stack_frame(frame_info*, int, print_what, int) /home/simark/src/binutils-gdb/gdb/stack.c:180
    #10 0x55b6ee9592f8 in print_stop_location /home/simark/src/binutils-gdb/gdb/infrun.c:7853
    #11 0x55b6ee95948f in print_stop_event(ui_out*) /home/simark/src/binutils-gdb/gdb/infrun.c:7870
    #12 0x55b6ef34b962 in tui_on_normal_stop /home/simark/src/binutils-gdb/gdb/tui/tui-interp.c:98
    #13 0x55b6ee01a14d in std::_Function_handler<void (bpstats*, int), void (*)(bpstats*, int)>::_M_invoke(std::_Any_data const&, bpstats*&&, int&&) /usr/include/c++/8.2.1/bits/std_function.h:297
    #14 0x55b6ee965415 in std::function<void (bpstats*, int)>::operator()(bpstats*, int) const /usr/include/c++/8.2.1/bits/std_function.h:687
    #15 0x55b6ee962f1b in gdb::observers::observable<bpstats*, int>::notify(bpstats*, int) const /home/simark/src/binutils-gdb/gdb/common/observable.h:106
    #16 0x55b6ee95a6e7 in normal_stop() /home/simark/src/binutils-gdb/gdb/infrun.c:8142
    #17 0x55b6ee93f236 in fetch_inferior_event(void*) /home/simark/src/binutils-gdb/gdb/infrun.c:3782
    #18 0x55b6ee8f2641 in inferior_event_handler(inferior_event_type, void*) /home/simark/src/binutils-gdb/gdb/inf-loop.c:43
    #19 0x55b6eea2a1f0 in handle_target_event /home/simark/src/binutils-gdb/gdb/linux-nat.c:4358
    #20 0x55b6ee7045f1 in handle_file_event /home/simark/src/binutils-gdb/gdb/event-loop.c:733
    #21 0x55b6ee704e89 in gdb_wait_for_event /home/simark/src/binutils-gdb/gdb/event-loop.c:859
    #22 0x55b6ee7027b5 in gdb_do_one_event() /home/simark/src/binutils-gdb/gdb/event-loop.c:322
    #23 0x55b6ee702907 in start_event_loop() /home/simark/src/binutils-gdb/gdb/event-loop.c:371
    #24 0x55b6eeadfc16 in captured_command_loop /home/simark/src/binutils-gdb/gdb/main.c:331
    #25 0x55b6eeae2ef9 in captured_main /home/simark/src/binutils-gdb/gdb/main.c:1174
    #26 0x55b6eeae30c2 in gdb_main(captured_main_args*) /home/simark/src/binutils-gdb/gdb/main.c:1190
    #27 0x55b6edf4fa89 in main /home/simark/src/binutils-gdb/gdb/gdb.c:32
    #28 0x7fed88ad8222 in __libc_start_main (/usr/lib/libc.so.6+0x24222)

gdb/ChangeLog:

	* source-cache.c (source_cache::get_source_lines): Re-read
	fullname after calling open_source_file.
2019-03-25 20:32:41 -04:00
Eli Zaretskii ab42892fb7 Fix vertical scrolling of TUI source window
gdb/ChangeLog:
2019-03-16  Eli Zaretskii  <eliz@gnu.org>

	* source-cache.c (source_cache::get_source_lines): Call
	find_source_lines to initialize s->nlines.  This fixes vertical
	scrolling of TUI source window when the DOWN arrow is pressed.
2019-03-16 19:53:46 +02:00
Tom Tromey 3b336828de Avoid a crash in source_cache::extract_lines
If the first requested line is larger than the number of lines in the
source buffer, source_cache::extract_lines could crash, because it
would try to pass string::npos" to string::substr.

This patch avoids the crash by checking for this case.

This version of the patch changes get_source_lines to return
std::string.

gdb/ChangeLog
2019-03-14  Tom Tromey  <tromey@adacore.com>

	* source-cache.h (class source_cache) <get_source_lines>: Return
	std::string.
	* source-cache.c (source_cache::extract_lines): Handle case where
	first_pos==npos.  Return std::string.
	(source_cache::get_source_lines): Update.
2019-03-14 05:47:11 -06:00
Tom Tromey d085f98901 Add the "set style source" command
This adds "set style source" (and "show style source") commands.  This
gives the user control over whether source code is highlighted.

gdb/ChangeLog
2019-03-14  Tom Tromey  <tromey@adacore.com>

	* NEWS: Add item for "style sources" commands.
	* source-cache.c (source_cache::get_source_lines): Check
	source_styling.
	* cli/cli-style.c (source_styling): New global.
	(_initialize_cli_style): Add "style sources" commands.
	(show_style_sources): New function.
	* cli/cli-style.h (source_styling): Declare.

gdb/doc/ChangeLog
2019-03-14  Tom Tromey  <tromey@adacore.com>

	* gdb.texinfo (Output Styling): Document "set style source" and
	"show style source".

gdb/testsuite/ChangeLog
2019-03-14  Tom Tromey  <tromey@adacore.com>

	* gdb.base/style.exp: Add "set style sources" test.
2019-03-14 05:47:11 -06:00
Eli Zaretskii 3a3508220e Fix MinGW build with source-highlight
gdb/ChangeLog
2019-03-12  Eli Zaretskii  <eliz@gnu.org>

	PR/24325
	* source-cache.c: #undef open and close, to avoid unresolved
	externals during linking.
2019-03-12 19:47:23 +02:00
Joel Brobecker 42a4f53d2b Update copyright year range in all GDB files.
This commit applies all changes made after running the gdb/copyright.py
script.

Note that one file was flagged by the script, due to an invalid
copyright header
(gdb/unittests/basic_string_view/element_access/char/empty.cc).
As the file was copied from GCC's libstdc++-v3 testsuite, this commit
leaves this file untouched for the time being; a patch to fix the header
was sent to gcc-patches first.

gdb/ChangeLog:

	Update copyright year range in all GDB files.
2019-01-01 10:01:51 +04:00
Tom Tromey 64c45143db Fix the build when GNU Source Highlight is not available
The builder pointed out that, when GNU Source Highlight is not
available, get_language_name is not used.  This patch makes it
conditional, fixing the build problem.

gdb/ChangeLog
2018-12-28  Tom Tromey  <tom@tromey.com>

	* source-cache.c (get_language_name): Conditionally compile.
2018-12-28 21:07:24 -07:00
Tom Tromey 62f29fda90 Highlight source code using GNU Source Highlight
This changes gdb to highlight source using GNU Source Highlight, if it
is available.

This affects the output of the "list" command and also the TUI source
window.

No new test because I didn't see a way to make it work when Source
Highlight is not found.

gdb/ChangeLog
2018-12-28  Tom Tromey  <tom@tromey.com>

	* utils.h (can_emit_style_escape): Declare.
	* utils.c (can_emit_style_escape): No longer static.
	* cli/cli-style.c (set_style_enabled): New function.
	(_initialize_cli_style): Use it.
	* tui/tui-winsource.c (tui_show_source_line): Use tui_puts.
	(tui_alloc_source_buffer): Change how source lines are allocated.
	* tui/tui-source.c (copy_source_line): New function.
	(tui_set_source_content): Use source cache.
	* tui/tui-io.h (tui_puts): Update.
	* tui/tui-io.c (tui_puts_internal): Add window parameter.
	(tui_puts): Likewise.
	(tui_redisplay_readline): Update.
	* tui/tui-data.c (free_content_elements): Change how source window
	contents are freed.
	* source.c (forget_cached_source_info): Clear the source cache.
	(print_source_lines_base): Use the source cache.
	* source-cache.h: New file.
	* source-cache.c: New file.
	* configure.ac: Check for GNU Source Highlight library.
	* configure: Update.
	* config.in: Update.
	* Makefile.in (SRCHIGH_LIBS, SRCHIGH_CFLAGS): New variables.
	(INTERNAL_CFLAGS_BASE): Add SRCHIGH_CFLAGS.
	(CLIBS): Add SRCHIGH_LIBS.
	(COMMON_SFILES): Add source-cache.c.
	(HFILES_NO_SRCDIR): Add source-cache.h.
2018-12-28 12:49:54 -07:00