-# Copyright 2015 Free Software Foundation, Inc.
+# Copyright 2015-2020 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
# Test the setting of "history size" via $HOME/.gdbinit
+# This test depends on being able to set $HOME and $GDBHISTSIZE.
+# We cannot expect remote hosts to see environment variables set on the
+# local machine.
+
+# Do not run if gdb debug is enabled - it interferes with the command history.
+if [gdb_debug_enabled] {
+ untested "debug is enabled"
+ return 0
+}
+
+if { [is_remote host] } {
+ unsupported "can't set environment variables on remote host"
+ return -1
+}
# Check that the history size is properly set to SIZE when reading the .gdbinit
-# file located in HOME.
+# file located in HOME with the environment variable GDBHISTSIZE optionally
+# set to GDBHISTSIZE_VAL.
-proc test_gdbinit_history_setting { home size } {
+proc test_gdbinit_history_setting { home size { gdbhistsize_val "-" } } {
global env
global INTERNAL_GDBFLAGS
global srcdir
global subdir
- array set old_env [array get env]
+ save_vars { INTERNAL_GDBFLAGS env(GDBHISTFILE) env(GDBHISTSIZE) env(HOME) } {
+ set env(HOME) "$srcdir/$subdir/$home"
- set env(HOME) "$srcdir/$subdir/$home"
+ # These environment variables take precedence over whatever
+ # history size is set in .gdbinit. Make sure the former is not
+ # set.
+ unset -nocomplain env(GDBHISTFILE)
+ unset -nocomplain env(GDBHISTSIZE)
- # The HISTSIZE environment variable takes precedence over whatever
- # history size is set in .gdbinit. Make sure the former is not
- # set.
- unset -nocomplain env(HISTSIZE)
+ if { $gdbhistsize_val != "-" } {
+ set env(GDBHISTSIZE) $gdbhistsize_val
+ }
+
+ set INTERNAL_GDBFLAGS [string map {"-nx" ""} $INTERNAL_GDBFLAGS]
- set saved_internal_gdbflags $INTERNAL_GDBFLAGS
- set INTERNAL_GDBFLAGS [string map {"-nx" ""} $INTERNAL_GDBFLAGS]
+ set prefix "home=$home"
+ if { $gdbhistsize_val != "-" } {
+ append prefix " gdbhistsize=$gdbhistsize_val"
+ }
- with_test_prefix "home=$home" {
- gdb_exit
- gdb_start
+ with_test_prefix $prefix {
+ gdb_exit
+ gdb_start
- gdb_test "show history size" "The size of the command history is $size."
+ gdb_test "show history size" "The size of the command history is $size."
- if { $size == "0" } {
- gdb_test_no_output "show commands"
- } elseif { $size != "1" } {
- gdb_test "show commands" " . show history size\r\n . show commands"
+ if { $size == "0" } {
+ gdb_test_no_output "show commands"
+ } elseif { $size != "1" } {
+ gdb_test "show commands" " . show history size\r\n . show commands"
+ }
}
}
+}
+
+# Check that the history file does not get truncated to zero when a gdbinit
+# file sets the history size to unlimited.
+
+proc test_no_truncation_of_unlimited_history_file { } {
+ global env
+ global INTERNAL_GDBFLAGS
+
+ save_vars { INTERNAL_GDBFLAGS env(GDBHISTFILE) env(GDBHISTSIZE) } {
+ # These environment variables take precedence over whatever
+ # history size is set in .gdbinit. Make sure the former is not
+ # set.
+ unset -nocomplain env(GDBHISTFILE)
+ unset -nocomplain env(GDBHISTSIZE)
+
+ set temp_gdbinit [standard_output_file "gdbinit-history.gdbinit"]
+ set temp_histfile [standard_output_file "gdbinit-history.gdb_history"]
+ file delete $temp_gdbinit
+ file delete $temp_histfile
+
+ set fd [open $temp_gdbinit "w"]
+ puts $fd "set history size unlimited\n"
+ puts $fd "set history filename $temp_histfile\n"
+ puts $fd "set history save\n"
+ close $fd
+
+ append INTERNAL_GDBFLAGS " -x $temp_gdbinit"
+
+ # We have to start then exit GDB twice: the first time to test the creation
+ # of the initial history file, and the second time to test appending to it.
+ # In either case the initial "print 1" command should persist through the
+ # history file.
+ with_test_prefix "truncation" {
+ gdb_exit
+ gdb_start
+ gdb_test "print 1"
+
+ with_test_prefix "creating" {
+ gdb_exit
+ gdb_start
+ gdb_test "server show commands" " . print 1.*"
+ }
+
+ with_test_prefix "appending" {
+ gdb_exit
+ gdb_start
+ gdb_test "server show commands" " . print 1.*"
+ }
+ }
+ }
+}
+
+# Check that the current command history matches HIST, which is a list
+# of commands, oldest fist.
+proc check_history { hist } {
+
+ # The show commands we issue here always appears last in the
+ # commands list.
+ lappend hist "show commands"
+
+ # Number all of the entries in the HIST list and convert the list
+ # into a pattern to match against GDB.
+ set hist_lines [list]
+ set idx 1
+ foreach h $hist {
+ lappend hist_lines " $idx $h"
+ incr idx
+ }
+ set pattern [eval multi_line $hist_lines]
- set INTERNAL_GDBFLAGS $saved_internal_gdbflags
+ # Check the history.
+ gdb_test "show commands" "$pattern.*"
+}
+
+# Run 'show history filename' and check the output contains the
+# filename matching PATTERN, unless, PATTERN is the empty string, in
+# which case match a different output that GDB will give if the
+# history filename is the empty string.
+#
+# TESTNAME is the name for the test, which defaults to the command run
+# in the test.
+proc check_history_filename { pattern {testname ""} } {
- array set env [array get old_env]
+ set cmd "show history filename"
+ if { $testname == "" } {
+ set testname $cmd
+ }
+
+ if { $pattern == "" } {
+ gdb_test $cmd \
+ "There is no filename currently set for recording the command history in." \
+ $testname
+ } else {
+ gdb_test $cmd \
+ "The filename in which to record the command history is \"$pattern\"\." \
+ $testname
+ }
+}
+
+# Tests for how GDB handles setting the history filename to the empty
+# string.
+proc test_empty_history_filename { } {
+ global env
+ global gdb_prompt
+
+ set common_history [list "set height 0" "set width 0"]
+
+ set test_dir [standard_output_file history_test]
+ remote_exec host "mkdir -p $test_dir"
+ foreach entry { { ".gdb_history" "xxxxx" } \
+ { "_gdb_history" "xxxxx" } \
+ { "alt_history" "yyyyy" } } {
+ set fn [lindex $entry 0]
+ set content [lindex $entry 1]
+ set fd [open [standard_output_file "$test_dir/$fn"] w]
+ puts $fd "$content"
+ close $fd
+ }
+
+ with_cwd "$test_dir" {
+ with_test_prefix "load default history file" {
+ # Start GDB and see that the history file was loaded
+ # correctly.
+ gdb_exit
+ gdb_start
+ check_history [concat "xxxxx" $common_history]
+ check_history_filename ".*/.gdb_history"
+ }
+
+ with_test_prefix "load GDBHISTFILE history file" {
+ # Now restart GDB with GDBHISTFILE set to see that the
+ # "other" history file is loaded.
+ save_vars { env(GDBHISTFILE) } {
+ setenv GDBHISTFILE \
+ "$test_dir/alt_history"
+ gdb_exit
+ gdb_start
+ check_history [concat "yyyyy" $common_history]
+ check_history_filename ".*/alt_history"
+ }
+ }
+
+ with_test_prefix "GDBHISTFILE is empty" {
+ # Now restart GDB with GDBHISTFILE set to indicate don't
+ # load any history file, check none was loaded.
+ save_vars { env(GDBHISTFILE) } {
+ setenv GDBHISTFILE ""
+ gdb_exit
+ gdb_start
+ check_history $common_history
+ check_history_filename ""
+ }
+
+ # Check that 'show history save' does the right thing when
+ # the history filename is the empty string.
+ gdb_test_no_output "set history save off" \
+ "ensure history save is off initially"
+ gdb_test "show history save" \
+ "Saving of the history record on exit is off." \
+ "Check history save is off"
+ gdb_test_no_output "set history save on"
+ gdb_test "show history save" \
+ "Saving of the history is disabled due to the value of 'history filename'." \
+ "Check history save is off due to filename"
+ gdb_test_no_output \
+ "set history filename $test_dir/alt_history" \
+ "set history filename at the command line"
+ check_history_filename ".*/alt_history" \
+ "check filename after setting at the command line"
+ gdb_test "show history save" \
+ "Saving of the history record on exit is on." \
+ "Check history save is on"
+ gdb_test_no_output "set history filename"
+ gdb_test "show history save" \
+ "Saving of the history is disabled due to the value of 'history filename'." \
+ "Check history save is off due to filename again"
+ gdb_test_no_output "set history save off"
+ }
+
+ with_test_prefix "Use -ex to clear history file" {
+ # Now restart GDB with the command line '-ex' to indicate
+ # no history file should be loaded.
+ gdb_exit
+ if {[gdb_spawn_with_cmdline_opts \
+ "-ex \"set history filename\""] != 0} {
+ fail "spawn"
+ return
+ }
+ set test "initial prompt"
+ gdb_test_multiple "" $test {
+ -re ".*$gdb_prompt $" {
+ pass "$test"
+ }
+ }
+ check_history [list]
+ check_history_filename ""
+ }
+ }
}
test_gdbinit_history_setting "gdbinit-history/unlimited" "unlimited"
test_gdbinit_history_setting "gdbinit-history/zero" "0"
+
+test_no_truncation_of_unlimited_history_file
+
+# A valid GDBHISTSIZE value overrides the setting inside the .gdbinit file; an
+# invalid GDBHISTSIZE value is ignored, falling back on the setting inside the
+# .gdbinit file.
+test_gdbinit_history_setting "gdbinit-history/unlimited" "1000" "1000"
+test_gdbinit_history_setting "gdbinit-history/unlimited" "unlimited" "foo"
+
+# Check handling of empty history filename.
+test_empty_history_filename