Skip to content

Commit a5291c9

Browse files
authored
Fixing issues noticed during testing. (#69)
- Added json file creation to GDB script, so user does not need to create or modify Uncore json file, just needs to enter any command settings (like sysroot or solib-search-path setting) before running 'setup_session' command. - Added Crash server/Uncore and GDB synchronization needed when Uncore takes longer time to be executed. + some smaller changes
1 parent bfcc3ce commit a5291c9

File tree

3 files changed

+138
-4
lines changed

3 files changed

+138
-4
lines changed

llvm-15.0.3/lldb/tools/lldb-crash-server/UncoreHandler.cpp

+34-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#include <iostream>
33
#include <memory>
44
#include <regex>
5+
#include <fstream>
6+
#include <unistd.h>
7+
#include <fcntl.h>
58

69
#include "UncoreHandler.h"
710

@@ -14,14 +17,36 @@ bool lldb::UncoreHandler::RunUncore() {
1417

1518
int status = std::system(cmd.c_str());
1619

17-
if (status != 0) {
20+
std::string loader_file_path = m_working_dir + "/outdir/loader.bin";
21+
22+
if (status != 0 && !llvm::sys::fs::exists(loader_file_path)) {
1823
llvm::errs() << "Uncore execution failed.\n";
1924
return false;
2025
}
2126

2227
return true;
2328
}
2429

30+
bool WriteToPipe(std::string working_dir) {
31+
std::string pipe_path = working_dir + "/gdb_lldb_signal_pipe";
32+
int fd = open(pipe_path.c_str(), O_WRONLY);
33+
if (fd == -1) {
34+
llvm::errs() << "Failed to open the FIFO pipe. \n";
35+
return false;
36+
}
37+
38+
std::string message = "Crash server is ready.";
39+
if (write(fd, message.c_str(), message.size()) == -1) {
40+
llvm::errs() << "Failed to write into the pipe. \n";
41+
close(fd);
42+
return false;
43+
}
44+
45+
close(fd);
46+
return true;
47+
}
48+
49+
2550
::pid_t lldb::UncoreHandler::RunLoaderProcess() {
2651

2752
::pid_t pid = fork();
@@ -40,7 +65,14 @@ ::pid_t lldb::UncoreHandler::RunLoaderProcess() {
4065

4166
llvm::errs() << "Failed to execute loader.bin process. \n";
4267
} else {
43-
sleep(2);
68+
// TODO: Some kind of synchronization should be implemented with loader.bin
69+
// so this can be removed
70+
sleep(20);
71+
72+
if (!WriteToPipe(m_working_dir)) {
73+
return LLDB_INVALID_PROCESS_ID;
74+
}
75+
4476
return pid;
4577
}
4678

llvm-15.0.3/lldb/tools/lldb-crash-server/UncoreHandler.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class UncoreHandler {
2424
<< "\n";
2525
exit(1);
2626
}
27-
m_working_dir = cwd.str().data();
27+
m_working_dir = cwd.c_str();
2828
}
2929

3030
bool RunUncore();

llvm-15.0.3/lldb/tools/lldb-crash-server/gdb-interop/gdb_session_setup.py

+103-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import subprocess
55
import socket
66
import os
7+
import json
78
from contextlib import closing
89
from pty import STDERR_FILENO, STDOUT_FILENO
910

@@ -19,6 +20,9 @@
1920
core_registers = {}
2021
live_registers = {}
2122

23+
# Current working directory
24+
cwd = os.getcwd()
25+
2226
# Global variable to store Crash server path
2327
lldb_crash_server_path = None
2428

@@ -41,12 +45,14 @@ def __init__(self):
4145
)
4246

4347
def invoke(self, arg, from_tty):
44-
global lldb_crash_server_path
48+
global lldb_crash_server_path, cwd
4549

4650
args = arg.split()
4751
if len(args) != 2:
4852
print("Usage: setup_session <binary> <corefile>")
4953
return
54+
55+
gdb_settings = self.get_gdb_setting()
5056

5157
binary, corefile = args
5258
gdb.execute(f"file {binary}")
@@ -64,12 +70,22 @@ def invoke(self, arg, from_tty):
6470
if lldb_crash_server_path is None:
6571
print("Crash server path is not set.")
6672
return
73+
74+
# Create uncore json file
75+
self.create_json_file(corefile, binary, gdb_settings)
76+
77+
# Create a named pipe
78+
pipe_path = os.path.join(cwd, "gdb_lldb_signal_pipe")
79+
self.create_pipe(pipe_path)
6780

6881
# Start Crash server as a subprocess
6982
port = self.find_free_port()
7083
subprocess.Popen([lldb_crash_server_path, "g", f"localhost:{port}", binary,
7184
"--uncore-json", "./uncore.json"], stdout=STDOUT_FILENO, stderr=STDERR_FILENO)
7285

86+
# Read from a named pipe (waiting for a signal from Crash server)
87+
self.read_from_pipe(pipe_path)
88+
7389
# Connect to remote target
7490
gdb.execute(f"target remote localhost:{port}")
7591

@@ -98,6 +114,92 @@ def find_free_port(self):
98114
s.bind(('localhost', 0))
99115
return s.getsockname()[1]
100116

117+
def create_json_file(self, core_path, binary_path, gdb_settings):
118+
global cwd
119+
120+
# Set the uncore output and json file path
121+
output_path = os.path.join(cwd, "outdir")
122+
json_path = os.path.join(cwd, "uncore.json")
123+
124+
data = {
125+
"core": core_path,
126+
"binos_root": "",
127+
"entry_point": "main",
128+
"prog": binary_path,
129+
"pid": "",
130+
"additional_resources": "",
131+
"custom_o_file": [],
132+
"output_directory": output_path,
133+
"hot_patch": {
134+
},
135+
"gdbparse": {
136+
"gdb": "gdb",
137+
"args": [
138+
binary_path,
139+
core_path
140+
],
141+
"kwargs": {
142+
}
143+
}
144+
}
145+
146+
if len(gdb_settings) > 1:
147+
# Create a gdb script with all commands from gdb_settings
148+
script_path = os.path.join(cwd, "gdb_uncore.script")
149+
with open(script_path, "w") as script_file:
150+
for cmd in gdb_settings:
151+
script_file.write(cmd + "\n")
152+
data["gdbparse"]["kwargs"]["-x"] = script_path
153+
elif len(gdb_settings) == 1:
154+
data["gdbparse"]["kwargs"]["-ex"] = gdb_settings[0]
155+
156+
# Convert the JSON data to a string
157+
json_str = json.dumps(data, indent=4)
158+
159+
# Write the JSON string to a file in the current working directory
160+
try:
161+
with open(json_path, "w") as json_file:
162+
json_file.write(json_str)
163+
print(f"JSON file successfully created at: {json_path}")
164+
except Exception as e:
165+
print(f"Error: {e}")
166+
167+
# Get gdb session settings
168+
def get_gdb_setting(self):
169+
gdb_settings = []
170+
171+
# Retrieve the process sysroot setting
172+
sysroot_setting = gdb.execute("show sysroot", to_string=True)
173+
if sysroot_setting.startswith("The current system root is"):
174+
sysroot_path = sysroot_setting.split('"')[1].strip()
175+
if sysroot_path != "target:" and sysroot_path != "":
176+
gdb_settings.append(f"set sysroot {sysroot_path}")
177+
178+
# Retrieve and process solib-search-path setting
179+
solib_search_path_setting = gdb.execute("show solib-search-path", to_string=True)
180+
if solib_search_path_setting.startswith("The search path for loading non-absolute shared library symbol files is"):
181+
solib_search_path = solib_search_path_setting.split(' is ')[1].strip()
182+
if solib_search_path != "." and solib_search_path != "":
183+
gdb_settings.append(f"set solib-search-path {solib_search_path}")
184+
185+
return gdb_settings
186+
187+
# Create a named FIFO pipe
188+
def create_pipe(self, pipe_path):
189+
try:
190+
os.mkfifo(pipe_path)
191+
except OSError as e:
192+
print(f"Error creating the pipe: {e}")
193+
194+
# Read from the named pipe
195+
def read_from_pipe(self, pipe_path):
196+
try:
197+
with open(pipe_path, "r") as pipe:
198+
message = pipe.read()
199+
print(message)
200+
except Exception as e:
201+
print(f"Error reading from the pipe: {e}")
202+
101203

102204
class RestoreRegisters(gdb.Command):
103205
"""Restore registers to saved values from either corefile or live process."""

0 commit comments

Comments
 (0)