Skip to content
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

Collecting dumps can cause process termination with "*** buffer overflow detected ***" message #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions threadstacks/signal_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <sys/timerfd.h>
#include <sys/types.h>
#include <unistd.h>
#include <poll.h>

#include <algorithm>
#include <cstring>
Expand Down Expand Up @@ -386,28 +387,31 @@ auto StackTraceCollector::Collect(std::string* error) -> std::vector<Result> {
// process to become non-responsive.
int flags = fcntl(pipe_fd[0], F_GETFL, 0);
fcntl(pipe_fd[0], F_SETFL, flags | O_NONBLOCK);
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(pipe_fd[0], &read_fds);
FD_SET(timer_fd, &read_fds);
auto max_fd = std::max(pipe_fd[0], timer_fd) + 1;
auto ret = select(max_fd, &read_fds, nullptr, nullptr, nullptr);
pollfd pipeAndTimerPollFd[2];
pipeAndTimerPollFd[0].fd = pipe_fd[0];
pipeAndTimerPollFd[0].events = POLLIN;
pipeAndTimerPollFd[1].fd = timer_fd;
pipeAndTimerPollFd[1].events = POLLIN;
const int noTimeout = -1;
auto ret = poll(pipeAndTimerPollFd, 2, noTimeout);
if (ret == -1) {
std::cerr << "select(...) failed, will try again" << std::endl; // errno
std::cerr << "poll(...) failed, will try again" << std::endl;
} else if (ret == 0) {
// We should never encounter this case as we use an infinite timeout in
// the select syscall.
std::cerr << "No file descriptors ready, will try again"
<< std::endl; // errno
} else if (FD_ISSET(timer_fd, &read_fds)) {
// This should never happen as 0 means timeout but no timeout has been given!
std::cerr << "poll() returned 0 even though no timeout was given, will try again" << std::endl;
} else if(pipeAndTimerPollFd[1].revents == POLLIN) {
std::cerr << "Failed to get all (" << tids.size()
<< ") the stacktrace acks within timeout. Got only " << acks
<< std::endl; // errno
<< ") the stacktrace messages within timeout. Got only " << acks
<< std::endl;
error->assign("Failed to get all (" + std::to_string(tids.size()) +
") stacktraces within timeout. Got only " +
std::to_string(acks));
return {};
} else if (FD_ISSET(pipe_fd[0], &read_fds)) {
} else {
if(pipeAndTimerPollFd[0].revents != POLLIN) {
std::cerr << "Error calling poll(), expected the pipe to be ready for reading!" << std::endl;
}

char ch;
auto num_read = read(pipe_fd[0], &ch, sizeof(ch));
if (-1 == num_read) {
Expand Down