mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-05 15:15:42 +00:00
In the previous commits I have been working on improving inferior function call support. One thing that worries me about using inferior function calls from a conditional breakpoint is: what happens if the inferior function call fails? If the failure is obvious, e.g. the thread performing the call crashes, or hits a breakpoint, then this case is already well handled, and the error is reported to the user. But what if the thread performing the inferior call just deadlocks? If the user made the call from a 'print' or 'call' command, then the user might have some expectation of when the function call should complete, and, when this time limit is exceeded, the user will (hopefully) interrupt GDB and regain control of the debug session. But, when the inferior function call is from a breakpoint condition it is much harder to understand that GDB is deadlocked within an inferior call. Maybe the breakpoint hasn't been hit yet? Or maybe the condition was always false? Or maybe GDB is deadlocked in an inferior call? The only way to know for sure is to periodically interrupt GDB, check on all the threads, and then continue. Additionally, the focus of the previous commit was inferior function calls, from a conditional breakpoint, in a multi-threaded inferior. This opens up a whole new set of potential failure conditions. For example, what if the function called relies on interaction with some other thread, and the other thread crashes? Or hits a breakpoint? Given how inferior function calls work - in a synchronous manor, a stop event in some other thread is going to be ignored when the inferior function call is being done as part of a breakpoint condition, and this means that GDB could get stuck waiting for the original condition thread, which will now never complete. In this commit I propose a solution to this problem. A timeout. For targets that support async-mode we can install an event-loop timer before starting the inferior function call. When the timer expires we will stop the thread performing the inferior function call. With this mechanism in place a user can be sure that any inferior call they make will either complete, or timeout eventually. Adding a timer like this is obviously a change in behaviour for the more common 'call' and 'print' uses of inferior function calls, so, in this patch, I propose having two different timers. One I call the 'direct-call-timeout', which is used for 'call' and 'print' commands. This timeout is by default set to unlimited, which, not surprisingly, means there is no timeout in place. A second timer, which I've called 'indirect-call-timeout', is used for inferior function calls from breakpoint conditions. This timeout has a default value of 300 seconds. This is still a pretty substantial time to be waiting for a single inferior call to complete, but I didn't want to be too aggressive with the value I selected. A user can, of course, still use Ctrl-c to interrupt an inferior function call, but this limit will ensure that GDB will stop at some point. The new commands added by this commit are: set direct-call-timeout SECONDS show direct-call-timeout set indirect-call-timeout SECONDS show indirect-call-timeout These new timeouts do depend on async-mode, so, if async-mode is disabled (maint set target-async off), or not supported (e.g. target sim), then the timeout is treated as unlimited (that is, no timeout is set). For targets that "fake" non-async mode, e.g. Linux native, where non-async mode is really just async mode, but then we park the target in a sissuspend, we could easily fix things so that the timeouts still work, however, for targets that really are not async aware, like the simulator, fixing things so that timeouts work correctly would be a much bigger task - that effort would be better spent just making the target async-aware. And so, I'm happy for now that this feature will only work on async targets. The two new show commands will display slightly different text if the current target is a non-async target, which should allow users to understand what's going on. There's a somewhat random test adjustment needed in gdb.base/help.exp, the test uses a regexp with the apropos command, and expects to find a single result. Turns out the new settings I added also matched the regexp, which broke the test. I've updated the regexp a little to exclude my new settings.
37 lines
913 B
C
37 lines
913 B
C
/* Copyright 2022 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 <unistd.h>
|
|
|
|
/* This function is called from GDB. */
|
|
int
|
|
function_that_never_returns ()
|
|
{
|
|
while (1)
|
|
sleep (1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
main ()
|
|
{
|
|
alarm (300);
|
|
|
|
return 0;
|
|
}
|