This is an archive of the discontinued LLVM Phabricator instance.

tab completion for process signal
ClosedPublic

Authored by MrHate on Feb 29 2020, 8:46 PM.

Details

Summary

Provide a list of Unix signals for the tap completion for command "process signal".

Diff Detail

Event Timeline

MrHate created this revision.Feb 29 2020, 8:46 PM
teemperor requested changes to this revision.Mar 2 2020, 5:15 PM

I think that's a good start, but the usual way LLDB implements completions is that we go to the same backend that handles the actual values and retrieve the completions from there. The main reason is that this prevents duplicate code and that we provide completions that don't end up being valid commands. For example, you are missing SIGRTMIN+12 in your list but MIPS on Linux has this signal. So we won't get completions for that. But if you add SIGRTMIN+12 to your list, then on other systems we would offer it as completion even though it's not a valid signal there. We could of course implement all the checks for that in the HandleArgumentCompletion function but then we end up with a lot of duplicate and hard to maintain code.

So the better way to implement this is to look at the UnixSignals class and just list all the signal names in it. You can get the current instance of the UnixSignals via process->GetUnixSignals().

In general you can always look how DoExecute is implemented for a CommandObject and then mirror that logic but instead of doing the actual action just extract the completions. That works for like 99% of the completions in LLDB I would guess (even though some might require some refactoring to get it into a nice format).

This revision now requires changes to proceed.Mar 2 2020, 5:15 PM
teemperor set the repository for this revision to rLLDB LLDB.Mar 2 2020, 5:15 PM
MrHate added a comment.Mar 2 2020, 9:22 PM

Thanks for pointing out my misunderstanding on the Unix signals, and fetching the list of valid signals from backend is always a better way indeed.
However, getting the current process from the current context m_exe_ctx which is got from m_interpreter will cause an issue that the completion won't be triggered before executing some process commands.
This is similar to frame variable cause these two commands both work on the base of the current context from m_interpreter.
In order to process completion successfully whenever we've got a valid process, I will update the current execution context both in m_interpreter and the current command object.
But what I am worried about is whether a new issue would be caused due to updating the current execution context.

MrHate updated this revision to Diff 247785.Mar 2 2020, 9:25 PM

Update the current execution context, then get signals from the current process.

MrHate updated this revision to Diff 247786.Mar 2 2020, 10:12 PM

removed unnecessary assignment in test

In order to process completion successfully whenever we've got a valid process, I will update the current execution context both in m_interpreter and the current command object.
But what I am worried about is whether a new issue would be caused due to updating the current execution context.

This worries me too. I don't really understand how this works, but it seems rather odd that this command should need to do this. There's plenty of other commands that operate on the current process and they don't call UpdateExecutionContext. Maybe @jingham knows what is going on here?

I think this is just a bug in argument completion.

The CommandInterpreter needs to sync up with the currently selected target/process/thread/frame before running commands.

It COULD do that by having every API that changes the selected T/P/T/F above notify the CommandInterpreter of the change. Then you would only need UpdateExecutionContext when you want to override the currently selected context. You do that, for instance, when you run stop hooks or breakpoint commands, which don't actually select the context they operate on.

But it doesn't do it that way. Instead, the CommandInterpreter is responsible for syncing its state before running commands. It calls UpdateExecutionContext on each command evaluation, either passing along an override context as above, or sending in a nullptr to tell it to sync with the currently selected state.

However, HandleCompletions doesn't do that, so it might not be operating on a consistent state. To be consistent, it really should do that as well.

This is actually a bug in the other completions that actually depend on a selected entity. For instance, run a program to a breakpoint and before doing anything else do: frame var l<TAB> and you won't get anything, but then do just frame var and then frame var l<TAB> and then you will get all the locals starting with l... You wouldn't generally notice this, any other command you issued after stopping would have sync'ed up the state. So it only happens when frame var l<TAB> is the FIRST thing you do after a stop.

Seems like the correct fix is to have HandleCompletions call UpdateExecutionContext, rather than having individual completions call it.

MrHate updated this revision to Diff 248088.Mar 3 2020, 7:31 PM
MrHate edited the summary of this revision. (Show Details)

Removed individual execution context updating.

teemperor requested changes to this revision.Mar 6 2020, 8:26 AM

I would like to have a test for this without a running process but otherwise this LGTM. Thanks a lot!

lldb/test/API/functionalities/completion/TestCompletion.py
97

Could you make another test case that is trying tab completion without a running process? That should just provide no completions and not crash or something like that.

This revision now requires changes to proceed.Mar 6 2020, 8:26 AM
MrHate updated this revision to Diff 248784.Mar 6 2020, 10:15 AM

Added a test case where test "process signal" without a running process.

teemperor accepted this revision.Mar 6 2020, 4:16 PM

LGTM, thanks!

This revision is now accepted and ready to land.Mar 6 2020, 4:16 PM
This revision was automatically updated to reflect the committed changes.