mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 13:06:08 +00:00

Partly, there's just a lot of unnecessary boiler plate. It's also possible to define combinations of arguments that make no sense (e.g. eArgRepeatPlus followed by eArgRepeatPlain...) but these are never checked since we just push_back directly into the argument definitions. This commit is step 1 of this cleanup - do the obvious stuff. In it, all the simple homogenous argument lists and the breakpoint/watchpoint ID/Range types, are set with common functions. This is an NFC change, it just centralizes boiler plate. There's no checking yet because you can't get a single argument wrong. The end goal is that all argument definition goes through functions and m_arguments is hidden so that you can't define inconsistent argument sets.
106 lines
3.7 KiB
C++
106 lines
3.7 KiB
C++
//===-- CommandObjectQuit.cpp ---------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CommandObjectQuit.h"
|
|
|
|
#include "lldb/Interpreter/CommandInterpreter.h"
|
|
#include "lldb/Interpreter/CommandReturnObject.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Utility/StreamString.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
// CommandObjectQuit
|
|
|
|
CommandObjectQuit::CommandObjectQuit(CommandInterpreter &interpreter)
|
|
: CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.",
|
|
"quit [exit-code]") {
|
|
AddSimpleArgumentList(eArgTypeUnsignedInteger);
|
|
}
|
|
|
|
CommandObjectQuit::~CommandObjectQuit() = default;
|
|
|
|
// returns true if there is at least one alive process is_a_detach will be true
|
|
// if all alive processes will be detached when you quit and false if at least
|
|
// one process will be killed instead
|
|
bool CommandObjectQuit::ShouldAskForConfirmation(bool &is_a_detach) {
|
|
if (!m_interpreter.GetPromptOnQuit())
|
|
return false;
|
|
bool should_prompt = false;
|
|
is_a_detach = true;
|
|
for (uint32_t debugger_idx = 0; debugger_idx < Debugger::GetNumDebuggers();
|
|
debugger_idx++) {
|
|
DebuggerSP debugger_sp(Debugger::GetDebuggerAtIndex(debugger_idx));
|
|
if (!debugger_sp)
|
|
continue;
|
|
const TargetList &target_list(debugger_sp->GetTargetList());
|
|
for (uint32_t target_idx = 0;
|
|
target_idx < static_cast<uint32_t>(target_list.GetNumTargets());
|
|
target_idx++) {
|
|
TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
|
|
if (!target_sp)
|
|
continue;
|
|
ProcessSP process_sp(target_sp->GetProcessSP());
|
|
if (process_sp && process_sp->IsValid() && process_sp->IsAlive() &&
|
|
process_sp->WarnBeforeDetach()) {
|
|
should_prompt = true;
|
|
if (!process_sp->GetShouldDetach()) {
|
|
// if we need to kill at least one process, just say so and return
|
|
is_a_detach = false;
|
|
return should_prompt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return should_prompt;
|
|
}
|
|
|
|
void CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) {
|
|
bool is_a_detach = true;
|
|
if (ShouldAskForConfirmation(is_a_detach)) {
|
|
StreamString message;
|
|
message.Printf("Quitting LLDB will %s one or more processes. Do you really "
|
|
"want to proceed",
|
|
(is_a_detach ? "detach from" : "kill"));
|
|
if (!m_interpreter.Confirm(message.GetString(), true)) {
|
|
result.SetStatus(eReturnStatusFailed);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (command.GetArgumentCount() > 1) {
|
|
result.AppendError("Too many arguments for 'quit'. Only an optional exit "
|
|
"code is allowed");
|
|
return;
|
|
}
|
|
|
|
// We parse the exit code argument if there is one.
|
|
if (command.GetArgumentCount() == 1) {
|
|
llvm::StringRef arg = command.GetArgumentAtIndex(0);
|
|
int exit_code;
|
|
if (arg.getAsInteger(/*autodetect radix*/ 0, exit_code)) {
|
|
lldb_private::StreamString s;
|
|
std::string arg_str = arg.str();
|
|
s.Printf("Couldn't parse '%s' as integer for exit code.", arg_str.data());
|
|
result.AppendError(s.GetString());
|
|
return;
|
|
}
|
|
if (!m_interpreter.SetQuitExitCode(exit_code)) {
|
|
result.AppendError("The current driver doesn't allow custom exit codes"
|
|
" for the quit command.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
const uint32_t event_type =
|
|
CommandInterpreter::eBroadcastBitQuitCommandReceived;
|
|
m_interpreter.BroadcastEvent(event_type);
|
|
result.SetStatus(eReturnStatusQuit);
|
|
}
|