Skip to content

Conversation

barsolo2000
Copy link

@barsolo2000 barsolo2000 commented Sep 16, 2025

GPUActions were not handled on the first stop-reply packed that is returned when we launch a process.

Modified the LaunchProcess method to capture and return the first stop-reply packet from the vRun command instead of discarding it. In ProcessGDBRemote::DoLaunch, we now use this captured launch response directly if it's a valid stop-reply packet, so GPU actions in the launch response are processed instead of ignored..

NOTE: It's just fixing the launch case, we also need to follow up and fix the attach and connect cases.

@barsolo2000 barsolo2000 marked this pull request as ready for review September 16, 2025 00:26
@@ -929,21 +930,22 @@ llvm::Error GDBRemoteCommunicationClient::LaunchProcess(const Args &args) {
packet.PutStringAsRawHex8(arg.ref());
}

StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
StringExtractorGDBRemote vrun_response;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to create a separate vrun_response here. We can just pass down the response we take as a parameter to LaunchProcess.

return false;

char first_char = m_packet.empty() ? '\0' : m_packet[0];
return first_char == 'T' || first_char == 'S';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.select_cpu()
self.expect(
"breakpoint list --internal",
substrs=["gpu_first_stop"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to expand this check a bit to show that we have hit the breakpoint

@dmpots
Copy link
Collaborator

dmpots commented Sep 16, 2025

Please run clang-format on this change to make sure it is formatted correctly.

Copy link
Collaborator

@dmpots dmpots left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -916,7 +916,8 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
return LLDB_INVALID_PROCESS_ID;
}

llvm::Error GDBRemoteCommunicationClient::LaunchProcess(const Args &args) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to change the return value to:

llvm::Expected<StringExtractorGDBRemote> GDBRemoteCommunicationClient::LaunchProcess(const Args &args);

Then we don't need to pass the StringExtractorGDBRemote &response in as a parameter.

Comment on lines 499 to 508
bool StringExtractorGDBRemote::IsStopReply() const {
if (!IsNormalResponse())
return false;

char first_char = m_packet.empty() ? '\0' : m_packet[0];
return first_char == 'T' || first_char == 'S' || first_char == 'W' ||
first_char == 'X' || first_char == 'w' || first_char == 'N' ||
first_char == 'O' || first_char == 'F';
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would check for 'T' or 'S' only here. 'W' is for exited, 'X' is for terminated, 'w' is for thread exited, 'N' is for non stop debugging, and 'O' is for output and 'F' is for calling syscalls.

So for using this in a launch scenario, we want to only check for a few. Maybe modifying this to be something like:

FLAGS_ENUM(StopReplyMask) {
  Signal =  (1u << 0),
  Exited = (1u << 1),
  Terminated = (1u << 2),
  Output = (1u << 3),
  NoResumed = (1u << 4),
  Syscall = (1u << 5),
  Any = ((Syscall << 1) - 1u),
};

bool StringExtractorGDBRemote::IsStopReply(uint32_t mask) const {
  if (!IsNormalResponse())
    return false;

  if (mask & Signal && (first_char == 'T' || first_char == 'S'))
    return true;
  if (mask & Exited && (first_char == 'w' || first_char == 'W'))
    return true;
  if (mask & Terminated && first_char == 'X')
    return true;
  if (mask & Output && first_char == 'O')
    return true;
  if (mask & NoResumed && first_char == 'N')
    return true;
  if (mask & Syscall && first_char == 'F')
    return true;
  return false;
}

Copy link
Owner

@clayborg clayborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes, looks good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants