LLDB mainline
PythonRuntimeLoaderWindows.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Host/Config.h"
10
11#if LLDB_ENABLE_PYTHON
12
15#include "llvm/ADT/STLFunctionalExtras.h"
16#include "llvm/ADT/SmallString.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/ConvertUTF.h"
20#include "llvm/Support/Path.h"
21#include "llvm/Support/Windows/WindowsSupport.h"
22
23#include <pathcch.h>
24#include <string>
25
26namespace lldb_private {
27
28namespace {
29
30/// Absolute path of \p module, or the running executable when null.
31std::string GetModulePath(HMODULE module) {
32 std::vector<WCHAR> buffer(MAX_PATH);
33 while (buffer.size() <= PATHCCH_MAX_CCH) {
34 DWORD len = ::GetModuleFileNameW(module, buffer.data(), buffer.size());
35 if (len == 0)
36 return "";
37 if (len < buffer.size()) {
38 std::string utf8;
39 if (llvm::convertWideToUTF8(std::wstring(buffer.data(), len), utf8))
40 return utf8;
41 return "";
42 }
43 if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
44 buffer.resize(buffer.size() * 2);
45 }
46 return "";
47}
48
49#ifdef LLDB_PYTHON_DLL_RELATIVE_PATH
50std::string ExeRelativeCandidate() {
51#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME
52 std::string exe = GetModulePath(nullptr);
53 if (exe.empty())
54 return "";
55 llvm::SmallString<MAX_PATH> path(exe);
56 llvm::sys::path::remove_filename(path);
57 llvm::sys::path::append(path, LLDB_PYTHON_DLL_RELATIVE_PATH);
58 llvm::sys::path::append(path, LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME);
59 llvm::sys::fs::make_absolute(path);
60 return std::string(path);
61#else
62 return "";
63#endif
64}
65#endif
66
67} // namespace
68
70 llvm::function_ref<bool(const char *)> callback) {
71 // Mapping the DLL by base name first lets the plugin's delay-load thunks
72 // (which LoadLibrary by base name) resolve against the already-mapped
73 // module on first use, bypassing DLL search rules.
74#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME
75 if (callback(LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME))
76 return;
77#endif
78
79#ifdef LLDB_PYTHON_DLL_RELATIVE_PATH
80 std::string exe_relative = ExeRelativeCandidate();
81 if (!exe_relative.empty() && callback(exe_relative.c_str()))
82 return;
83#endif
84}
85
86} // namespace lldb_private
87
88#endif // LLDB_ENABLE_PYTHON
A class that represents a running process on the host machine.
void ForEachPythonRuntimeCandidate(llvm::function_ref< bool(const char *)> callback)
Visits candidate Python runtime paths in priority order, stopping at the first call that returns true...