[lldb] Add support for a "global" lldbinit file

This patch adds introduces a new kind of an lldbinit file. Unlike the
lldbinit in the home directory (useful for customizing lldb to the needs
of a particular user), or the cwd lldbinit file (useful for
project-specific settings), this file can be used to customize an entire
lldb installation to a particular environment.

The feature is enabled at build time, by setting the
LLDB_GLOBAL_INIT_DIRECTORY variable to a path to a directory which
should contain an "lldbinit" file. Lldb will then load the file at
startup, if it exists, and if automatic init loading has not been
disabled. Relative paths will be resolved (at runtime) relative to the
location of the lldb library (liblldb or LLDB.framework).

The system-wide lldbinit file will be loaded first, before any
$HOME/.lldbinit and $CWD/.lldbinit files are processed, so that those
can override any system-wide settings.

More information can be found on the RFC thread at
<https://discourse.llvm.org/t/rfc-system-wide-lldbinit/59933>.

Differential Revision: https://reviews.llvm.org/D119831
This commit is contained in:
Pavel Labath 2022-02-15 13:28:34 +01:00
parent de2c0a2e61
commit 6c99a3469d
8 changed files with 48 additions and 2 deletions

View File

@ -72,6 +72,10 @@ option(LLDB_USE_SYSTEM_DEBUGSERVER "Use the system's debugserver for testing (Da
option(LLDB_SKIP_STRIP "Whether to skip stripping of binaries when installing lldb." OFF)
option(LLDB_SKIP_DSYM "Whether to skip generating a dSYM when installing lldb." OFF)
set(LLDB_GLOBAL_INIT_DIRECTORY "" CACHE STRING
"Path to the global lldbinit directory. Relative paths are resolved relative to the
directory containing the LLDB library.")
if (LLDB_USE_SYSTEM_DEBUGSERVER)
# The custom target for the system debugserver has no install target, so we
# need to remove it from the LLVM_DISTRIBUTION_COMPONENTS list.

View File

@ -147,6 +147,8 @@ public:
const char *help, const char *syntax,
const char *auto_repeat_command);
void SourceInitFileInGlobalDirectory(lldb::SBCommandReturnObject &result);
void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result);
void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result,
bool is_repl);

View File

@ -53,4 +53,6 @@
#define LLDB_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}"
#cmakedefine LLDB_GLOBAL_INIT_DIRECTORY R"(${LLDB_GLOBAL_INIT_DIRECTORY})"
#endif // #ifndef LLDB_HOST_CONFIG_H

View File

@ -253,6 +253,7 @@ public:
void SourceInitFileCwd(CommandReturnObject &result);
void SourceInitFileHome(CommandReturnObject &result, bool is_repl);
void SourceInitFileGlobal(CommandReturnObject &result);
bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp,
bool can_replace);

View File

@ -423,6 +423,22 @@ void SBCommandInterpreter::reset(
m_opaque_ptr = interpreter;
}
void SBCommandInterpreter::SourceInitFileInGlobalDirectory(
SBCommandReturnObject &result) {
LLDB_INSTRUMENT_VA(this, result);
result.Clear();
if (IsValid()) {
TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
std::unique_lock<std::recursive_mutex> lock;
if (target_sp)
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
m_opaque_ptr->SourceInitFileGlobal(result.ref());
} else {
result->AppendError("SBCommandInterpreter is not valid");
}
}
void SBCommandInterpreter::SourceInitFileInHomeDirectory(
SBCommandReturnObject &result) {
LLDB_INSTRUMENT_VA(this, result);

View File

@ -236,6 +236,7 @@ SBDebugger SBDebugger::Create(bool source_init_files,
interp.get()->SkipLLDBInitFiles(false);
interp.get()->SkipAppInitFiles(false);
SBCommandReturnObject result;
interp.SourceInitFileInGlobalDirectory(result);
interp.SourceInitFileInHomeDirectory(result, false);
} else {
interp.get()->SkipLLDBInitFiles(true);

View File

@ -2380,6 +2380,21 @@ void CommandInterpreter::SourceInitFileHome(CommandReturnObject &result,
SourceInitFile(FileSpec(init_file.str()), result);
}
void CommandInterpreter::SourceInitFileGlobal(CommandReturnObject &result) {
#ifdef LLDB_GLOBAL_INIT_DIRECTORY
if (!m_skip_lldbinit_files) {
FileSpec init_file(LLDB_GLOBAL_INIT_DIRECTORY);
if (init_file)
init_file.MakeAbsolute(HostInfo::GetShlibDir());
init_file.AppendPathComponent("lldbinit");
SourceInitFile(init_file, result);
return;
}
#endif
result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
const char *CommandInterpreter::GetCommandPrefix() {
const char *prefix = GetDebugger().GetIOHandlerCommandPrefix();
return prefix == nullptr ? "" : prefix;

View File

@ -452,9 +452,14 @@ int Driver::MainLoop() {
SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
// Before we handle any options from the command line, we parse the
// REPL init file or the default file in the user's home directory.
// Process lldbinit files before handling any options from the command line.
SBCommandReturnObject result;
sb_interpreter.SourceInitFileInGlobalDirectory(result);
if (m_option_data.m_debug_mode) {
result.PutError(m_debugger.GetErrorFile());
result.PutOutput(m_debugger.GetOutputFile());
}
sb_interpreter.SourceInitFileInHomeDirectory(result, m_option_data.m_repl);
if (m_option_data.m_debug_mode) {
result.PutError(m_debugger.GetErrorFile());