-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathpysymfix.cpp
More file actions
103 lines (80 loc) · 2.92 KB
/
pysymfix.cpp
File metadata and controls
103 lines (80 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "extension.h"
#include <engextcpp.hpp>
#include <filesystem>
#include <string>
#include <stdexcept>
#include <cassert>
using namespace std;
namespace {
auto getSymbolPath(IDebugSymbols* pSymbols) -> string
{
// Get the size we'll need first.
ULONG pathSize = 0;
HRESULT hr = pSymbols->GetSymbolPath(nullptr, 0, &pathSize);
if (FAILED(hr))
throw runtime_error("GetSymbolPath failed to get path size with hr=" + hr);
// Now get the buffer.
string buff(pathSize, '\0');
hr = pSymbols->GetSymbolPath(buff.data(), pathSize, &pathSize);
if (FAILED(hr))
throw runtime_error("GetSymbolPath failed to get path size with hr=" + hr);
assert(pathSize == buff.size() && "Unexpected symbol path size after second call to GetSymbolPath.");
buff.erase(buff.find('\0')); //< Trim off any extra from our string.
return buff;
}
auto setSymbolPath(IDebugSymbols* pSymbols, const string& path) -> void
{
HRESULT hr = pSymbols->SetSymbolPath(path.c_str());
if (FAILED(hr))
throw runtime_error("SetSymbolPath failed with hr=" + hr);
}
string concatenatePaths(const string& path1, const string& path2, char delim = ';')
{
auto cattedPath = path1;
if (!cattedPath.empty() && cattedPath.back() != delim) {
cattedPath += delim;
}
cattedPath += path2;
return cattedPath;
}
}
namespace PyExt {
EXT_COMMAND(pysymfix, "Adds python symbols to the symbol path.", "")
{
auto sympath = getSymbolPath(m_Symbols);
Out("Current symbol path: %s\n", sympath.c_str());
// Check for local PDBs next to each python*.dll and append their directories.
ULONG moduleCount = 0, unloadedCount = 0;
if (SUCCEEDED(m_Symbols->GetNumberModules(&moduleCount, &unloadedCount))) {
for (ULONG i = 0; i < moduleCount; i++) {
char modName[MAX_PATH] = {};
char imagePath[MAX_PATH] = {};
if (FAILED(m_Symbols->GetModuleNames(i, 0,
imagePath, sizeof(imagePath), nullptr,
modName, sizeof(modName), nullptr,
nullptr, 0, nullptr)))
continue;
if (_strnicmp(modName, "python", 6) != 0)
continue;
auto dir = filesystem::path(imagePath).parent_path();
if (!filesystem::exists(dir / (string(modName) + ".pdb")))
continue;
string dirStr = dir.string();
if (sympath.find(dirStr) != string::npos)
continue;
Out("Found local PDB in %s, adding to symbol path.\n", dirStr.c_str());
sympath = concatenatePaths(sympath, dirStr);
}
}
if (sympath.find("pythonsymbols.sdcline.com/symbols") == string::npos) {
Out("Adding symbol server to path...\n");
sympath = concatenatePaths(sympath, "srv*http://pythonsymbols.sdcline.com/symbols");
} else {
Out("Python symbol server already in path.\n");
}
setSymbolPath(m_Symbols, sympath);
Out("New symbol path: %s\n", getSymbolPath(m_Symbols).c_str());
Out("Loading symbols...\n");
ensureSymbolsLoaded();
}
}