Sometimes a closed Socket::Shared reads indefinitely and does not close session endpoint (part two)
- Ngôn ngữ chính
- C++
- Star
- 192
- Fork
- 66
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Mô tả
Ref: https://github.com/google/cppdap/issues/101
I'm still having this issue **sometimes**, at least on Mac OS X (Sonoma 14.0). I'm using commit 82beeea and there doesn't seem to have been any relevant changes since then https://github.com/google/cppdap/compare/82beeea...main
Here's an example server:
hello_debugger.cpp
[I know it's not the best code with the condition variables but it shows the issue I'm facing]
```cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include "dap/io.h"
#include "dap/network.h"
#include "dap/protocol.h"
#include "dap/session.h"
class Event {
public:
// wait() blocks until the event is fired.
void wait();
// fire() sets signals the event, and unblocks any calls to wait().
void fire();
private:
std::mutex mutex;
std::condition_variable cv;
bool fired = false;
};
void Event::wait() {
std::unique_lock lock(mutex);
cv.wait(lock, [&] { return fired; });
}
void Event::fire() {
std::unique_lock lock(mutex);
fired = true;
cv.notify_all();
}
Event terminate;
std::vector threads;
void my_handler(int s) {
printf("Caught signal %d\n", s);
terminate.fire();
}
int main(int argc, char** argv) {
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = my_handler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
auto _server = dap::net::Server::create();
auto address = "0.0.0.0";
auto started = _server->start(
address, 12345, [&](const std::shared_ptr& rw) {
threads.emplace_back([=] {
auto session = dap::Session::create();
session->onError([&](const char* msg) {
std::cout << "Session error: " << msg << "\n";
terminate.fire();
});
session->bind(rw,
[&]() { std::cout << "Session endpoint closed\n"; });
terminate.wait();
});
});
if (!started) {
std::cerr << "Failed to start DAP server.\n";
_server.reset();
}
sigaction(SIGINT, &sigIntHandler, NULL);
terminate.wait();
std::cout << "Exiting\n";
for (auto& thread : threads) {
thread.join();
}
return 0;
}
```
When I run the server and `nc localhost 12345` and then Ctrl+C the `nc` process, my CPU usage flies through the roof, and it looks like there is still an infinite read:
```
* thread #6, stop reason = breakpoint 3.1
* frame #0: 0x000000010008a520 hello_debugger`dap::Socket::Shared::read(this=0x000000013ef044e8, buffer=0x0000000170142c78, bytes=15) at socket.cpp:210:13
frame #1: 0x000000010000d678 hello_debugger`dap::ContentReader::buffer(this=0x0000000140104390, bytes=15) at content_stream.cpp:151:27
frame #2: 0x000000010000d8b4 hello_debugger`dap::ContentReader::scan(this=0x0000000140104390, seq="Content-Length:", len=15) at content_stream.cpp:96:10
frame #3: 0x000000010000d4c0 hello_debugger`dap::ContentReader::scan(this=0x0000000140104390, str="Content-Length:") at content_stream.cpp:107:10
frame #4: 0x000000010000d1d8 hello_debugger`dap::ContentReader::read(this=0x0000000140104390) at content_stream.cpp:56:10
```
Again, the `recv()` call is returning `0` on the closed socket:
https://github.com/google/cppdap/blob/6464cd7bd0a5639b11902055ca607b53915833fc/src/socket.cpp#L208-L209
The loop comes from here, where `reader.isOpen()` is `true`, but `getPayload()` is empty:
https://github.com/google/cppdap/blob/6464cd7bd0a5639b11902055ca607b53915833fc/src/session.cpp#L87-L91
I say **sometimes** this issue happens because sometimes the session `ClosedHandler` does execute ... other times, it hangs in this loop forever. **Under no circumstance is the session error handler triggered.**
Hướng dẫn đóng góp
Đánh giá
Issue này chưa được đánh giá.