Skip to content

Commit 42994b7

Browse files
ytsedancrosire
authored andcommitted
Fix object files not being found sometimes due to relative paths (#29)
Also added command line switch for attaching to running process by name
1 parent a69eec7 commit 42994b7

File tree

2 files changed

+111
-20
lines changed

2 files changed

+111
-20
lines changed

source/main.cpp

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <iostream>
99
#include <Windows.h>
1010
#include <Psapi.h>
11+
#include <TlHelp32.h> // GetProcessByName
1112

1213
#pragma region CRT sections
1314
// This exists to imitate the behavior of the CRT initialization code
@@ -32,6 +33,37 @@ void print(const char *message, size_t length)
3233
WriteFile(console, message, size, &size, nullptr);
3334
}
3435

36+
DWORD GetProcessByName(PCSTR name)
37+
{
38+
DWORD pid = 0;
39+
40+
WCHAR exe[MAX_PATH] = {};
41+
mbstowcs_s(NULL, exe, name, MAX_PATH);
42+
43+
// Create toolhelp snapshot.
44+
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
45+
PROCESSENTRY32 process;
46+
ZeroMemory(&process, sizeof(process));
47+
process.dwSize = sizeof(process);
48+
49+
// Walkthrough all processes.
50+
if (Process32First(snapshot, &process))
51+
{
52+
do
53+
{
54+
if (wcscmp(process.szExeFile, exe) == 0)
55+
{
56+
pid = process.th32ProcessID;
57+
break;
58+
}
59+
} while (Process32Next(snapshot, &process));
60+
}
61+
62+
CloseHandle(snapshot);
63+
64+
return pid;
65+
}
66+
3567
DWORD CALLBACK remote_main(BYTE *image_base)
3668
{
3769
#pragma region Initialize module image
@@ -124,27 +156,46 @@ int main(int argc, char *argv[])
124156

125157
if (argc > 1)
126158
{
127-
pid = strtoul(argv[1], nullptr, 0);
128-
129-
if (pid == 0)
159+
if (argc > 2)
130160
{
131-
STARTUPINFOA startup_info = { sizeof(startup_info) };
132-
PROCESS_INFORMATION process_info = {};
161+
if (strcmp(argv[1],"-a") == 0) // Attach to running process
162+
{
163+
// Is numerical PID
164+
pid = strtoul(argv[2], nullptr, 0);
133165

134-
std::string command_line;
135-
for (int i = 1; i < argc; ++i, command_line += ' ')
136-
command_line += argv[i];
166+
if (pid == 0)
167+
{
168+
// Try to look up PID of running process by name
169+
pid = GetProcessByName(argv[2]);
170+
}
171+
}
172+
}
173+
else
174+
{
175+
// Attach to running process by PID
176+
pid = strtoul(argv[1], nullptr, 0);
137177

138-
if (!CreateProcessA(nullptr, command_line.data(), nullptr, nullptr, FALSE, CREATE_NEW_CONSOLE, nullptr, nullptr, &startup_info, &process_info))
178+
// Launch target application and determine PID
179+
if (pid == 0)
139180
{
140-
std::cout << "Failed to start target application process!" << std::endl;
141-
return GetLastError();
142-
}
181+
STARTUPINFOA startup_info = { sizeof(startup_info) };
182+
PROCESS_INFORMATION process_info = {};
183+
184+
std::string command_line;
185+
for (int i = 1; i < argc; ++i, command_line += ' ')
186+
command_line += argv[i];
187+
188+
if (!CreateProcessA(nullptr, command_line.data(), nullptr, nullptr, FALSE, CREATE_NEW_CONSOLE, nullptr, nullptr, &startup_info, &process_info))
189+
{
190+
std::cout << "Failed to start target application process!" << std::endl;
191+
return GetLastError();
192+
}
143193

144-
pid = process_info.dwProcessId;
194+
pid = process_info.dwProcessId;
145195

146-
CloseHandle(process_info.hThread);
147-
CloseHandle(process_info.hProcess);
196+
CloseHandle(process_info.hThread);
197+
CloseHandle(process_info.hProcess);
198+
}
148199
}
149200
}
150201

source/pdb_reader.cpp

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,47 @@ void blink::pdb_reader::read_object_files(std::vector<std::filesystem::path> &ob
226226
// Read module information stream (https://llvm.org/docs/PDB/DbiStream.html#dbi-mod-info-substream)
227227
while (stream.tell() < sizeof(pdb_dbi_header) + header.module_info_size)
228228
{
229-
stream.skip(sizeof(pdb_dbi_module_info));
229+
const pdb_dbi_module_info &info = stream.read<pdb_dbi_module_info>();
230230

231231
const auto module_name = stream.read_string();
232232
const auto obj_file_name = stream.read_string(); // Contains the name of the ".lib" if this object file is part of a library
233233

234-
object_files.push_back(module_name);
234+
std::filesystem::path path(module_name);
235+
236+
// Find absolute path to if necessary
237+
if (path.is_relative())
238+
{
239+
if (info.symbol_stream != 65535 /*-1*/)
240+
{
241+
std::filesystem::path cwd;
242+
243+
// Look up current working directory in symbol stream https://llvm.org/docs/PDB/ModiStream.html
244+
stream_reader stream(msf_reader::stream(info.symbol_stream));
245+
stream.skip(4); // Skip 32-bit signature
246+
247+
parse_code_view_records(stream, [&](uint16_t tag) {
248+
if (tag == 0x113d) // S_ENVBLOCK
249+
{
250+
stream.skip(1);
251+
while (stream.tell() < stream.size() && *stream.data() != '\0')
252+
{
253+
const auto key = stream.read_string();
254+
const std::string value(stream.read_string());
255+
256+
if (key == "cwd")
257+
{
258+
cwd = value;
259+
return;
260+
}
261+
}
262+
}
263+
});
264+
265+
path = cwd / path;
266+
}
267+
}
268+
269+
object_files.push_back( path.string() );
235270

236271
stream.align(4);
237272
}
@@ -263,14 +298,19 @@ void blink::pdb_reader::read_source_files(std::vector<std::vector<std::filesyste
263298
stream.skip(num_modules * sizeof(uint16_t) * 2 + num_source_files * sizeof(uint32_t));
264299
const auto offset = stream.tell();
265300

266-
source_files.resize(num_modules);
301+
// Append source files to array
302+
size_t n = source_files.size();
303+
source_files.resize(n + num_modules);
267304

268305
for (uint32_t k = 0; k < num_modules; ++k)
269306
{
270-
for (uint32_t i = 0; i < module_num_source_files[k]; ++i)
307+
uint16_t num_files = module_num_source_files[k];
308+
source_files[n + k].resize(num_files);
309+
310+
for (uint32_t i = 0; i < num_files; ++i)
271311
{
272312
stream.seek(offset + file_name_offsets[module_file_offsets[k] + i]);
273-
source_files[k].push_back(stream.read_string());
313+
source_files[n + k][i] = stream.read_string();
274314
}
275315
}
276316
}

0 commit comments

Comments
 (0)