Thrift error logging improvements
Summary: - Move strerror_s to Thrift.h (was previously in TTransportException.h)
- Capture errno as soon as syscall returns failure and make it part of error message.
- Cleaned up several instances of the wrong error value being printed.
- More consistently pass the errno in the TTransport Exception
- Add more consistent error logging for the various transport failure modes
Reviewed By: dreiss
Test Plan: - compile everything.
- test on search tier
Revert: OK
TracCamp Project: Thrift
DiffCamp Revision: 11077
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665648 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/Thrift.cpp b/lib/cpp/src/Thrift.cpp
index 88890d4..963f938 100644
--- a/lib/cpp/src/Thrift.cpp
+++ b/lib/cpp/src/Thrift.cpp
@@ -11,6 +11,31 @@
TOutput GlobalOutput;
+std::string TOutput::strerror_s(int errno_copy) {
+#ifndef HAVE_STRERROR_R
+ return "errno = " + lexical_cast<string>(errno_copy);
+#else // HAVE_STRERROR_R
+
+ char b_errbuf[1024] = { '\0' };
+#ifdef STRERROR_R_CHAR_P
+ char *b_error = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
+#else
+ char *b_error = b_errbuf;
+ int rv = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
+ if (rv == -1) {
+ // strerror_r failed. omgwtfbbq.
+ return "XSI-compliant strerror_r() failed with errno = " +
+ lexical_cast<string>(errno_copy);
+ }
+#endif
+ // Can anyone prove that explicit cast is probably not necessary
+ // to ensure that the string object is constructed before
+ // b_error becomes invalid?
+ return std::string(b_error);
+
+#endif // HAVE_STRERROR_R
+}
+
uint32_t TApplicationException::read(facebook::thrift::protocol::TProtocol* iprot) {
uint32_t xfer = 0;
std::string fname;
diff --git a/lib/cpp/src/Thrift.h b/lib/cpp/src/Thrift.h
index 8e93bb0..6eb20bb 100644
--- a/lib/cpp/src/Thrift.h
+++ b/lib/cpp/src/Thrift.h
@@ -21,6 +21,8 @@
#include <set>
#include <vector>
#include <exception>
+#include <string>
+#include <boost/lexical_cast.hpp>
#include "TLogging.h"
@@ -28,7 +30,7 @@
class TOutput {
public:
- TOutput() : f_(&perrorTimeWrapper) {}
+ TOutput() : f_(&errorTimeWrapper) {}
inline void setOutputFunction(void (*function)(const char *)){
f_ = function;
@@ -38,15 +40,18 @@
f_(message);
}
- inline static void perrorTimeWrapper(const char* msg) {
+ inline static void errorTimeWrapper(const char* msg) {
time_t now;
char dbgtime[25];
time(&now);
ctime_r(&now, dbgtime);
dbgtime[24] = 0;
- fprintf(stderr, "%s ", dbgtime);
- perror(msg);
+ fprintf(stderr, "Thrift: %s %s\n", dbgtime, msg);
}
+
+ /** Just like strerror_r but returns a C++ string object. */
+ static std::string strerror_s(int errno_copy);
+
private:
void (*f_)(const char *);
};
diff --git a/lib/cpp/src/server/TNonblockingServer.cpp b/lib/cpp/src/server/TNonblockingServer.cpp
index c840bcc..ebe85a6 100644
--- a/lib/cpp/src/server/TNonblockingServer.cpp
+++ b/lib/cpp/src/server/TNonblockingServer.cpp
@@ -50,10 +50,12 @@
// Signal completion back to the libevent thread via a socketpair
int8_t b = 0;
if (-1 == send(taskHandle_, &b, sizeof(int8_t), 0)) {
- GlobalOutput("TNonblockingServer::Task: send");
+ string errStr = "TNonblockingServer::Task: send " + TOutput::strerror_s(errno);
+ GlobalOutput(errStr.c_str());
}
if (-1 == ::close(taskHandle_)) {
- GlobalOutput("TNonblockingServer::Task: close, possible resource leak");
+ string errStr = "TNonblockingServer::Task: close, possible resource leak " + TOutput::strerror_s(errno);
+ GlobalOutput(errStr.c_str());
}
}
@@ -139,7 +141,8 @@
}
if (errno != ECONNRESET) {
- GlobalOutput("TConnection::workSocket() recv -1");
+ string errStr = "TConnection::workSocket() recv -1 " + TOutput::strerror_s(errno);
+ GlobalOutput(errStr.c_str());
}
}
@@ -175,7 +178,8 @@
return;
}
if (errno != EPIPE) {
- GlobalOutput("TConnection::workSocket() send -1");
+ string errStr = "TConnection::workSocket() send -1 " + TOutput::strerror_s(errno);
+ GlobalOutput(errStr.c_str());
}
close();
return;
@@ -221,7 +225,8 @@
// We are setting up a Task to do this work and we will wait on it
int sv[2];
if (-1 == socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
- GlobalOutput("TConnection::socketpair() failed");
+ string errStr = "TConnection::socketpair() failed " + TOutput::strerror_s(errno);
+ GlobalOutput(errStr.c_str());
// Now we will fall through to the APP_WAIT_TASK block with no response
} else {
// Create task and dispatch to the thread manager
@@ -519,7 +524,8 @@
int flags;
if ((flags = fcntl(clientSocket, F_GETFL, 0)) < 0 ||
fcntl(clientSocket, F_SETFL, flags | O_NONBLOCK) < 0) {
- GlobalOutput("thriftServerEventHandler: set O_NONBLOCK");
+ string errStr = "thriftServerEventHandler: set O_NONBLOCK (fcntl) " + TOutput::strerror_s(errno);
+ GlobalOutput(errStr.c_str());
close(clientSocket);
return;
}
@@ -542,7 +548,8 @@
// Done looping accept, now we have to make sure the error is due to
// blocking. Any other error is a problem
if (errno != EAGAIN && errno != EWOULDBLOCK) {
- GlobalOutput("thriftServerEventHandler: accept()");
+ string errStr = "thriftServerEventHandler: accept() " + TOutput::strerror_s(errno);
+ GlobalOutput(errStr.c_str());
}
}
@@ -564,7 +571,8 @@
// Wildcard address
error = getaddrinfo(NULL, port, &hints, &res0);
if (error) {
- GlobalOutput("TNonblockingServer::serve() getaddrinfo");
+ string errStr = "TNonblockingServer::serve() getaddrinfo " + string(gai_strerror(error));
+ GlobalOutput(errStr.c_str());
return;
}
diff --git a/lib/cpp/src/server/TNonblockingServer.h b/lib/cpp/src/server/TNonblockingServer.h
index 89c69a0..7c6bc7f 100644
--- a/lib/cpp/src/server/TNonblockingServer.h
+++ b/lib/cpp/src/server/TNonblockingServer.h
@@ -12,6 +12,8 @@
#include <transport/TTransportUtils.h>
#include <concurrency/ThreadManager.h>
#include <stack>
+#include <string>
+#include <errno.h>
#include <cstdlib>
#include <event.h>
@@ -320,7 +322,8 @@
static void taskHandler(int fd, short /* which */, void* v) {
assert(fd == ((TConnection*)v)->taskHandle_);
if (-1 == ::close(((TConnection*)v)->taskHandle_)) {
- GlobalOutput("TConnection::taskHandler close handle failed, resource leak");
+ std::string errStr = "TConnection::taskHandler close handle failed, resource leak " + TOutput::strerror_s(errno);
+ GlobalOutput(errStr.c_str());
}
((TConnection*)v)->transition();
}
diff --git a/lib/cpp/src/transport/TFileTransport.cpp b/lib/cpp/src/transport/TFileTransport.cpp
index a4b275f..41c6005 100644
--- a/lib/cpp/src/transport/TFileTransport.cpp
+++ b/lib/cpp/src/transport/TFileTransport.cpp
@@ -101,8 +101,10 @@
flush();
fprintf(stderr, "error, current file (%s) not closed\n", filename_.c_str());
if (-1 == ::close(fd_)) {
- GlobalOutput("TFileTransport: error in file close");
- throw TTransportException("TFileTransport: error in file close");
+ int errno_copy = errno;
+ string errStr = "TFileTransport: resetOutputFile() ::close() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::UNKNOWN, "TFileTransport: error in file close", errno_copy);
}
}
@@ -159,7 +161,9 @@
// close logfile
if (fd_ > 0) {
if(-1 == ::close(fd_)) {
- GlobalOutput("TFileTransport: error in file close");
+ int errno_copy = errno;
+ string errStr = "TFileTransport: ~TFileTransport() ::close() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
}
}
}
@@ -315,8 +319,10 @@
// empty out both the buffers
if (enqueueBuffer_->isEmpty() && dequeueBuffer_->isEmpty()) {
if (-1 == ::close(fd_)) {
- GlobalOutput("TFileTransport: error in close");
- throw TTransportException("TFileTransport: error in file close");
+ int errno_copy = errno;
+ string errStr = "TFileTransport: writerThread() ::close() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::UNKNOWN, "TFileTransport: error in file close", errno_copy);
}
// just be safe and sync to disk
fsync(fd_);
@@ -362,8 +368,10 @@
uint8_t zeros[padding];
bzero(zeros, padding);
if (-1 == ::write(fd_, zeros, padding)) {
- GlobalOutput("TFileTransport: error while padding zeros");
- throw TTransportException("TFileTransport: error while padding zeros");
+ int errno_copy = errno;
+ string errStr = "TFileTransport: writerThread() error while padding zeros " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::UNKNOWN, "TFileTransport: error while padding zeros", errno_copy);
}
unflushed += padding;
offset_ += padding;
@@ -373,8 +381,10 @@
// write the dequeued event to the file
if (outEvent->eventSize_ > 0) {
if (-1 == ::write(fd_, outEvent->eventBuff_, outEvent->eventSize_)) {
- GlobalOutput("TFileTransport: error while writing event");
- throw TTransportException("TFileTransport: error while writing event");
+ int errno_copy = errno;
+ string errStr = "TFileTransport: error while writing event " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::UNKNOWN, "TFileTransport: error while writing event", errno_copy);
}
unflushed += outEvent->eventSize_;
@@ -746,10 +756,10 @@
// make sure open call was successful
if(fd_ == -1) {
- char errorMsg[1024];
- sprintf(errorMsg, "TFileTransport: Could not open file: %s", filename_.c_str());
- GlobalOutput(errorMsg);
- throw TTransportException(errorMsg);
+ int errno_copy = errno;
+ string errStr = "TFileTransport: openLogFile() ::open() file: " + filename_ + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::NOT_OPEN, errStr, errno_copy);
}
}
diff --git a/lib/cpp/src/transport/TServerSocket.cpp b/lib/cpp/src/transport/TServerSocket.cpp
index 38ca363..2b4e7c3 100644
--- a/lib/cpp/src/transport/TServerSocket.cpp
+++ b/lib/cpp/src/transport/TServerSocket.cpp
@@ -79,7 +79,9 @@
void TServerSocket::listen() {
int sv[2];
if (-1 == socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
- GlobalOutput("TServerSocket::init()");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() socketpair() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
intSock1_ = -1;
intSock2_ = -1;
} else {
@@ -113,36 +115,44 @@
serverSocket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (serverSocket_ == -1) {
- GlobalOutput("TServerSocket::listen() socket");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() socket() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
close();
- throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.");
+ throw TTransportException(TTransportException::NOT_OPEN, "Could not create server socket.", errno_copy);
}
// Set reusaddress to prevent 2MSL delay on accept
int one = 1;
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_REUSEADDR,
&one, sizeof(one))) {
- GlobalOutput("TServerSocket::listen() SO_REUSEADDR");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() setsockopt() SO_REUSEADDR " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
close();
- throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_REUSEADDR");
+ throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_REUSEADDR", errno_copy);
}
// Set TCP buffer sizes
if (tcpSendBuffer_ > 0) {
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_SNDBUF,
&tcpSendBuffer_, sizeof(tcpSendBuffer_))) {
- GlobalOutput("TServerSocket::listen() SO_SNDBUF");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() setsockopt() SO_SNDBUF " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
close();
- throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF");
+ throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_SNDBUF", errno_copy);
}
}
if (tcpRecvBuffer_ > 0) {
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_RCVBUF,
&tcpRecvBuffer_, sizeof(tcpRecvBuffer_))) {
- GlobalOutput("TServerSocket::listen() SO_RCVBUF");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() setsockopt() SO_RCVBUF " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
close();
- throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF");
+ throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_RCVBUF", errno_copy);
}
}
@@ -150,9 +160,11 @@
#ifdef TCP_DEFER_ACCEPT
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, TCP_DEFER_ACCEPT,
&one, sizeof(one))) {
- GlobalOutput("TServerSocket::listen() TCP_DEFER_ACCEPT");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() setsockopt() TCP_DEFER_ACCEPT " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
close();
- throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_DEFER_ACCEPT");
+ throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_DEFER_ACCEPT", errno_copy);
}
#endif // #ifdef TCP_DEFER_ACCEPT
@@ -160,27 +172,37 @@
struct linger ling = {0, 0};
if (-1 == setsockopt(serverSocket_, SOL_SOCKET, SO_LINGER,
&ling, sizeof(ling))) {
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() setsockopt() SO_LINGER " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
close();
- GlobalOutput("TServerSocket::listen() SO_LINGER");
- throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER");
+ throw TTransportException(TTransportException::NOT_OPEN, "Could not set SO_LINGER", errno_copy);
}
// TCP Nodelay, speed over bandwidth
if (-1 == setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY,
&one, sizeof(one))) {
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() setsockopt() TCP_NODELAY " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
close();
- GlobalOutput("setsockopt TCP_NODELAY");
- throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY");
+ throw TTransportException(TTransportException::NOT_OPEN, "Could not set TCP_NODELAY", errno_copy);
}
// Set NONBLOCK on the accept socket
int flags = fcntl(serverSocket_, F_GETFL, 0);
if (flags == -1) {
- throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() fcntl() F_GETFL " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed", errno_copy);
}
if (-1 == fcntl(serverSocket_, F_SETFL, flags | O_NONBLOCK)) {
- throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() fcntl() O_NONBLOCK " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed", errno_copy);
}
// prepare the port information
@@ -209,9 +231,11 @@
// Call listen
if (-1 == ::listen(serverSocket_, acceptBacklog_)) {
- GlobalOutput("TServerSocket::listen() LISTEN");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::listen() listen() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
close();
- throw TTransportException(TTransportException::NOT_OPEN, "Could not listen");
+ throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy);
}
// The socket is now listening!
@@ -242,17 +266,22 @@
// a certain number
continue;
}
- GlobalOutput("TServerSocket::acceptImpl() select -1");
- throw TTransportException(TTransportException::UNKNOWN);
+ int errno_copy = errno;
+ string errStr = "TServerSocket::acceptImpl() poll() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno_copy);
} else if (ret > 0) {
// Check for an interrupt signal
if (intSock2_ >= 0 && FD_ISSET(intSock2_, &fds)) {
int8_t buf;
if (-1 == recv(intSock2_, &buf, sizeof(int8_t), 0)) {
- GlobalOutput("TServerSocket::acceptImpl() interrupt receive");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::acceptImpl() recv() interrupt " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
}
throw TTransportException(TTransportException::INTERRUPTED);
}
+
// Check for the actual server socket being ready
if (FD_ISSET(serverSocket_, &fds)) {
break;
@@ -271,7 +300,8 @@
if (clientSocket < 0) {
int errno_copy = errno;
- GlobalOutput("TServerSocket::accept()");
+ string errStr = "TServerSocket::acceptImpl() ::accept() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
throw TTransportException(TTransportException::UNKNOWN, "accept()", errno_copy);
}
@@ -279,12 +309,15 @@
int flags = fcntl(clientSocket, F_GETFL, 0);
if (flags == -1) {
int errno_copy = errno;
- GlobalOutput("TServerSocket::select() fcntl GETFL");
+ string errStr = "TServerSocket::acceptImpl() fcntl() F_GETFL " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
throw TTransportException(TTransportException::UNKNOWN, "fcntl(F_GETFL)", errno_copy);
}
+
if (-1 == fcntl(clientSocket, F_SETFL, flags & ~O_NONBLOCK)) {
int errno_copy = errno;
- GlobalOutput("TServerSocket::select() fcntl SETFL");
+ string errStr = "TServerSocket::acceptImpl() fcntl() F_SETFL ~O_NONBLOCK " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
throw TTransportException(TTransportException::UNKNOWN, "fcntl(F_SETFL)", errno_copy);
}
@@ -303,7 +336,9 @@
if (intSock1_ >= 0) {
int8_t byte = 0;
if (-1 == send(intSock1_, &byte, sizeof(int8_t), 0)) {
- GlobalOutput("TServerSocket::interrupt()");
+ int errno_copy = errno;
+ string errStr = "TServerSocket::interrupt() send() " + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
}
}
}
diff --git a/lib/cpp/src/transport/TSocket.cpp b/lib/cpp/src/transport/TSocket.cpp
index 85a6358..6a16664 100644
--- a/lib/cpp/src/transport/TSocket.cpp
+++ b/lib/cpp/src/transport/TSocket.cpp
@@ -94,7 +94,7 @@
int r = recv(socket_, &buf, 1, MSG_PEEK);
if (r == -1) {
int errno_copy = errno;
- string errStr = "TSocket::peek() " + getSocketInfo();
+ string errStr = "TSocket::peek() recv() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
throw TTransportException(TTransportException::UNKNOWN, "recv()", errno_copy);
}
@@ -109,7 +109,7 @@
socket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (socket_ == -1) {
int errno_copy = errno;
- string errStr = "TSocket::open() socket " + getSocketInfo();
+ string errStr = "TSocket::open() socket() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
throw TTransportException(TTransportException::NOT_OPEN, "socket()", errno_copy);
}
@@ -134,26 +134,33 @@
int flags = fcntl(socket_, F_GETFL, 0);
if (connTimeout_ > 0) {
if (-1 == fcntl(socket_, F_SETFL, flags | O_NONBLOCK)) {
- throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed");
+ int errno_copy = errno;
+ string errStr = "TSocket::open() fcntl() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed", errno_copy);
}
} else {
if (-1 == fcntl(socket_, F_SETFL, flags & ~O_NONBLOCK)) {
- throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed");
+ int errno_copy = errno;
+ string errStr = "TSocket::open() fcntl " + getSocketInfo() + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+ throw TTransportException(TTransportException::NOT_OPEN, "fcntl() failed", errno_copy);
}
}
// Connect the socket
int ret = connect(socket_, res->ai_addr, res->ai_addrlen);
+ // success case
if (ret == 0) {
goto done;
}
if (errno != EINPROGRESS) {
int errno_copy = errno;
- string errStr = "TSocket::open() connect " + getSocketInfo();
+ string errStr = "TSocket::open() connect() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
- throw TTransportException(TTransportException::NOT_OPEN, "connect()", errno_copy);
+ throw TTransportException(TTransportException::NOT_OPEN, "connect() failed", errno_copy);
}
@@ -164,34 +171,35 @@
ret = poll(fds, 1, connTimeout_);
if (ret > 0) {
- // Ensure connected
+ // Ensure the socket is connected and that there are no errors set
int val;
socklen_t lon;
lon = sizeof(int);
int ret2 = getsockopt(socket_, SOL_SOCKET, SO_ERROR, (void *)&val, &lon);
if (ret2 == -1) {
int errno_copy = errno;
- string errStr = "TSocket::open() getsockopt SO_ERROR " + getSocketInfo();
+ string errStr = "TSocket::open() getsockopt() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
- throw TTransportException(TTransportException::NOT_OPEN, "open()", errno_copy);
+ throw TTransportException(TTransportException::NOT_OPEN, "getsockopt()", errno_copy);
}
+ // no errors on socket, go to town
if (val == 0) {
goto done;
}
- int errno_copy = errno;
- string errStr = "TSocket::open() SO_ERROR was set " + getSocketInfo();
+ string errStr = "TSocket::open() error on socket (after poll) " + getSocketInfo() + TOutput::strerror_s(val);
GlobalOutput(errStr.c_str());
- throw TTransportException(TTransportException::NOT_OPEN, "open()", errno_copy);
+ throw TTransportException(TTransportException::NOT_OPEN, "socket open() error", val);
} else if (ret == 0) {
- int errno_copy = errno;
+ // socket timed out
string errStr = "TSocket::open() timed out " + getSocketInfo();
GlobalOutput(errStr.c_str());
- throw TTransportException(TTransportException::NOT_OPEN, "open()", errno_copy);
+ throw TTransportException(TTransportException::NOT_OPEN, "open() timed out");
} else {
+ // error on poll()
int errno_copy = errno;
- string errStr = "TSocket::open() poll error " + getSocketInfo();
+ string errStr = "TSocket::open() poll() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
- throw TTransportException(TTransportException::NOT_OPEN, "open()", errno_copy);
+ throw TTransportException(TTransportException::NOT_OPEN, "poll() failed", errno_copy);
}
done:
@@ -210,8 +218,10 @@
}
struct addrinfo hints, *res, *res0;
+ res = NULL;
+ res0 = NULL;
int error;
- char port[sizeof("65536") + 1];
+ char port[sizeof("65536")];
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
@@ -221,7 +231,8 @@
error = getaddrinfo(host_.c_str(), port, &hints, &res0);
if (error) {
- fprintf(stderr, "getaddrinfo %d: %s\n", error, gai_strerror(error));
+ string errStr = "TSocket::open() getaddrinfo() " + getSocketInfo() + string(gai_strerror(error));
+ GlobalOutput(errStr.c_str());
close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not resolve host for client socket.");
}
@@ -310,7 +321,7 @@
}
// Now it's not a try again case, but a real probblez
- string errStr = "TSocket::read() " + getSocketInfo();
+ string errStr = "TSocket::read() recv() " + getSocketInfo() + TOutput::strerror_s(errno);
GlobalOutput(errStr.c_str());
// If we disconnect with no linger time
@@ -329,9 +340,7 @@
}
// Some other error, whatevz
- char buff[1024];
- sprintf(buff, "ERROR errno: %d", errno);
- throw TTransportException(TTransportException::UNKNOWN, buff);
+ throw TTransportException(TTransportException::UNKNOWN, "Unknown", errno);
}
// The remote host has closed the socket
@@ -365,16 +374,16 @@
// Fail on a send error
if (b < 0) {
+ int errno_copy = errno;
+ string errStr = "TSocket::write() send() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
+ GlobalOutput(errStr.c_str());
+
if (errno == EPIPE || errno == ECONNRESET || errno == ENOTCONN) {
- int errno_copy = errno;
close();
- throw TTransportException(TTransportException::NOT_OPEN, "send()", errno_copy);
+ throw TTransportException(TTransportException::NOT_OPEN, "write() send()", errno_copy);
}
- int errno_copy = errno;
- string errStr = "TSocket::write() send < 0 " + getSocketInfo();
- GlobalOutput(errStr.c_str());
- throw TTransportException(TTransportException::UNKNOWN, "send", errno_copy);
+ throw TTransportException(TTransportException::UNKNOWN, "write() send()", errno_copy);
}
// Fail on blocked send
@@ -411,7 +420,8 @@
struct linger l = {(lingerOn_ ? 1 : 0), lingerVal_};
int ret = setsockopt(socket_, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
if (ret == -1) {
- string errStr = "TSocket::setLinger() " + getSocketInfo();
+ int errno_copy = errno;
+ string errStr = "TSocket::setLinger() setsockopt() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
}
}
@@ -426,7 +436,8 @@
int v = noDelay_ ? 1 : 0;
int ret = setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
if (ret == -1) {
- string errStr = "TSocket::setNoDelay() " + getSocketInfo();
+ int errno_copy = errno;
+ string errStr = "TSocket::setNoDelay() setsockopt() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
}
}
@@ -455,7 +466,8 @@
struct timeval r = recvTimeval_;
int ret = setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, &r, sizeof(r));
if (ret == -1) {
- string errStr = "TSocket::setRecvTimeout() " + getSocketInfo();
+ int errno_copy = errno;
+ string errStr = "TSocket::setRecvTimeout() setsockopt() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
}
}
@@ -477,7 +489,8 @@
(int)((sendTimeout_%1000)*1000)};
int ret = setsockopt(socket_, SOL_SOCKET, SO_SNDTIMEO, &s, sizeof(s));
if (ret == -1) {
- string errStr = "TSocket::setSendTimeout() " + getSocketInfo();
+ int errno_copy = errno;
+ string errStr = "TSocket::setSendTimeout() setsockopt() " + getSocketInfo() + TOutput::strerror_s(errno_copy);
GlobalOutput(errStr.c_str());
}
}
diff --git a/lib/cpp/src/transport/TSocket.h b/lib/cpp/src/transport/TSocket.h
index f0495ec..8d4a5a7 100644
--- a/lib/cpp/src/transport/TSocket.h
+++ b/lib/cpp/src/transport/TSocket.h
@@ -223,7 +223,6 @@
/** Recv timeout timeval */
struct timeval recvTimeval_;
-
};
}}} // facebook::thrift::transport
diff --git a/lib/cpp/src/transport/TTransportException.cpp b/lib/cpp/src/transport/TTransportException.cpp
index e632265..e231a93 100644
--- a/lib/cpp/src/transport/TTransportException.cpp
+++ b/lib/cpp/src/transport/TTransportException.cpp
@@ -14,29 +14,5 @@
namespace facebook { namespace thrift { namespace transport {
-string TTransportException::strerror_s(int errno_copy) {
-#ifndef HAVE_STRERROR_R
- return "errno = " + lexical_cast<string>(errno_copy);
-#else // HAVE_STRERROR_R
-
- char b_errbuf[1024] = { '\0' };
-#ifdef STRERROR_R_CHAR_P
- char *b_error = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
-#else
- char *b_error = b_errbuf;
- int rv = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
- if (rv == -1) {
- // strerror_r failed. omgwtfbbq.
- return "XSI-compliant strerror_r() failed with errno = " +
- lexical_cast<string>(errno_copy);
- }
-#endif
- // Can anyone prove that explicit cast is probably not necessary
- // to ensure that the string object is constructed before
- // b_error becomes invalid?
- return string(b_error);
-
-#endif // HAVE_STRERROR_R
-}
-
}}} // facebook::thrift::transport
+
diff --git a/lib/cpp/src/transport/TTransportException.h b/lib/cpp/src/transport/TTransportException.h
index 73bad80..09129ec 100644
--- a/lib/cpp/src/transport/TTransportException.h
+++ b/lib/cpp/src/transport/TTransportException.h
@@ -58,7 +58,7 @@
TTransportException(TTransportExceptionType type,
const std::string& message,
int errno_copy) :
- facebook::thrift::TException(message + ": " + strerror_s(errno_copy)),
+ facebook::thrift::TException(message + ": " + TOutput::strerror_s(errno_copy)),
type_(type) {}
virtual ~TTransportException() throw() {}