12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439 |
- /* Top level stuff for GDB, the GNU debugger.
- Copyright (C) 1999-2022 Free Software Foundation, Inc.
- Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
- 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 "top.h"
- #include "inferior.h"
- #include "infrun.h"
- #include "target.h"
- #include "terminal.h"
- #include "gdbsupport/event-loop.h"
- #include "event-top.h"
- #include "interps.h"
- #include <signal.h>
- #include "cli/cli-script.h" /* for reset_command_nest_depth */
- #include "main.h"
- #include "gdbthread.h"
- #include "observable.h"
- #include "gdbcmd.h" /* for dont_repeat() */
- #include "annotate.h"
- #include "maint.h"
- #include "gdbsupport/buffer.h"
- #include "ser-event.h"
- #include "gdbsupport/gdb_select.h"
- #include "gdbsupport/gdb-sigmask.h"
- #include "async-event.h"
- #include "bt-utils.h"
- #include "pager.h"
- /* readline include files. */
- #include "readline/readline.h"
- #include "readline/history.h"
- /* readline defines this. */
- #undef savestring
- static std::string top_level_prompt ();
- /* Signal handlers. */
- #ifdef SIGQUIT
- static void handle_sigquit (int sig);
- #endif
- #ifdef SIGHUP
- static void handle_sighup (int sig);
- #endif
- /* Functions to be invoked by the event loop in response to
- signals. */
- #if defined (SIGQUIT) || defined (SIGHUP)
- static void async_do_nothing (gdb_client_data);
- #endif
- #ifdef SIGHUP
- static void async_disconnect (gdb_client_data);
- #endif
- #ifdef SIGTSTP
- static void async_sigtstp_handler (gdb_client_data);
- #endif
- static void async_sigterm_handler (gdb_client_data arg);
- /* Instead of invoking (and waiting for) readline to read the command
- line and pass it back for processing, we use readline's alternate
- interface, via callback functions, so that the event loop can react
- to other event sources while we wait for input. */
- /* Important variables for the event loop. */
- /* This is used to determine if GDB is using the readline library or
- its own simplified form of readline. It is used by the asynchronous
- form of the set editing command.
- ezannoni: as of 1999-04-29 I expect that this
- variable will not be used after gdb is changed to use the event
- loop as default engine, and event-top.c is merged into top.c. */
- bool set_editing_cmd_var;
- /* This is used to display the notification of the completion of an
- asynchronous execution command. */
- bool exec_done_display_p = false;
- /* Used by the stdin event handler to compensate for missed stdin events.
- Setting this to a non-zero value inside an stdin callback makes the callback
- run again. */
- int call_stdin_event_handler_again_p;
- /* When true GDB will produce a minimal backtrace when a fatal signal is
- reached (within GDB code). */
- static bool bt_on_fatal_signal = GDB_PRINT_INTERNAL_BACKTRACE_INIT_ON;
- /* Implement 'maintenance show backtrace-on-fatal-signal'. */
- static void
- show_bt_on_fatal_signal (struct ui_file *file, int from_tty,
- struct cmd_list_element *cmd, const char *value)
- {
- gdb_printf (file, _("Backtrace on a fatal signal is %s.\n"), value);
- }
- /* Signal handling variables. */
- /* Each of these is a pointer to a function that the event loop will
- invoke if the corresponding signal has received. The real signal
- handlers mark these functions as ready to be executed and the event
- loop, in a later iteration, calls them. See the function
- invoke_async_signal_handler. */
- static struct async_signal_handler *sigint_token;
- #ifdef SIGHUP
- static struct async_signal_handler *sighup_token;
- #endif
- #ifdef SIGQUIT
- static struct async_signal_handler *sigquit_token;
- #endif
- #ifdef SIGTSTP
- static struct async_signal_handler *sigtstp_token;
- #endif
- static struct async_signal_handler *async_sigterm_token;
- /* This hook is called by gdb_rl_callback_read_char_wrapper after each
- character is processed. */
- void (*after_char_processing_hook) (void);
- /* Wrapper function for calling into the readline library. This takes
- care of a couple things:
- - The event loop expects the callback function to have a parameter,
- while readline expects none.
- - Propagation of GDB exceptions/errors thrown from INPUT_HANDLER
- across readline requires special handling.
- On the exceptions issue:
- DWARF-based unwinding cannot cross code built without -fexceptions.
- Any exception that tries to propagate through such code will fail
- and the result is a call to std::terminate. While some ABIs, such
- as x86-64, require all code to be built with exception tables,
- others don't.
- This is a problem when GDB calls some non-EH-aware C library code,
- that calls into GDB again through a callback, and that GDB callback
- code throws a C++ exception. Turns out this is exactly what
- happens with GDB's readline callback.
- In such cases, we must catch and save any C++ exception that might
- be thrown from the GDB callback before returning to the
- non-EH-aware code. When the non-EH-aware function itself returns
- back to GDB, we then rethrow the original C++ exception.
- In the readline case however, the right thing to do is to longjmp
- out of the callback, rather than do a normal return -- there's no
- way for the callback to return to readline an indication that an
- error happened, so a normal return would have rl_callback_read_char
- potentially continue processing further input, redisplay the
- prompt, etc. Instead of raw setjmp/longjmp however, we use our
- sjlj-based TRY/CATCH mechanism, which knows to handle multiple
- levels of active setjmp/longjmp frames, needed in order to handle
- the readline callback recursing, as happens with e.g., secondary
- prompts / queries, through gdb_readline_wrapper. This must be
- noexcept in order to avoid problems with mixing sjlj and
- (sjlj-based) C++ exceptions. */
- static struct gdb_exception
- gdb_rl_callback_read_char_wrapper_noexcept () noexcept
- {
- struct gdb_exception gdb_expt;
- /* C++ exceptions can't normally be thrown across readline (unless
- it is built with -fexceptions, but it won't by default on many
- ABIs). So we instead wrap the readline call with a sjlj-based
- TRY/CATCH, and rethrow the GDB exception once back in GDB. */
- TRY_SJLJ
- {
- rl_callback_read_char ();
- if (after_char_processing_hook)
- (*after_char_processing_hook) ();
- }
- CATCH_SJLJ (ex, RETURN_MASK_ALL)
- {
- gdb_expt = std::move (ex);
- }
- END_CATCH_SJLJ
- return gdb_expt;
- }
- static void
- gdb_rl_callback_read_char_wrapper (gdb_client_data client_data)
- {
- struct gdb_exception gdb_expt
- = gdb_rl_callback_read_char_wrapper_noexcept ();
- /* Rethrow using the normal EH mechanism. */
- if (gdb_expt.reason < 0)
- throw_exception (std::move (gdb_expt));
- }
- /* GDB's readline callback handler. Calls the current INPUT_HANDLER,
- and propagates GDB exceptions/errors thrown from INPUT_HANDLER back
- across readline. See gdb_rl_callback_read_char_wrapper. This must
- be noexcept in order to avoid problems with mixing sjlj and
- (sjlj-based) C++ exceptions. */
- static void
- gdb_rl_callback_handler (char *rl) noexcept
- {
- /* This is static to avoid undefined behavior when calling longjmp
- -- gdb_exception has a destructor with side effects. */
- static struct gdb_exception gdb_rl_expt;
- struct ui *ui = current_ui;
- try
- {
- /* Ensure the exception is reset on each call. */
- gdb_rl_expt = {};
- ui->input_handler (gdb::unique_xmalloc_ptr<char> (rl));
- }
- catch (gdb_exception &ex)
- {
- gdb_rl_expt = std::move (ex);
- }
- /* If we caught a GDB exception, longjmp out of the readline
- callback. There's no other way for the callback to signal to
- readline that an error happened. A normal return would have
- readline potentially continue processing further input, redisplay
- the prompt, etc. (This is what GDB historically did when it was
- a C program.) Note that since we're long jumping, local variable
- dtors are NOT run automatically. */
- if (gdb_rl_expt.reason < 0)
- throw_exception_sjlj (gdb_rl_expt);
- }
- /* Change the function to be invoked every time there is a character
- ready on stdin. This is used when the user sets the editing off,
- therefore bypassing readline, and letting gdb handle the input
- itself, via gdb_readline_no_editing_callback. Also it is used in
- the opposite case in which the user sets editing on again, by
- restoring readline handling of the input.
- NOTE: this operates on input_fd, not instream. If we are reading
- commands from a file, instream will point to the file. However, we
- always read commands from a file with editing off. This means that
- the 'set editing on/off' will have effect only on the interactive
- session. */
- void
- change_line_handler (int editing)
- {
- struct ui *ui = current_ui;
- /* We can only have one instance of readline, so we only allow
- editing on the main UI. */
- if (ui != main_ui)
- return;
- /* Don't try enabling editing if the interpreter doesn't support it
- (e.g., MI). */
- if (!interp_supports_command_editing (top_level_interpreter ())
- || !interp_supports_command_editing (command_interp ()))
- return;
- if (editing)
- {
- gdb_assert (ui == main_ui);
- /* Turn on editing by using readline. */
- ui->call_readline = gdb_rl_callback_read_char_wrapper;
- }
- else
- {
- /* Turn off editing by using gdb_readline_no_editing_callback. */
- if (ui->command_editing)
- gdb_rl_callback_handler_remove ();
- ui->call_readline = gdb_readline_no_editing_callback;
- }
- ui->command_editing = editing;
- }
- /* The functions below are wrappers for rl_callback_handler_remove and
- rl_callback_handler_install that keep track of whether the callback
- handler is installed in readline. This is necessary because after
- handling a target event of a background execution command, we may
- need to reinstall the callback handler if it was removed due to a
- secondary prompt. See gdb_readline_wrapper_line. We don't
- unconditionally install the handler for every target event because
- that also clears the line buffer, thus installing it while the user
- is typing would lose input. */
- /* Whether we've registered a callback handler with readline. */
- static bool callback_handler_installed;
- /* See event-top.h, and above. */
- void
- gdb_rl_callback_handler_remove (void)
- {
- gdb_assert (current_ui == main_ui);
- rl_callback_handler_remove ();
- callback_handler_installed = false;
- }
- /* See event-top.h, and above. Note this wrapper doesn't have an
- actual callback parameter because we always install
- INPUT_HANDLER. */
- void
- gdb_rl_callback_handler_install (const char *prompt)
- {
- gdb_assert (current_ui == main_ui);
- /* Calling rl_callback_handler_install resets readline's input
- buffer. Calling this when we were already processing input
- therefore loses input. */
- gdb_assert (!callback_handler_installed);
- rl_callback_handler_install (prompt, gdb_rl_callback_handler);
- callback_handler_installed = true;
- }
- /* See event-top.h, and above. */
- void
- gdb_rl_callback_handler_reinstall (void)
- {
- gdb_assert (current_ui == main_ui);
- if (!callback_handler_installed)
- {
- /* Passing NULL as prompt argument tells readline to not display
- a prompt. */
- gdb_rl_callback_handler_install (NULL);
- }
- }
- /* Displays the prompt. If the argument NEW_PROMPT is NULL, the
- prompt that is displayed is the current top level prompt.
- Otherwise, it displays whatever NEW_PROMPT is as a local/secondary
- prompt.
- This is used after each gdb command has completed, and in the
- following cases:
- 1. When the user enters a command line which is ended by '\'
- indicating that the command will continue on the next line. In
- that case the prompt that is displayed is the empty string.
- 2. When the user is entering 'commands' for a breakpoint, or
- actions for a tracepoint. In this case the prompt will be '>'
- 3. On prompting for pagination. */
- void
- display_gdb_prompt (const char *new_prompt)
- {
- std::string actual_gdb_prompt;
- annotate_display_prompt ();
- /* Reset the nesting depth used when trace-commands is set. */
- reset_command_nest_depth ();
- /* Do not call the python hook on an explicit prompt change as
- passed to this function, as this forms a secondary/local prompt,
- IE, displayed but not set. */
- if (! new_prompt)
- {
- struct ui *ui = current_ui;
- if (ui->prompt_state == PROMPTED)
- internal_error (__FILE__, __LINE__, _("double prompt"));
- else if (ui->prompt_state == PROMPT_BLOCKED)
- {
- /* This is to trick readline into not trying to display the
- prompt. Even though we display the prompt using this
- function, readline still tries to do its own display if
- we don't call rl_callback_handler_install and
- rl_callback_handler_remove (which readline detects
- because a global variable is not set). If readline did
- that, it could mess up gdb signal handlers for SIGINT.
- Readline assumes that between calls to rl_set_signals and
- rl_clear_signals gdb doesn't do anything with the signal
- handlers. Well, that's not the case, because when the
- target executes we change the SIGINT signal handler. If
- we allowed readline to display the prompt, the signal
- handler change would happen exactly between the calls to
- the above two functions. Calling
- rl_callback_handler_remove(), does the job. */
- if (current_ui->command_editing)
- gdb_rl_callback_handler_remove ();
- return;
- }
- else if (ui->prompt_state == PROMPT_NEEDED)
- {
- /* Display the top level prompt. */
- actual_gdb_prompt = top_level_prompt ();
- ui->prompt_state = PROMPTED;
- }
- }
- else
- actual_gdb_prompt = new_prompt;
- if (current_ui->command_editing)
- {
- gdb_rl_callback_handler_remove ();
- gdb_rl_callback_handler_install (actual_gdb_prompt.c_str ());
- }
- /* new_prompt at this point can be the top of the stack or the one
- passed in. It can't be NULL. */
- else
- {
- /* Don't use a _filtered function here. It causes the assumed
- character position to be off, since the newline we read from
- the user is not accounted for. */
- printf_unfiltered ("%s", actual_gdb_prompt.c_str ());
- gdb_flush (gdb_stdout);
- }
- }
- /* Return the top level prompt, as specified by "set prompt", possibly
- overridden by the python gdb.prompt_hook hook, and then composed
- with the prompt prefix and suffix (annotations). */
- static std::string
- top_level_prompt (void)
- {
- /* Give observers a chance of changing the prompt. E.g., the python
- `gdb.prompt_hook' is installed as an observer. */
- gdb::observers::before_prompt.notify (get_prompt ().c_str ());
- const std::string &prompt = get_prompt ();
- if (annotation_level >= 2)
- {
- /* Prefix needs to have new line at end. */
- const char prefix[] = "\n\032\032pre-prompt\n";
- /* Suffix needs to have a new line at end and \032 \032 at
- beginning. */
- const char suffix[] = "\n\032\032prompt\n";
- return std::string (prefix) + prompt.c_str () + suffix;
- }
- return prompt;
- }
- /* See top.h. */
- struct ui *main_ui;
- struct ui *current_ui;
- struct ui *ui_list;
- /* Get a pointer to the current UI's line buffer. This is used to
- construct a whole line of input from partial input. */
- static struct buffer *
- get_command_line_buffer (void)
- {
- return ¤t_ui->line_buffer;
- }
- /* When there is an event ready on the stdin file descriptor, instead
- of calling readline directly throught the callback function, or
- instead of calling gdb_readline_no_editing_callback, give gdb a
- chance to detect errors and do something. */
- void
- stdin_event_handler (int error, gdb_client_data client_data)
- {
- struct ui *ui = (struct ui *) client_data;
- if (error)
- {
- /* Switch to the main UI, so diagnostics always go there. */
- current_ui = main_ui;
- delete_file_handler (ui->input_fd);
- if (main_ui == ui)
- {
- /* If stdin died, we may as well kill gdb. */
- gdb_printf (gdb_stderr, _("error detected on stdin\n"));
- quit_command ((char *) 0, 0);
- }
- else
- {
- /* Simply delete the UI. */
- delete ui;
- }
- }
- else
- {
- /* Switch to the UI whose input descriptor woke up the event
- loop. */
- current_ui = ui;
- /* This makes sure a ^C immediately followed by further input is
- always processed in that order. E.g,. with input like
- "^Cprint 1\n", the SIGINT handler runs, marks the async
- signal handler, and then select/poll may return with stdin
- ready, instead of -1/EINTR. The
- gdb.base/double-prompt-target-event-error.exp test exercises
- this. */
- QUIT;
- do
- {
- call_stdin_event_handler_again_p = 0;
- ui->call_readline (client_data);
- }
- while (call_stdin_event_handler_again_p != 0);
- }
- }
- /* See top.h. */
- void
- ui_register_input_event_handler (struct ui *ui)
- {
- add_file_handler (ui->input_fd, stdin_event_handler, ui,
- string_printf ("ui-%d", ui->num), true);
- }
- /* See top.h. */
- void
- ui_unregister_input_event_handler (struct ui *ui)
- {
- delete_file_handler (ui->input_fd);
- }
- /* Re-enable stdin after the end of an execution command in
- synchronous mode, or after an error from the target, and we aborted
- the exec operation. */
- void
- async_enable_stdin (void)
- {
- struct ui *ui = current_ui;
- if (ui->prompt_state == PROMPT_BLOCKED)
- {
- target_terminal::ours ();
- ui_register_input_event_handler (ui);
- ui->prompt_state = PROMPT_NEEDED;
- }
- }
- /* Disable reads from stdin (the console) marking the command as
- synchronous. */
- void
- async_disable_stdin (void)
- {
- struct ui *ui = current_ui;
- ui->prompt_state = PROMPT_BLOCKED;
- delete_file_handler (ui->input_fd);
- }
- /* Handle a gdb command line. This function is called when
- handle_line_of_input has concatenated one or more input lines into
- a whole command. */
- void
- command_handler (const char *command)
- {
- struct ui *ui = current_ui;
- const char *c;
- if (ui->instream == ui->stdin_stream)
- reinitialize_more_filter ();
- scoped_command_stats stat_reporter (true);
- /* Do not execute commented lines. */
- for (c = command; *c == ' ' || *c == '\t'; c++)
- ;
- if (c[0] != '#')
- {
- execute_command (command, ui->instream == ui->stdin_stream);
- /* Do any commands attached to breakpoint we stopped at. */
- bpstat_do_actions ();
- }
- }
- /* Append RL, an input line returned by readline or one of its
- emulations, to CMD_LINE_BUFFER. Returns the command line if we
- have a whole command line ready to be processed by the command
- interpreter or NULL if the command line isn't complete yet (input
- line ends in a backslash). */
- static char *
- command_line_append_input_line (struct buffer *cmd_line_buffer, const char *rl)
- {
- char *cmd;
- size_t len;
- len = strlen (rl);
- if (len > 0 && rl[len - 1] == '\\')
- {
- /* Don't copy the backslash and wait for more. */
- buffer_grow (cmd_line_buffer, rl, len - 1);
- cmd = NULL;
- }
- else
- {
- /* Copy whole line including terminating null, and we're
- done. */
- buffer_grow (cmd_line_buffer, rl, len + 1);
- cmd = cmd_line_buffer->buffer;
- }
- return cmd;
- }
- /* Handle a line of input coming from readline.
- If the read line ends with a continuation character (backslash),
- save the partial input in CMD_LINE_BUFFER (except the backslash),
- and return NULL. Otherwise, save the partial input and return a
- pointer to CMD_LINE_BUFFER's buffer (null terminated), indicating a
- whole command line is ready to be executed.
- Returns EOF on end of file.
- If REPEAT, handle command repetitions:
- - If the input command line is NOT empty, the command returned is
- saved using save_command_line () so that it can be repeated later.
- - OTOH, if the input command line IS empty, return the saved
- command instead of the empty input line.
- */
- char *
- handle_line_of_input (struct buffer *cmd_line_buffer,
- const char *rl, int repeat,
- const char *annotation_suffix)
- {
- struct ui *ui = current_ui;
- int from_tty = ui->instream == ui->stdin_stream;
- char *p1;
- char *cmd;
- if (rl == NULL)
- return (char *) EOF;
- cmd = command_line_append_input_line (cmd_line_buffer, rl);
- if (cmd == NULL)
- return NULL;
- /* We have a complete command line now. Prepare for the next
- command, but leave ownership of memory to the buffer . */
- cmd_line_buffer->used_size = 0;
- if (from_tty && annotation_level > 1)
- printf_unfiltered (("\n\032\032post-%s\n"), annotation_suffix);
- #define SERVER_COMMAND_PREFIX "server "
- server_command = startswith (cmd, SERVER_COMMAND_PREFIX);
- if (server_command)
- {
- /* Note that we don't call `save_command_line'. Between this
- and the check in dont_repeat, this insures that repeating
- will still do the right thing. */
- return cmd + strlen (SERVER_COMMAND_PREFIX);
- }
- /* Do history expansion if that is wished. */
- if (history_expansion_p && from_tty && input_interactive_p (current_ui))
- {
- char *cmd_expansion;
- int expanded;
- expanded = history_expand (cmd, &cmd_expansion);
- gdb::unique_xmalloc_ptr<char> history_value (cmd_expansion);
- if (expanded)
- {
- size_t len;
- /* Print the changes. */
- printf_unfiltered ("%s\n", history_value.get ());
- /* If there was an error, call this function again. */
- if (expanded < 0)
- return cmd;
- /* history_expand returns an allocated string. Just replace
- our buffer with it. */
- len = strlen (history_value.get ());
- xfree (buffer_finish (cmd_line_buffer));
- cmd_line_buffer->buffer = history_value.get ();
- cmd_line_buffer->buffer_size = len + 1;
- cmd = history_value.release ();
- }
- }
- /* If we just got an empty line, and that is supposed to repeat the
- previous command, return the previously saved command. */
- for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++)
- ;
- if (repeat && *p1 == '\0')
- return get_saved_command_line ();
- /* Add command to history if appropriate. Note: lines consisting
- solely of comments are also added to the command history. This
- is useful when you type a command, and then realize you don't
- want to execute it quite yet. You can comment out the command
- and then later fetch it from the value history and remove the
- '#'. The kill ring is probably better, but some people are in
- the habit of commenting things out. */
- if (*cmd != '\0' && from_tty && input_interactive_p (current_ui))
- gdb_add_history (cmd);
- /* Save into global buffer if appropriate. */
- if (repeat)
- {
- save_command_line (cmd);
- return get_saved_command_line ();
- }
- else
- return cmd;
- }
- /* Handle a complete line of input. This is called by the callback
- mechanism within the readline library. Deal with incomplete
- commands as well, by saving the partial input in a global
- buffer.
- NOTE: This is the asynchronous version of the command_line_input
- function. */
- void
- command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl)
- {
- struct buffer *line_buffer = get_command_line_buffer ();
- struct ui *ui = current_ui;
- char *cmd;
- cmd = handle_line_of_input (line_buffer, rl.get (), 1, "prompt");
- if (cmd == (char *) EOF)
- {
- /* stdin closed. The connection with the terminal is gone.
- This happens at the end of a testsuite run, after Expect has
- hung up but GDB is still alive. In such a case, we just quit
- gdb killing the inferior program too. This also happens if the
- user sends EOF, which is usually bound to ctrl+d.
- What we want to do in this case is print "quit" after the GDB
- prompt, as if the user had just typed "quit" and pressed return.
- This used to work just fine, but unfortunately, doesn't play well
- with readline's bracketed paste mode. By the time we get here,
- readline has already sent the control sequence to leave bracketed
- paste mode, and this sequence ends with a '\r' character. As a
- result, if bracketed paste mode is on, and we print quit here,
- then this will overwrite the prompt.
- To work around this issue, when bracketed paste mode is enabled,
- we first print '\n' to move to the next line, and then print the
- quit. This isn't ideal, but avoids corrupting the prompt. */
- const char *value = rl_variable_value ("enable-bracketed-paste");
- if (value != nullptr && strcmp (value, "on") == 0)
- printf_unfiltered ("\n");
- printf_unfiltered ("quit\n");
- execute_command ("quit", 1);
- }
- else if (cmd == NULL)
- {
- /* We don't have a full line yet. Print an empty prompt. */
- display_gdb_prompt ("");
- }
- else
- {
- ui->prompt_state = PROMPT_NEEDED;
- command_handler (cmd);
- if (ui->prompt_state != PROMPTED)
- display_gdb_prompt (0);
- }
- }
- /* Does reading of input from terminal w/o the editing features
- provided by the readline library. Calls the line input handler
- once we have a whole input line. */
- void
- gdb_readline_no_editing_callback (gdb_client_data client_data)
- {
- int c;
- char *result;
- struct buffer line_buffer;
- struct ui *ui = current_ui;
- buffer_init (&line_buffer);
- FILE *stream = ui->instream != nullptr ? ui->instream : ui->stdin_stream;
- gdb_assert (stream != nullptr);
- /* Unbuffer the input stream, so that, later on, the calls to fgetc
- fetch only one char at the time from the stream. The fgetc's will
- get up to the first newline, but there may be more chars in the
- stream after '\n'. If we buffer the input and fgetc drains the
- stream, getting stuff beyond the newline as well, a select, done
- afterwards will not trigger.
- This unbuffering was, at one point, not applied if the input stream
- was a tty, however, the buffering can cause problems, even for a tty,
- in some cases. Please ensure that any changes in this area run the MI
- tests with the FORCE_SEPARATE_MI_TTY=1 flag being passed. */
- setbuf (stream, NULL);
- /* We still need the while loop here, even though it would seem
- obvious to invoke gdb_readline_no_editing_callback at every
- character entered. If not using the readline library, the
- terminal is in cooked mode, which sends the characters all at
- once. Poll will notice that the input fd has changed state only
- after enter is pressed. At this point we still need to fetch all
- the chars entered. */
- while (1)
- {
- /* Read from stdin if we are executing a user defined command.
- This is the right thing for prompt_for_continue, at least. */
- c = fgetc (stream);
- if (c == EOF)
- {
- if (line_buffer.used_size > 0)
- {
- /* The last line does not end with a newline. Return it, and
- if we are called again fgetc will still return EOF and
- we'll return NULL then. */
- break;
- }
- xfree (buffer_finish (&line_buffer));
- ui->input_handler (NULL);
- return;
- }
- if (c == '\n')
- {
- if (line_buffer.used_size > 0
- && line_buffer.buffer[line_buffer.used_size - 1] == '\r')
- line_buffer.used_size--;
- break;
- }
- buffer_grow_char (&line_buffer, c);
- }
- buffer_grow_char (&line_buffer, '\0');
- result = buffer_finish (&line_buffer);
- ui->input_handler (gdb::unique_xmalloc_ptr<char> (result));
- }
- /* Attempt to unblock signal SIG, return true if the signal was unblocked,
- otherwise, return false. */
- static bool
- unblock_signal (int sig)
- {
- #if HAVE_SIGPROCMASK
- sigset_t sigset;
- sigemptyset (&sigset);
- sigaddset (&sigset, sig);
- gdb_sigmask (SIG_UNBLOCK, &sigset, 0);
- return true;
- #endif
- return false;
- }
- /* Called to handle fatal signals. SIG is the signal number. */
- static void ATTRIBUTE_NORETURN
- handle_fatal_signal (int sig)
- {
- #ifdef GDB_PRINT_INTERNAL_BACKTRACE
- const auto sig_write = [] (const char *msg) -> void
- {
- gdb_stderr->write_async_safe (msg, strlen (msg));
- };
- if (bt_on_fatal_signal)
- {
- sig_write ("\n\n");
- sig_write (_("Fatal signal: "));
- sig_write (strsignal (sig));
- sig_write ("\n");
- gdb_internal_backtrace ();
- sig_write (_("A fatal error internal to GDB has been detected, "
- "further\ndebugging is not possible. GDB will now "
- "terminate.\n\n"));
- sig_write (_("This is a bug, please report it."));
- if (REPORT_BUGS_TO[0] != '\0')
- {
- sig_write (_(" For instructions, see:\n"));
- sig_write (REPORT_BUGS_TO);
- sig_write (".");
- }
- sig_write ("\n\n");
- gdb_stderr->flush ();
- }
- #endif
- /* If possible arrange for SIG to have its default behaviour (which
- should be to terminate the current process), unblock SIG, and reraise
- the signal. This ensures GDB terminates with the expected signal. */
- if (signal (sig, SIG_DFL) != SIG_ERR
- && unblock_signal (sig))
- raise (sig);
- /* The above failed, so try to use SIGABRT to terminate GDB. */
- #ifdef SIGABRT
- signal (SIGABRT, SIG_DFL);
- #endif
- abort (); /* ARI: abort */
- }
- /* The SIGSEGV handler for this thread, or NULL if there is none. GDB
- always installs a global SIGSEGV handler, and then lets threads
- indicate their interest in handling the signal by setting this
- thread-local variable.
- This is a static variable instead of extern because on various platforms
- (notably Cygwin) extern thread_local variables cause link errors. So
- instead, we have scoped_segv_handler_restore, which also makes it impossible
- to accidentally forget to restore it to the original value. */
- static thread_local void (*thread_local_segv_handler) (int);
- static void handle_sigsegv (int sig);
- /* Install the SIGSEGV handler. */
- static void
- install_handle_sigsegv ()
- {
- #if defined (HAVE_SIGACTION)
- struct sigaction sa;
- sa.sa_handler = handle_sigsegv;
- sigemptyset (&sa.sa_mask);
- #ifdef HAVE_SIGALTSTACK
- sa.sa_flags = SA_ONSTACK;
- #else
- sa.sa_flags = 0;
- #endif
- sigaction (SIGSEGV, &sa, nullptr);
- #else
- signal (SIGSEGV, handle_sigsegv);
- #endif
- }
- /* Handler for SIGSEGV. */
- static void
- handle_sigsegv (int sig)
- {
- install_handle_sigsegv ();
- if (thread_local_segv_handler == nullptr)
- handle_fatal_signal (sig);
- thread_local_segv_handler (sig);
- }
- /* The serial event associated with the QUIT flag. set_quit_flag sets
- this, and check_quit_flag clears it. Used by interruptible_select
- to be able to do interruptible I/O with no race with the SIGINT
- handler. */
- static struct serial_event *quit_serial_event;
- /* Initialization of signal handlers and tokens. There are a number of
- different strategies for handling different signals here.
- For SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGTSTP, there is a function
- handle_sig* for each of these signals. These functions are the actual
- signal handlers associated to the signals via calls to signal(). The
- only job for these functions is to enqueue the appropriate
- event/procedure with the event loop. The event loop will take care of
- invoking the queued procedures to perform the usual tasks associated
- with the reception of the signal.
- For SIGSEGV the handle_sig* function does all the work for handling this
- signal.
- For SIGFPE, SIGBUS, and SIGABRT, these signals will all cause GDB to
- terminate immediately. */
- void
- gdb_init_signals (void)
- {
- initialize_async_signal_handlers ();
- quit_serial_event = make_serial_event ();
- sigint_token =
- create_async_signal_handler (async_request_quit, NULL, "sigint");
- signal (SIGINT, handle_sigint);
- async_sigterm_token
- = create_async_signal_handler (async_sigterm_handler, NULL, "sigterm");
- signal (SIGTERM, handle_sigterm);
- #ifdef SIGQUIT
- sigquit_token =
- create_async_signal_handler (async_do_nothing, NULL, "sigquit");
- signal (SIGQUIT, handle_sigquit);
- #endif
- #ifdef SIGHUP
- if (signal (SIGHUP, handle_sighup) != SIG_IGN)
- sighup_token =
- create_async_signal_handler (async_disconnect, NULL, "sighup");
- else
- sighup_token =
- create_async_signal_handler (async_do_nothing, NULL, "sighup");
- #endif
- #ifdef SIGTSTP
- sigtstp_token =
- create_async_signal_handler (async_sigtstp_handler, NULL, "sigtstp");
- #endif
- #ifdef SIGFPE
- signal (SIGFPE, handle_fatal_signal);
- #endif
- #ifdef SIGBUS
- signal (SIGBUS, handle_fatal_signal);
- #endif
- #ifdef SIGABRT
- signal (SIGABRT, handle_fatal_signal);
- #endif
- install_handle_sigsegv ();
- }
- /* See defs.h. */
- void
- quit_serial_event_set (void)
- {
- serial_event_set (quit_serial_event);
- }
- /* See defs.h. */
- void
- quit_serial_event_clear (void)
- {
- serial_event_clear (quit_serial_event);
- }
- /* Return the selectable file descriptor of the serial event
- associated with the quit flag. */
- static int
- quit_serial_event_fd (void)
- {
- return serial_event_fd (quit_serial_event);
- }
- /* See defs.h. */
- void
- default_quit_handler (void)
- {
- if (check_quit_flag ())
- {
- if (target_terminal::is_ours ())
- quit ();
- else
- target_pass_ctrlc ();
- }
- }
- /* See defs.h. */
- quit_handler_ftype *quit_handler = default_quit_handler;
- /* Handle a SIGINT. */
- void
- handle_sigint (int sig)
- {
- signal (sig, handle_sigint);
- /* We could be running in a loop reading in symfiles or something so
- it may be quite a while before we get back to the event loop. So
- set quit_flag to 1 here. Then if QUIT is called before we get to
- the event loop, we will unwind as expected. */
- set_quit_flag ();
- /* In case nothing calls QUIT before the event loop is reached, the
- event loop handles it. */
- mark_async_signal_handler (sigint_token);
- }
- /* See gdb_select.h. */
- int
- interruptible_select (int n,
- fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- struct timeval *timeout)
- {
- fd_set my_readfds;
- int fd;
- int res;
- if (readfds == NULL)
- {
- readfds = &my_readfds;
- FD_ZERO (&my_readfds);
- }
- fd = quit_serial_event_fd ();
- FD_SET (fd, readfds);
- if (n <= fd)
- n = fd + 1;
- do
- {
- res = gdb_select (n, readfds, writefds, exceptfds, timeout);
- }
- while (res == -1 && errno == EINTR);
- if (res == 1 && FD_ISSET (fd, readfds))
- {
- errno = EINTR;
- return -1;
- }
- return res;
- }
- /* Handle GDB exit upon receiving SIGTERM if target_can_async_p (). */
- static void
- async_sigterm_handler (gdb_client_data arg)
- {
- quit_force (NULL, 0);
- }
- /* See defs.h. */
- volatile int sync_quit_force_run;
- /* Quit GDB if SIGTERM is received.
- GDB would quit anyway, but this way it will clean up properly. */
- void
- handle_sigterm (int sig)
- {
- signal (sig, handle_sigterm);
- sync_quit_force_run = 1;
- set_quit_flag ();
- mark_async_signal_handler (async_sigterm_token);
- }
- /* Do the quit. All the checks have been done by the caller. */
- void
- async_request_quit (gdb_client_data arg)
- {
- /* If the quit_flag has gotten reset back to 0 by the time we get
- back here, that means that an exception was thrown to unwind the
- current command before we got back to the event loop. So there
- is no reason to call quit again here. */
- QUIT;
- }
- #ifdef SIGQUIT
- /* Tell the event loop what to do if SIGQUIT is received.
- See event-signal.c. */
- static void
- handle_sigquit (int sig)
- {
- mark_async_signal_handler (sigquit_token);
- signal (sig, handle_sigquit);
- }
- #endif
- #if defined (SIGQUIT) || defined (SIGHUP)
- /* Called by the event loop in response to a SIGQUIT or an
- ignored SIGHUP. */
- static void
- async_do_nothing (gdb_client_data arg)
- {
- /* Empty function body. */
- }
- #endif
- #ifdef SIGHUP
- /* Tell the event loop what to do if SIGHUP is received.
- See event-signal.c. */
- static void
- handle_sighup (int sig)
- {
- mark_async_signal_handler (sighup_token);
- signal (sig, handle_sighup);
- }
- /* Called by the event loop to process a SIGHUP. */
- static void
- async_disconnect (gdb_client_data arg)
- {
- try
- {
- quit_cover ();
- }
- catch (const gdb_exception &exception)
- {
- gdb_puts ("Could not kill the program being debugged",
- gdb_stderr);
- exception_print (gdb_stderr, exception);
- }
- for (inferior *inf : all_inferiors ())
- {
- switch_to_inferior_no_thread (inf);
- try
- {
- pop_all_targets ();
- }
- catch (const gdb_exception &exception)
- {
- }
- }
- signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */
- raise (SIGHUP);
- }
- #endif
- #ifdef SIGTSTP
- void
- handle_sigtstp (int sig)
- {
- mark_async_signal_handler (sigtstp_token);
- signal (sig, handle_sigtstp);
- }
- static void
- async_sigtstp_handler (gdb_client_data arg)
- {
- const std::string &prompt = get_prompt ();
- signal (SIGTSTP, SIG_DFL);
- unblock_signal (SIGTSTP);
- raise (SIGTSTP);
- signal (SIGTSTP, handle_sigtstp);
- printf_unfiltered ("%s", prompt.c_str ());
- gdb_flush (gdb_stdout);
- /* Forget about any previous command -- null line now will do
- nothing. */
- dont_repeat ();
- }
- #endif /* SIGTSTP */
- /* Set things up for readline to be invoked via the alternate
- interface, i.e. via a callback function
- (gdb_rl_callback_read_char), and hook up instream to the event
- loop. */
- void
- gdb_setup_readline (int editing)
- {
- struct ui *ui = current_ui;
- /* This function is a noop for the sync case. The assumption is
- that the sync setup is ALL done in gdb_init, and we would only
- mess it up here. The sync stuff should really go away over
- time. */
- if (!batch_silent)
- gdb_stdout = new pager_file (new stdio_file (ui->outstream));
- gdb_stderr = new stderr_file (ui->errstream);
- gdb_stdlog = new timestamped_file (gdb_stderr);
- gdb_stdtarg = gdb_stderr; /* for moment */
- gdb_stdtargerr = gdb_stderr; /* for moment */
- /* If the input stream is connected to a terminal, turn on editing.
- However, that is only allowed on the main UI, as we can only have
- one instance of readline. */
- if (ISATTY (ui->instream) && editing && ui == main_ui)
- {
- /* Tell gdb that we will be using the readline library. This
- could be overwritten by a command in .gdbinit like 'set
- editing on' or 'off'. */
- ui->command_editing = 1;
- /* When a character is detected on instream by select or poll,
- readline will be invoked via this callback function. */
- ui->call_readline = gdb_rl_callback_read_char_wrapper;
- /* Tell readline to use the same input stream that gdb uses. */
- rl_instream = ui->instream;
- }
- else
- {
- ui->command_editing = 0;
- ui->call_readline = gdb_readline_no_editing_callback;
- }
- /* Now create the event source for this UI's input file descriptor.
- Another source is going to be the target program (inferior), but
- that must be registered only when it actually exists (I.e. after
- we say 'run' or after we connect to a remote target. */
- ui_register_input_event_handler (ui);
- }
- /* Disable command input through the standard CLI channels. Used in
- the suspend proc for interpreters that use the standard gdb readline
- interface, like the cli & the mi. */
- void
- gdb_disable_readline (void)
- {
- struct ui *ui = current_ui;
- /* FIXME - It is too heavyweight to delete and remake these every
- time you run an interpreter that needs readline. It is probably
- better to have the interpreters cache these, which in turn means
- that this needs to be moved into interpreter specific code. */
- #if 0
- ui_file_delete (gdb_stdout);
- ui_file_delete (gdb_stderr);
- gdb_stdlog = NULL;
- gdb_stdtarg = NULL;
- gdb_stdtargerr = NULL;
- #endif
- if (ui->command_editing)
- gdb_rl_callback_handler_remove ();
- delete_file_handler (ui->input_fd);
- }
- scoped_segv_handler_restore::scoped_segv_handler_restore (segv_handler_t new_handler)
- {
- m_old_handler = thread_local_segv_handler;
- thread_local_segv_handler = new_handler;
- }
- scoped_segv_handler_restore::~scoped_segv_handler_restore()
- {
- thread_local_segv_handler = m_old_handler;
- }
- static const char debug_event_loop_off[] = "off";
- static const char debug_event_loop_all_except_ui[] = "all-except-ui";
- static const char debug_event_loop_all[] = "all";
- static const char *debug_event_loop_enum[] = {
- debug_event_loop_off,
- debug_event_loop_all_except_ui,
- debug_event_loop_all,
- nullptr
- };
- static const char *debug_event_loop_value = debug_event_loop_off;
- static void
- set_debug_event_loop_command (const char *args, int from_tty,
- cmd_list_element *c)
- {
- if (debug_event_loop_value == debug_event_loop_off)
- debug_event_loop = debug_event_loop_kind::OFF;
- else if (debug_event_loop_value == debug_event_loop_all_except_ui)
- debug_event_loop = debug_event_loop_kind::ALL_EXCEPT_UI;
- else if (debug_event_loop_value == debug_event_loop_all)
- debug_event_loop = debug_event_loop_kind::ALL;
- else
- gdb_assert_not_reached ("Invalid debug event look kind value.");
- }
- static void
- show_debug_event_loop_command (struct ui_file *file, int from_tty,
- struct cmd_list_element *cmd, const char *value)
- {
- gdb_printf (file, _("Event loop debugging is %s.\n"), value);
- }
- void _initialize_event_top ();
- void
- _initialize_event_top ()
- {
- add_setshow_enum_cmd ("event-loop", class_maintenance,
- debug_event_loop_enum,
- &debug_event_loop_value,
- _("Set event-loop debugging."),
- _("Show event-loop debugging."),
- _("\
- Control whether to show event loop-related debug messages."),
- set_debug_event_loop_command,
- show_debug_event_loop_command,
- &setdebuglist, &showdebuglist);
- add_setshow_boolean_cmd ("backtrace-on-fatal-signal", class_maintenance,
- &bt_on_fatal_signal, _("\
- Set whether to produce a backtrace if GDB receives a fatal signal."), _("\
- Show whether GDB will produce a backtrace if it receives a fatal signal."), _("\
- Use \"on\" to enable, \"off\" to disable.\n\
- If enabled, GDB will produce a minimal backtrace if it encounters a fatal\n\
- signal from within GDB itself. This is a mechanism to help diagnose\n\
- crashes within GDB, not a mechanism for debugging inferiors."),
- gdb_internal_backtrace_set_cmd,
- show_bt_on_fatal_signal,
- &maintenance_set_cmdlist,
- &maintenance_show_cmdlist);
- }
|