llvm-project/lldb/source/API/SystemInitializerFull.cpp
Pavel Labath 004a264f8c [lldb] Fix shared library directory computation on windows
Our code for locating the shared library directory works via dladdr (or
the windows equivalent) to locate the path of an address known to reside
in liblldb. This works great for C++ programs, but there's a catch.

When (lib)lldb is used from python (like in our test suite), this dladdr
call will return a path to the _lldb.so (or such) file in the python
directory. To compensate for this, we have code which attempts to
resolve this symlink, to ensure we get the canonical location. However,
here's the second catch.

On windows, this file is not a symlink (but a copy), so this logic
fails. Since most of our other paths are derived from the liblldb
location, all of these paths will be wrong, when running the test suite.
One effect of this was the failure to find lldb-server in D96202.

To fix this issue, I add some windows-specific code to locate the
liblldb directory. Since it cannot rely on symlinks, it works by
manually walking the directory tree -- essentially doing the opposite of
what we do when computing the python directory.

To avoid python leaking back into the host code, I implement this with
the help of a callback which can be passed to HostInfo::Initialize in
order to assist with the directory location. The callback lives inside
the python plugin.

I also strenghten the existing path test to ensure the returned path is
the right one.

Differential Revision: https://reviews.llvm.org/D96779
2021-02-18 15:37:52 +01:00

99 lines
3.1 KiB
C++

//===-- SystemInitializerFull.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 "SystemInitializerFull.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/Host.h"
#include "lldb/Initialization/SystemInitializerCommon.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Target/ProcessTrace.h"
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/Timer.h"
#include "llvm/Support/TargetSelect.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
#include "llvm/ExecutionEngine/MCJIT.h"
#pragma clang diagnostic pop
#include <string>
#define LLDB_PLUGIN(p) LLDB_PLUGIN_DECLARE(p)
#include "Plugins/Plugins.def"
#if LLDB_ENABLE_PYTHON
#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper
*g_shlib_dir_helper =
lldb_private::ScriptInterpreterPython::SharedLibraryDirectoryHelper;
#else
constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper
*g_shlib_dir_helper = 0;
#endif
using namespace lldb_private;
SystemInitializerFull::SystemInitializerFull()
: SystemInitializerCommon(g_shlib_dir_helper) {}
SystemInitializerFull::~SystemInitializerFull() = default;
llvm::Error SystemInitializerFull::Initialize() {
llvm::Error error = SystemInitializerCommon::Initialize();
if (error) {
// During active replay, the ::Initialize call is replayed like any other
// SB API call and the return value is ignored. Since we can't intercept
// this, we terminate here before the uninitialized debugger inevitably
// crashes.
if (repro::Reproducer::Instance().IsReplaying())
llvm::report_fatal_error(std::move(error));
return error;
}
// Initialize LLVM and Clang
llvm::InitializeAllTargets();
llvm::InitializeAllAsmPrinters();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllDisassemblers();
#define LLDB_PLUGIN(p) LLDB_PLUGIN_INITIALIZE(p);
#include "Plugins/Plugins.def"
// Initialize plug-ins in core LLDB
ProcessTrace::Initialize();
// Scan for any system or user LLDB plug-ins
PluginManager::Initialize();
// The process settings need to know about installed plug-ins, so the
// Settings must be initialized AFTER PluginManager::Initialize is called.
Debugger::SettingsInitialize();
return llvm::Error::success();
}
void SystemInitializerFull::Terminate() {
Debugger::SettingsTerminate();
// Terminate plug-ins in core LLDB
ProcessTrace::Terminate();
// Terminate and unload and loaded system or user LLDB plug-ins
PluginManager::Terminate();
#define LLDB_PLUGIN(p) LLDB_PLUGIN_TERMINATE(p);
#include "Plugins/Plugins.def"
// Now shutdown the common parts, in reverse order.
SystemInitializerCommon::Terminate();
}