Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions llvm-15.0.3/lldb/tools/lldb-crash-server/UncoreHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#include <iostream>
#include <memory>
#include <regex>
#include <fstream>
#include <unistd.h>
#include <fcntl.h>

#include "UncoreHandler.h"

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

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

if (status != 0) {
std::string loader_file_path = m_working_dir + "/outdir/loader.bin";

if (status != 0 && !llvm::sys::fs::exists(loader_file_path)) {
llvm::errs() << "Uncore execution failed.\n";
return false;
}

return true;
}

bool WriteToPipe(std::string working_dir) {
std::string pipe_path = working_dir + "/gdb_lldb_signal_pipe";
int fd = open(pipe_path.c_str(), O_WRONLY);
if (fd == -1) {
llvm::errs() << "Failed to open the FIFO pipe. \n";
return false;
}

std::string message = "Crash server is ready.";
if (write(fd, message.c_str(), message.size()) == -1) {
llvm::errs() << "Failed to write into the pipe. \n";
close(fd);
return false;
}

close(fd);
return true;
}


::pid_t lldb::UncoreHandler::RunLoaderProcess() {

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

llvm::errs() << "Failed to execute loader.bin process. \n";
} else {
sleep(2);
// TODO: Some kind of synchronization should be implemented with loader.bin
// so this can be removed
sleep(20);

if (!WriteToPipe(m_working_dir)) {
return LLDB_INVALID_PROCESS_ID;
}

return pid;
}

Expand Down
2 changes: 1 addition & 1 deletion llvm-15.0.3/lldb/tools/lldb-crash-server/UncoreHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class UncoreHandler {
<< "\n";
exit(1);
}
m_working_dir = cwd.str().data();
m_working_dir = cwd.c_str();
}

bool RunUncore();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import subprocess
import socket
import os
import json
from contextlib import closing
from pty import STDERR_FILENO, STDOUT_FILENO

Expand All @@ -19,6 +20,9 @@
core_registers = {}
live_registers = {}

# Current working directory
cwd = os.getcwd()

# Global variable to store Crash server path
lldb_crash_server_path = None

Expand All @@ -41,12 +45,14 @@ def __init__(self):
)

def invoke(self, arg, from_tty):
global lldb_crash_server_path
global lldb_crash_server_path, cwd

args = arg.split()
if len(args) != 2:
print("Usage: setup_session <binary> <corefile>")
return

gdb_settings = self.get_gdb_setting()

binary, corefile = args
gdb.execute(f"file {binary}")
Expand All @@ -64,12 +70,22 @@ def invoke(self, arg, from_tty):
if lldb_crash_server_path is None:
print("Crash server path is not set.")
return

# Create uncore json file
self.create_json_file(corefile, binary, gdb_settings)

# Create a named pipe
pipe_path = os.path.join(cwd, "gdb_lldb_signal_pipe")
self.create_pipe(pipe_path)

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

# Read from a named pipe (waiting for a signal from Crash server)
self.read_from_pipe(pipe_path)

# Connect to remote target
gdb.execute(f"target remote localhost:{port}")

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

def create_json_file(self, core_path, binary_path, gdb_settings):
global cwd

# Set the uncore output and json file path
output_path = os.path.join(cwd, "outdir")
json_path = os.path.join(cwd, "uncore.json")

data = {
"core": core_path,
"binos_root": "",
"entry_point": "main",
"prog": binary_path,
"pid": "",
"additional_resources": "",
"custom_o_file": [],
"output_directory": output_path,
"hot_patch": {
},
"gdbparse": {
"gdb": "gdb",
"args": [
binary_path,
core_path
],
"kwargs": {
}
}
}

if len(gdb_settings) > 1:
# Create a gdb script with all commands from gdb_settings
script_path = os.path.join(cwd, "gdb_uncore.script")
with open(script_path, "w") as script_file:
for cmd in gdb_settings:
script_file.write(cmd + "\n")
data["gdbparse"]["kwargs"]["-x"] = script_path
elif len(gdb_settings) == 1:
data["gdbparse"]["kwargs"]["-ex"] = gdb_settings[0]

# Convert the JSON data to a string
json_str = json.dumps(data, indent=4)

# Write the JSON string to a file in the current working directory
try:
with open(json_path, "w") as json_file:
json_file.write(json_str)
print(f"JSON file successfully created at: {json_path}")
except Exception as e:
print(f"Error: {e}")

# Get gdb session settings
def get_gdb_setting(self):
gdb_settings = []

# Retrieve the process sysroot setting
sysroot_setting = gdb.execute("show sysroot", to_string=True)
if sysroot_setting.startswith("The current system root is"):
sysroot_path = sysroot_setting.split('"')[1].strip()
if sysroot_path != "target:" and sysroot_path != "":
gdb_settings.append(f"set sysroot {sysroot_path}")

# Retrieve and process solib-search-path setting
solib_search_path_setting = gdb.execute("show solib-search-path", to_string=True)
if solib_search_path_setting.startswith("The search path for loading non-absolute shared library symbol files is"):
solib_search_path = solib_search_path_setting.split(' is ')[1].strip()
if solib_search_path != "." and solib_search_path != "":
gdb_settings.append(f"set solib-search-path {solib_search_path}")

return gdb_settings

# Create a named FIFO pipe
def create_pipe(self, pipe_path):
try:
os.mkfifo(pipe_path)
except OSError as e:
print(f"Error creating the pipe: {e}")

# Read from the named pipe
def read_from_pipe(self, pipe_path):
try:
with open(pipe_path, "r") as pipe:
message = pipe.read()
print(message)
except Exception as e:
print(f"Error reading from the pipe: {e}")


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