Skip to content

Commit

Permalink
Merged main:4b284b9ca809 into amd-gfx:f12986ba074f
Browse files Browse the repository at this point in the history
Local branch amd-gfx f12986b Merged main:6ed3083a9654 into amd-gfx:1c8672849f8a
Remote branch main 4b284b9 [lldb] Fix TestPlatformProcessConnect.py
  • Loading branch information
Sw authored and Sw committed Jan 14, 2021
2 parents f12986b + 4b284b9 commit 27f3456
Show file tree
Hide file tree
Showing 13 changed files with 356 additions and 81 deletions.
26 changes: 13 additions & 13 deletions lldb/packages/Python/lldbsuite/test/lldbtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,19 @@ def cleanup(self, dictionary=None):
"Don't know how to do cleanup with dictionary: " +
dictionary)

def invoke(self, obj, name, trace=False):
"""Use reflection to call a method dynamically with no argument."""
trace = (True if traceAlways else trace)

method = getattr(obj, name)
import inspect
self.assertTrue(inspect.ismethod(method),
name + "is a method name of object: " + str(obj))
result = method()
with recording(self, trace) as sbuf:
print(str(method) + ":", result, file=sbuf)
return result

def getLLDBLibraryEnvVal(self):
""" Returns the path that the OS-specific library search environment variable
(self.dylibPath) should be set to in order for a program to find the LLDB
Expand Down Expand Up @@ -2624,19 +2637,6 @@ def expect_var_path(
value_check.check_value(self, eval_result, str(eval_result))
return eval_result

def invoke(self, obj, name, trace=False):
"""Use reflection to call a method dynamically with no argument."""
trace = (True if traceAlways else trace)

method = getattr(obj, name)
import inspect
self.assertTrue(inspect.ismethod(method),
name + "is a method name of object: " + str(obj))
result = method()
with recording(self, trace) as sbuf:
print(str(method) + ":", result, file=sbuf)
return result

def build(
self,
architecture=None,
Expand Down
61 changes: 38 additions & 23 deletions lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,43 @@ bool ObjectFileWasm::ParseHeader() {

Symtab *ObjectFileWasm::GetSymtab() { return nullptr; }

static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) {
return llvm::StringSwitch<SectionType>(Name)
.Case("abbrev", eSectionTypeDWARFDebugAbbrev)
.Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
.Case("addr", eSectionTypeDWARFDebugAddr)
.Case("aranges", eSectionTypeDWARFDebugAranges)
.Case("cu_index", eSectionTypeDWARFDebugCuIndex)
.Case("frame", eSectionTypeDWARFDebugFrame)
.Case("info", eSectionTypeDWARFDebugInfo)
.Case("info.dwo", eSectionTypeDWARFDebugInfoDwo)
.Cases("line", "line.dwo", eSectionTypeDWARFDebugLine)
.Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr)
.Case("loc", eSectionTypeDWARFDebugLoc)
.Case("loc.dwo", eSectionTypeDWARFDebugLocDwo)
.Case("loclists", eSectionTypeDWARFDebugLocLists)
.Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo)
.Case("macinfo", eSectionTypeDWARFDebugMacInfo)
.Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro)
.Case("names", eSectionTypeDWARFDebugNames)
.Case("pubnames", eSectionTypeDWARFDebugPubNames)
.Case("pubtypes", eSectionTypeDWARFDebugPubTypes)
.Case("ranges", eSectionTypeDWARFDebugRanges)
.Case("rnglists", eSectionTypeDWARFDebugRngLists)
.Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo)
.Case("str", eSectionTypeDWARFDebugStr)
.Case("str.dwo", eSectionTypeDWARFDebugStrDwo)
.Case("str_offsets", eSectionTypeDWARFDebugStrOffsets)
.Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
.Case("tu_index", eSectionTypeDWARFDebugTuIndex)
.Case("types", eSectionTypeDWARFDebugTypes)
.Case("types.dwo", eSectionTypeDWARFDebugTypesDwo)
.Default(eSectionTypeOther);
}
return eSectionTypeOther;
}

void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
if (m_sections_up)
return;
Expand Down Expand Up @@ -280,29 +317,7 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
// Code section.
vm_addr = 0;
} else {
section_type =
llvm::StringSwitch<SectionType>(sect_info.name.GetStringRef())
.Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev)
.Case(".debug_addr", eSectionTypeDWARFDebugAddr)
.Case(".debug_aranges", eSectionTypeDWARFDebugAranges)
.Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex)
.Case(".debug_frame", eSectionTypeDWARFDebugFrame)
.Case(".debug_info", eSectionTypeDWARFDebugInfo)
.Case(".debug_line", eSectionTypeDWARFDebugLine)
.Case(".debug_line_str", eSectionTypeDWARFDebugLineStr)
.Case(".debug_loc", eSectionTypeDWARFDebugLoc)
.Case(".debug_loclists", eSectionTypeDWARFDebugLocLists)
.Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo)
.Case(".debug_macro", eSectionTypeDWARFDebugMacro)
.Case(".debug_names", eSectionTypeDWARFDebugNames)
.Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames)
.Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes)
.Case(".debug_ranges", eSectionTypeDWARFDebugRanges)
.Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists)
.Case(".debug_str", eSectionTypeDWARFDebugStr)
.Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets)
.Case(".debug_types", eSectionTypeDWARFDebugTypes)
.Default(eSectionTypeOther);
section_type = GetSectionTypeFromName(sect_info.name.GetStringRef());
if (section_type == eSectionTypeOther)
continue;
section_name = sect_info.name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme,
const char *hostname,
uint16_t port, const char *path) {
StreamString result;
result.Printf("%s://%s", scheme, hostname);
result.Printf("%s://[%s]", scheme, hostname);
if (port != 0)
result.Printf(":%u", port);
if (path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vAttach,
&GDBRemoteCommunicationServerLLGS::Handle_vAttach);
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vAttachWait,
&GDBRemoteCommunicationServerLLGS::Handle_vAttachWait);
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vCont,
&GDBRemoteCommunicationServerLLGS::Handle_vCont);
Expand Down Expand Up @@ -334,6 +337,71 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
return Status();
}

Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess(
llvm::StringRef process_name) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));

std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1);

// Create the matcher used to search the process list.
ProcessInstanceInfoList exclusion_list;
ProcessInstanceInfoMatch match_info;
match_info.GetProcessInfo().GetExecutableFile().SetFile(
process_name, llvm::sys::path::Style::posix);
match_info.SetNameMatchType(NameMatch::EndsWith);

// Create the excluded process list before polling begins.
Host::FindProcesses(match_info, exclusion_list);
LLDB_LOG(log, "placed '{0}' processes in the exclusion list.",
exclusion_list.size());

LLDB_LOG(log, "waiting for '{0}' to appear", process_name);

auto is_in_exclusion_list =
[&exclusion_list](const ProcessInstanceInfo &info) {
for (auto &excluded : exclusion_list) {
if (excluded.GetProcessID() == info.GetProcessID())
return true;
}
return false;
};

ProcessInstanceInfoList loop_process_list;
while (true) {
loop_process_list.clear();
if (Host::FindProcesses(match_info, loop_process_list)) {
// Remove all the elements that are in the exclusion list.
llvm::erase_if(loop_process_list, is_in_exclusion_list);

// One match! We found the desired process.
if (loop_process_list.size() == 1) {
auto matching_process_pid = loop_process_list[0].GetProcessID();
LLDB_LOG(log, "found pid {0}", matching_process_pid);
return AttachToProcess(matching_process_pid);
}

// Multiple matches! Return an error reporting the PIDs we found.
if (loop_process_list.size() > 1) {
StreamString error_stream;
error_stream.Format(
"Multiple executables with name: '{0}' found. Pids: ",
process_name);
for (size_t i = 0; i < loop_process_list.size() - 1; ++i) {
error_stream.Format("{0}, ", loop_process_list[i].GetProcessID());
}
error_stream.Format("{0}.", loop_process_list.back().GetProcessID());

Status error;
error.SetErrorString(error_stream.GetString());
return error;
}
}
// No matches, we have not found the process. Sleep until next poll.
LLDB_LOG(log, "sleep {0} seconds", polling_interval);
std::this_thread::sleep_for(polling_interval);
}
}

void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
NativeProcessProtocol *process) {
assert(process && "process cannot be NULL");
Expand Down Expand Up @@ -3188,6 +3256,36 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach(
return SendStopReasonForState(m_debugged_process_up->GetState());
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_vAttachWait(
StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));

// Consume the ';' after the identifier.
packet.SetFilePos(strlen("vAttachWait"));

if (!packet.GetBytesLeft() || packet.GetChar() != ';')
return SendIllFormedResponse(packet, "vAttachWait missing expected ';'");

// Allocate the buffer for the process name from vAttachWait.
std::string process_name;
if (!packet.GetHexByteString(process_name))
return SendIllFormedResponse(packet,
"vAttachWait failed to parse process name");

LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name);

Status error = AttachWaitProcess(process_name);
if (error.Fail()) {
LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name,
error);
return SendErrorResponse(error);
}

// Notify we attached by sending a stop packet.
return SendStopReasonForState(m_debugged_process_up->GetState());
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ class GDBRemoteCommunicationServerLLGS
/// attach operation.
Status AttachToProcess(lldb::pid_t pid);

/// Wait to attach to a process with a given name.
///
/// This method supports waiting for the next instance of a process
/// with a given name and attaching llgs to that via the configured
/// Platform.
///
/// \return
/// An Status object indicating the success or failure of the
/// attach operation.
Status AttachWaitProcess(llvm::StringRef process_name);

// NativeProcessProtocol::NativeDelegate overrides
void InitializeDelegate(NativeProcessProtocol *process) override;

Expand Down Expand Up @@ -170,6 +181,8 @@ class GDBRemoteCommunicationServerLLGS

PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);

PacketResult Handle_vAttachWait(StringExtractorGDBRemote &packet);

PacketResult Handle_D(StringExtractorGDBRemote &packet);

PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
platform_port, platform_path);
UNUSED_IF_ASSERT_DISABLED(ok);
assert(ok);
url << platform_ip.str() << ":" << *port;
url << '[' << platform_ip.str() << "]:" << *port;
} else {
socket_name = GetDomainSocketPath("gdbserver").GetPath();
url << socket_name;
Expand Down
1 change: 1 addition & 0 deletions lldb/test/API/macosx/builtin-debugtrap/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ int global = 0;
int main()
{
global = 5; // Set a breakpoint here
puts("");
__builtin_debugtrap();
global = 10;
__builtin_trap();
Expand Down
75 changes: 75 additions & 0 deletions lldb/test/API/tools/lldb-server/TestGdbRemoteAttachWait.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

import os
from time import sleep

import gdbremote_testcase
import lldbgdbserverutils
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class TestGdbRemoteAttachWait(gdbremote_testcase.GdbRemoteTestCaseBase):

mydir = TestBase.compute_mydir(__file__)

def test_attach_with_vAttachWait(self):
exe = '%s_%d' % (self.testMethodName, os.getpid())

def launch_inferior():
inferior = self.launch_process_for_attach(
inferior_args=["sleep:60"],
exe_path=self.getBuildArtifact(exe))
self.assertIsNotNone(inferior)
self.assertTrue(inferior.pid > 0)
self.assertTrue(
lldbgdbserverutils.process_is_running(
inferior.pid, True))
return inferior

self.build(dictionary={'EXE': exe})
self.set_inferior_startup_attach_manually()

server = self.connect_to_debug_monitor()
self.assertIsNotNone(server)

# Launch the first inferior (we shouldn't attach to this one).
launch_inferior()

self.add_no_ack_remote_stream()
self.test_sequence.add_log_lines([
# Do the attach.
"read packet: $vAttachWait;{}#00".format(lldbgdbserverutils.gdbremote_hex_encode_string(exe)),
], True)
# Run the stream until attachWait.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)

# Sleep so we're sure that the inferior is launched after we ask for the attach.
sleep(1)

# Launch the second inferior (we SHOULD attach to this one).
inferior_to_attach = launch_inferior()

# Make sure the attach succeeded.
self.test_sequence.add_log_lines([
{"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
"capture": {1: "stop_signal_hex"}},
], True)
self.add_process_info_collection_packets()


# Run the stream sending the response..
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)

# Gather process info response.
process_info = self.parse_process_info_response(context)
self.assertIsNotNone(process_info)

# Ensure the process id matches what we expected.
pid_text = process_info.get('pid', None)
self.assertIsNotNone(pid_text)
reported_pid = int(pid_text, base=16)
self.assertEqual(reported_pid, inferior_to_attach.pid)
Loading

0 comments on commit 27f3456

Please sign in to comment.