blob: 1b3521e8f03f26d8b740529e65d2e3858e6e44a2 [file] [log] [blame]
//===-- MIDriverMain.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Overview: Defines the entry point for the console application.
// The MI application (project name MI) runs in two modes:
// An LLDB native driver mode where it acts no different from the
// LLDB driver.
// The other mode is the MI when it finds on the command line
// the --interpreter option. Command line argument --help on its
// own will give
// help for the LLDB driver. If entered with --interpreter then MI
// help will
// provided.
// To implement new MI commands derive a new command class from the
// command base
// class. To enable the new command for interpretation add the new
// command class
// to the command factory. The files of relevance are:
// MICmdCommands.cpp
// MICmdBase.h / .cpp
// MICmdCmd.h / .cpp
// Third party headers:
#include "lldb/API/SBHostOS.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include <atomic>
#include <csignal>
#include <stdio.h>
// In house headers:
#include "MICmnConfig.h"
#include "MICmnResources.h"
#include "MICmnStreamStdin.h"
#include "MIDriver.h"
#include "MIDriverMgr.h"
#include "MIUtilDebug.h"
#include "Platform.h" // Define signals - CODETAG_IOR_SIGNALS
#if defined(_MSC_VER)
#pragma warning( \
once : 4530) // Warning C4530: C++ exception handler used, but unwind
// semantics are not enabled. Specify /EHsc
#endif // _MSC_VER
// CODETAG_IOR_SIGNALS
//++
//------------------------------------------------------------------------------------
// Details: The SIGINT signal is sent to a process by its controlling terminal
// when a
// user wishes to interrupt the process. This is typically initiated by
// pressing
// Control-C, but on some systems, the "delete" character or "break"
// key can be
// used.
// Be aware this function may be called on another thread besides the
// main thread.
// Type: Function.
// Args: vSigno - (R) Signal number.
// Return: None.
// Throws: None.
//--
void sigint_handler(int vSigno) {
#ifdef _WIN32 // Restore handler as it is not persistent on Windows
signal(SIGINT, sigint_handler);
#endif
static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT;
CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger();
if (pDebugger != nullptr) {
if (!g_interrupt_sent.test_and_set()) {
pDebugger->DispatchInputInterrupt();
g_interrupt_sent.clear();
}
}
// Send signal to driver so that it can take suitable action
rDriverMgr.DeliverSignal(vSigno);
}
//++
//------------------------------------------------------------------------------------
// Details: Init the MI driver system. Initialize the whole driver system which
// includes
// both the original LLDB driver and the MI driver.
// Type: Function.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool DriverSystemInit() {
bool bOk = MIstatus::success;
CMIDriver &rMIDriver = CMIDriver::Instance();
CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
bOk = rDriverMgr.Initialize();
// Register MIDriver first as it needs to initialize and be ready
// for the Driver to get information from MIDriver when it initializes
// (LLDB Driver is registered with the Driver Manager in MI's Initialize())
bOk = bOk &&
rDriverMgr.RegisterDriver(rMIDriver, "MIDriver"); // Will be main driver
return bOk;
}
//++
//------------------------------------------------------------------------------------
// Details: Shutdown the debugger system. Release / terminate resources external
// to
// specifically the MI driver.
// Type: Function.
// Args: vbAppExitOk - (R) True = No problems, false = App exiting with
// problems (investigate!).
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool DriverSystemShutdown(const bool vbAppExitOk) {
bool bOk = MIstatus::success;
// *** Order is important here ***
CMIDriverMgr::Instance().Shutdown();
return bOk;
}
//++
//------------------------------------------------------------------------------------
// Details: MI's application start point of execution. The application runs in
// two modes.
// An LLDB native driver mode where it acts no different from the LLDB
// driver.
// The other mode is the MI when it finds on the command line
// the --interpreter option. Command line argument --help on its own
// will give
// help for the LLDB driver. If entered with --interpreter then
// application
// help will provided.
// Type: Method.
// Args: argc - (R) An integer that contains the count of arguments that
// follow in
// argv. The argc parameter is always greater than or
// equal to 1.
// argv - (R) An array of null-terminated strings representing
// command-line
// arguments entered by the user of the program. By
// convention,
// argv[0] is the command with which the program is
// invoked.
// Return: int - 0 = Normal exit, program success.
// >0 = Program success with status i.e. Control-C signal
// status
// <0 = Program failed.
// -1 = Program failed reason not specified here, see MI log
// file.
// -1000 = Program failed did not initialize successfully.
// Throws: None.
//--
int main(int argc, char const *argv[]) {
#if MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG
#ifdef _WIN32
CMIUtilDebug::ShowDlgWaitForDbgAttach();
#else
CMIUtilDebug::WaitForDbgAttachInfinteLoop();
#endif // _WIN32
#endif // MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG
llvm::StringRef ToolName = argv[0];
llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
llvm::PrettyStackTraceProgram X(argc, argv);
// *** Order is important here ***
bool bOk = DriverSystemInit();
if (!bOk) {
DriverSystemShutdown(bOk);
return -1000;
}
// CODETAG_IOR_SIGNALS
signal(SIGINT, sigint_handler);
bool bExiting = false;
CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
bOk = bOk && rDriverMgr.ParseArgs(argc, argv, bExiting);
if (bOk && !bExiting)
bOk = rDriverMgr.DriverParseArgs(argc, argv, stdout, bExiting);
if (bOk && !bExiting)
bOk = rDriverMgr.DriverMainLoop();
// Logger and other resources shutdown now
DriverSystemShutdown(bOk);
const int appResult = bOk ? 0 : -1;
return appResult;
}