This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Use a time-based timeout instead of a hardcoded instruction count in the IRInterpreter
ClosedPublic

Authored by JDevlieghere on May 19 2021, 5:32 AM.

Details

Summary

At the moment the IRInterpreter will stop interpreting an expression after a hardcoded 4096 instructions. After it reaches the limit it will stop interpreting and leave the process in whatever state it was when the timeout was reached.

This patch changes the instruction limit to a timeout and uses the user-specified expression timeout value for this.

The main motivation is to allow users on targets where we can't use the JIT to run more complicated expressions if they really want to (which they can do now by just increasing the timeout).

The time-based approach also seems much more meaningful than the arbitrary (and very low) instruction limit. 4096 instructions can be interpreted in a few microseconds on some setups but might take much longer if we have a slow connection to the target. I don't think any user actually cares about the number of instructions that are executed but only about the time they are willing to wait for a result.

One problem that we have with allowing the user to change the IRInterpreter timeout is that there is currently no way to interrupt the interpreter process. As a follow-up we should check if can nicely hook up the driver's SIGINT handler to the IRInterpreter's work loop, but until this is done one can easily cause LLDB to get stuck in the interpreter by specifying no timeout and running an infinite loop-ing expression. To prevent that any user accidentally locks up their debugging session, this patch prevents that the user can pass 'no timeout' to the IRInterpreter but instead sets the limit to 30 seconds when no timeout was set. Users can still manually specify a longer timeout if they really need it.

Diff Detail

Event Timeline

teemperor created this revision.May 19 2021, 5:32 AM
teemperor requested review of this revision.May 19 2021, 5:32 AM
JDevlieghere commandeered this revision.Jul 25 2023, 3:31 PM
JDevlieghere added a reviewer: teemperor.
Herald added a project: Restricted Project. · View Herald TranscriptJul 25 2023, 3:31 PM
Herald added a subscriber: Michael137. · View Herald Transcript

Generally LGTM, just left some minor comments

This assumes that each iteration of the loop won't misbehave and run for longer than the timeout. Which seems like an odd enough case for that not to be a concern?

lldb/source/Expression/IRInterpreter.cpp
733

Nit: should we check for timeout->count() > 0?

The Timeout docs don't really specify what < 0 means but AFAICT nothing technically stops that from happening

739

Haven't used this API before but is there a more concrete error? Perhaps something relating to timeouts?

lldb/source/Expression/LLVMUserExpression.cpp
128

Should we consider making this default timeout also configurable? So that we don't need to have a test that runs for at least 30 seconds?

LGTM modulo the existing comments!

lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
27

If we ever land my ancient "optimize expr" patch then this infinite loop will be fun to debug :). Maybe just add a function to the target such as void five_min_expr() { sleep(5 * 60); } and call five_min_expr().

JDevlieghere marked 2 inline comments as done.

Address review feedback

lldb/source/Expression/IRInterpreter.cpp
739

There's only std::errc:: stream_timeout (ETIME) which has been deprecated. The rest of the IRInterpreter also uses the generic error codes too so I think this is the most consistent.

This revision is now accepted and ready to land.Aug 1 2023, 10:06 AM
This revision was automatically updated to reflect the committed changes.