This is an archive of the discontinued LLVM Phabricator instance.

[lldb] [Communication] Add a WriteAll() method that resumes writing
ClosedPublic

Authored by mgorny on Oct 20 2021, 12:32 PM.

Details

Summary

Add a Communication::WriteAll() that resumes Write() if the initial call
did not write all data. Use it in GDBRemoteCommunication when sending
packets in order to fix handling partial writes (i.e. just resume/retry
them rather than erring out). This fixes LLDB failures when writing
large packets to a pty.

The solution used utilizes a short sleep in order to wait for the write
buffer to be freed. Using select() would be better but it would require
much deeper changes to the code and does not seem justified at the time.

Diff Detail

Event Timeline

mgorny requested review of this revision.Oct 20 2021, 12:32 PM
mgorny updated this revision to Diff 381063.
mgorny created this revision.

clang-format

I think it would be worth at least spending a bit of time to understand the reason for using non-blocking i/o here. Given that all Reads should go through the select(2) in ConnectionFileDescriptor::BytesAvailable, it's possible we could avoid it altogether.

I'm not against that. However, unless I'm mistaken — even with blocking I/O, we need to account for the write() being interrupted in the middle of operation and returning less than src_len.

I'm not against that. However, unless I'm mistaken — even with blocking I/O, we need to account for the write() being interrupted in the middle of operation and returning less than src_len.

You're not mistaken. However, we can get rid of the funky sleep.

mgorny updated this revision to Diff 381980.Oct 25 2021, 7:02 AM

sleep() is no longer necessary now that we're operating in blocking mode.

Maybe a quick unit test which send like 1MB of data in a single call or something similar?

lldb/include/lldb/Core/Communication.h
195

It might be worthwhile to emphasize that this will happily return after a partial write and point the reader to WriteAll if he wants to write everything.

lldb/source/Core/Communication.cpp
29

delete

199

It looks like this could be a do-while loop.

mgorny updated this revision to Diff 382227.Oct 26 2021, 1:54 AM
mgorny marked 2 inline comments as done.

Implemented requested changes. Added a minimal-ish unittest.

lldb/source/Core/Communication.cpp
199

Ah, yes, without the sleep it makes sense.

mgorny added inline comments.Oct 26 2021, 1:58 AM
lldb/unittests/Core/CommunicationTest.cpp
80

If we want to be super-strict, I can add an another Write() call above to verify that a partial write happens — but I'm not sure if we should fail on that.

labath accepted this revision.Oct 26 2021, 1:58 AM
This revision is now accepted and ready to land.Oct 26 2021, 1:58 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 26 2021, 3:45 AM