-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[lldb] Fix EditlineTest closing files multiple times. #169100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This updates the EditlineTest to use `lldb::FileSP` to ensure the associated FDs are only closed a single time. Currently, there is some confusion between the `FilePointer`, `PseudoTerminal` and `LockableStreamFile` about when the files are closed resulting in a crash in some due to a `fflush` on a closed file.
|
@llvm/pr-subscribers-lldb Author: John Harrison (ashgti) ChangesThis updates the EditlineTest to use Currently, there is some confusion between the Full diff: https://github.com/llvm/llvm-project/pull/169100.diff 1 Files Affected:
diff --git a/lldb/unittests/Editline/EditlineTest.cpp b/lldb/unittests/Editline/EditlineTest.cpp
index 2875f4ee7e6b4..2afc33680f348 100644
--- a/lldb/unittests/Editline/EditlineTest.cpp
+++ b/lldb/unittests/Editline/EditlineTest.cpp
@@ -9,6 +9,8 @@
#include "lldb/Host/Config.h"
#include "lldb/Host/File.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/lldb-forward.h"
+#include "llvm/Testing/Support/Error.h"
#if LLDB_ENABLE_LIBEDIT
@@ -25,7 +27,6 @@
#include "TestingSupport/SubsystemRAII.h"
#include "lldb/Host/Editline.h"
#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Pipe.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/StreamFile.h"
#include "lldb/Utility/Status.h"
@@ -37,27 +38,6 @@ namespace {
const size_t TIMEOUT_MILLIS = 5000;
}
-class FilePointer {
-public:
- FilePointer() = delete;
-
- FilePointer(const FilePointer &) = delete;
-
- FilePointer(FILE *file_p) : _file_p(file_p) {}
-
- ~FilePointer() {
- if (_file_p != nullptr) {
- const int close_result = fclose(_file_p);
- EXPECT_EQ(0, close_result);
- }
- }
-
- operator FILE *() { return _file_p; }
-
-private:
- FILE *_file_p;
-};
-
/**
Wraps an Editline class, providing a simple way to feed
input (as if from the keyboard) and receive output from Editline.
@@ -90,44 +70,39 @@ class EditlineAdapter {
std::recursive_mutex output_mutex;
std::unique_ptr<lldb_private::Editline> _editline_sp;
- PseudoTerminal _pty;
- int _pty_primary_fd = -1;
- int _pty_secondary_fd = -1;
-
- std::unique_ptr<FilePointer> _el_secondary_file;
+ lldb::FileSP _el_primary_file;
+ lldb::FileSP _el_secondary_file;
};
-EditlineAdapter::EditlineAdapter()
- : _editline_sp(), _pty(), _el_secondary_file() {
+EditlineAdapter::EditlineAdapter() : _editline_sp(), _el_secondary_file() {
lldb_private::Status error;
+ PseudoTerminal pty;
// Open the first primary pty available.
- EXPECT_THAT_ERROR(_pty.OpenFirstAvailablePrimary(O_RDWR), llvm::Succeeded());
+ EXPECT_THAT_ERROR(pty.OpenFirstAvailablePrimary(O_RDWR), llvm::Succeeded());
+ // Open the corresponding secondary pty.
+ EXPECT_THAT_ERROR(pty.OpenSecondary(O_RDWR), llvm::Succeeded());
// Grab the primary fd. This is a file descriptor we will:
// (1) write to when we want to send input to editline.
// (2) read from when we want to see what editline sends back.
- _pty_primary_fd = _pty.GetPrimaryFileDescriptor();
+ _el_primary_file.reset(
+ new NativeFile(pty.ReleasePrimaryFileDescriptor(),
+ lldb_private::NativeFile::eOpenOptionReadWrite, true));
- // Open the corresponding secondary pty.
- EXPECT_THAT_ERROR(_pty.OpenSecondary(O_RDWR), llvm::Succeeded());
- _pty_secondary_fd = _pty.GetSecondaryFileDescriptor();
-
- _el_secondary_file.reset(new FilePointer(fdopen(_pty_secondary_fd, "rw")));
- EXPECT_FALSE(nullptr == *_el_secondary_file);
- if (*_el_secondary_file == nullptr)
- return;
+ _el_secondary_file.reset(
+ new NativeFile(pty.ReleaseSecondaryFileDescriptor(),
+ lldb_private::NativeFile::eOpenOptionReadWrite, true));
lldb::LockableStreamFileSP output_stream_sp =
- std::make_shared<LockableStreamFile>(*_el_secondary_file,
- NativeFile::Unowned, output_mutex);
+ std::make_shared<LockableStreamFile>(_el_secondary_file, output_mutex);
lldb::LockableStreamFileSP error_stream_sp =
- std::make_shared<LockableStreamFile>(*_el_secondary_file,
- NativeFile::Unowned, output_mutex);
+ std::make_shared<LockableStreamFile>(_el_secondary_file, output_mutex);
// Create an Editline instance.
_editline_sp.reset(new lldb_private::Editline(
- "gtest editor", *_el_secondary_file, output_stream_sp, error_stream_sp,
+ "gtest editor", _el_secondary_file->GetStream(), output_stream_sp,
+ error_stream_sp,
/*color=*/false));
_editline_sp->SetPrompt("> ");
@@ -140,7 +115,7 @@ EditlineAdapter::EditlineAdapter()
void EditlineAdapter::CloseInput() {
if (_el_secondary_file != nullptr)
- _el_secondary_file.reset(nullptr);
+ _el_secondary_file->Close();
}
bool EditlineAdapter::SendLine(const std::string &line) {
@@ -148,19 +123,14 @@ bool EditlineAdapter::SendLine(const std::string &line) {
if (!IsValid())
return false;
+ std::string out = line + "\n";
+
// Write the line out to the pipe connected to editline's input.
- ssize_t input_bytes_written =
- ::write(_pty_primary_fd, line.c_str(),
- line.length() * sizeof(std::string::value_type));
-
- const char *eoln = "\n";
- const size_t eoln_length = strlen(eoln);
- input_bytes_written =
- ::write(_pty_primary_fd, eoln, eoln_length * sizeof(char));
-
- EXPECT_NE(-1, input_bytes_written) << strerror(errno);
- EXPECT_EQ(eoln_length * sizeof(char), size_t(input_bytes_written));
- return eoln_length * sizeof(char) == size_t(input_bytes_written);
+ size_t num_bytes = out.length() * sizeof(std::string::value_type);
+ EXPECT_THAT_ERROR(_el_primary_file->Write(out.c_str(), num_bytes).takeError(),
+ llvm::Succeeded());
+ EXPECT_EQ(num_bytes, out.length() * sizeof(std::string::value_type));
+ return true;
}
bool EditlineAdapter::SendLines(const std::vector<std::string> &lines) {
@@ -215,7 +185,7 @@ bool EditlineAdapter::IsInputComplete(lldb_private::Editline *editline,
}
void EditlineAdapter::ConsumeAllOutput() {
- FilePointer output_file(fdopen(_pty_primary_fd, "r"));
+ FILE *output_file = _el_primary_file->GetStream();
int ch;
while ((ch = fgetc(output_file)) != EOF) {
|
🐧 Linux x64 Test Results
|
This updates the EditlineTest to use `lldb::FileSP` to ensure the associated FDs are only closed a single time. Currently, there is some confusion between the `FilePointer`, `PseudoTerminal` and `LockableStreamFile` about when the files are closed resulting in a crash in some due to a `fflush` on a closed file.
This updates the EditlineTest to use `lldb::FileSP` to ensure the associated FDs are only closed a single time. Currently, there is some confusion between the `FilePointer`, `PseudoTerminal` and `LockableStreamFile` about when the files are closed resulting in a crash in some due to a `fflush` on a closed file.
This updates the EditlineTest to use
lldb::FileSPto ensure the associated FDs are only closed a single time.Currently, there is some confusion between the
FilePointer,PseudoTerminalandLockableStreamFileabout when the files are closed resulting in a crash in some due to afflushon a closed file.