thrift-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Trevor Gattis <gtr...@gmail.com>
Subject TNonblockingServer.cpp -- Strange vtable seg fault in TConnection::workSocket()
Date Thu, 26 Jan 2012 22:58:11 GMT
I'm using Thrift 0.7.0 and am trying to get a C++ server up and running.
I'm able to run a simple server just fine with no issues, but when I try to
convert that server code to using the TNonblockingServer setup, the server
crashes.

I've used gdb to pinpoint the issue which occurs in
TConnection::workSocket() when it's trying to execute the ->read method:

    // if we've already received some bytes we kept them here
    framing.size = readWant_;
    // determine size of this frame
    try {
      // Read from the socket
*      fetch = tSocket_->read(&framing.buf[readBufferPos_],*
*                             uint32_t(sizeof(framing.size) -
readBufferPos_));*

Here's my run in gdb when I was trying to debug what was going on:

Starting program: /home/trevor/src/main/server/tservice/MyThriftService.dbg
[Thread debugging using libthread_db enabled]
[New Thread 0xb7539710 (LWP 3248)]
Thrift: Wed Jan 25 17:12:18 2012 libevent 1.4.13-stable method epoll

Breakpoint 1, apache::thrift::server::TConnection::workSocket
(this=0x87a4130) at src/server/TNonblockingServer.cpp:168
(gdb) stepi
0x00a2d73a    168    in src/server/TNonblockingServer.cpp
(gdb) stepi
0x00a2d73f    168    in src/server/TNonblockingServer.cpp
(gdb) stepi
0x00a2d741    168    in src/server/TNonblockingServer.cpp
(gdb) stepi
0x00a2d744    168    in src/server/TNonblockingServer.cpp
(gdb) stepi
0x00a2d746    168    in src/server/TNonblockingServer.cpp
(gdb) stepi
0x00a2d74a    168    in src/server/TNonblockingServer.cpp
(gdb) stepi
0x00a2d74e    168    in src/server/TNonblockingServer.cpp
(gdb) stepi
0x00a2d752    168    in src/server/TNonblockingServer.cpp
(gdb) stepi
0x0825e988 in vtable for __cxxabiv1::__si_class_type_info ()
(gdb) bt
#0  apache::thrift::server::TConnection::workSocket (this=0x84e2130) at
src/server/TNonblockingServer.cpp:168
#1  0x01055857 in apache::thrift::server::TConnection::eventHandler (fd=10,
v=0x84e2130) at src/server/TNonblockingServer.h:915
#2  0x0177d188 in event_base_loop () from /usr/lib/libevent-1.4.so.2
#3  0x0104f25f in apache::thrift::server::TNonblockingServer::serve
(this=0xbf892ff8) at src/server/TNonblockingServer.cpp:923
#4  0x08100eed in main (argc=-1081527784, argv=0x4e36e8c) at
MyThriftService.cpp:61
(gdb) p socketState_
$21 = apache::thrift::server::SOCKET_RECV_FRAMING
(gdb) p framing
$22 = {
  buf = "\000\000\000",
  size = 0
}
(gdb) p tSocket_
$23 = {
  px = 0x84e2648,
  pn = {
    pi_ = 0x84e17f8
  }
}
(gdb) p readBufferPos_
$24 = 0
(gdb) ptype *tSocket_.px
type = class apache::thrift::transport::TSocket : public
apache::thrift::transport::TVirtualTransport<apache::thrift::transport::TSocket,apache::thrift::transport::TTransportDefaults>
{
  protected:
    string host_;
    string peerHost_;
    string peerAddress_;
    int peerPort_;
    int port_;
    string path_;
    int socket_;
    int connTimeout_;
    int sendTimeout_;
    int recvTimeout_;
    bool lingerOn_;
    int lingerVal_;
    bool noDelay_;
    int maxRecvRetries_;
    timeval recvTimeval_;
    apache::thrift::transport::TSocket::._97 cachedPeerAddr_;
    timespec startTime_;
    static bool useLowMinRto_;

  public:
    void TSocket(void);
    void TSocket(string, int);
    void TSocket(string);
    void TSocket(int);
    ~TSocket(int);
    virtual bool isOpen();
    virtual bool peek();
    virtual void open();
    virtual void close();
    uint32_t read(unsigned char*, unsigned int);
    void write(unsigned char const*, unsigned int);
    uint32_t write_partial(unsigned char const*, unsigned int);
    string getHost();
    int getPort();
    void setHost(std::string);
    void setPort(int);
    void setLinger(bool, int);
    void setNoDelay(bool);
    void setConnTimeout(int);
    void setRecvTimeout(int);
    void setSendTimeout(int);
    void setMaxRecvRetries(int);
    string getSocketInfo();
    string getPeerHost();
    string getPeerAddress();
    int getPeerPort();
    int getSocketFD();
    void setSocketFD(int);
    sockaddr * getCachedAddress(unsigned int*) const;
    static void setUseLowMinRto(bool);
    static bool getUseLowMinRto();
    void setCachedAddress(sockaddr const*, unsigned int);
  protected:
    void openConnection(addrinfo*);
  private:
    void unix_open();
    void local_open();
}
(gdb) p readBufferPos_
$25 = 0
(gdb) bt
#0  0x0825e988 in vtable for __cxxabiv1::__si_class_type_info ()
#1  0x01050755 in apache::thrift::server::TConnection::workSocket
(this=0x84e2130) at src/server/TNonblockingServer.cpp:168
#2  0x01055857 in apache::thrift::server::TConnection::eventHandler (fd=10,
v=0x84e2130) at src/server/TNonblockingServer.h:915
#3  0x0177d188 in event_base_loop () from /usr/lib/libevent-1.4.so.2
#4  0x0104f25f in apache::thrift::server::TNonblockingServer::serve
(this=0xbf892ff8) at src/server/TNonblockingServer.cpp:923
#5  0x08100eed in main (argc=-1081527784, argv=0x4e36e8c) at
MyThriftService.cpp:61

(gdb) stepi

Program received signal SIGSEGV, Segmentation fault.
0x0825e988 in vtable for __cxxabiv1::__si_class_type_info ()


What could I possibly be missing?  I've now tried to pear down my code to
the simplest version possible, but I'm still getting a segfault at this
point in the code.  Any ideas?  And again, when I use the simple server
implementation, the server runs just fine.

Any help is greatly appreciated.  The server code is below.

Thanks,
  Trevor


=======
// -- MyThriftServer.cpp

#include "thrift/Thrift.h"
#include "thrift/server.h"
#include "thrift/MyData.h"
#include "MyDataStore.h"


using boost::shared_ptr;
using namespace std;


class MyDataHandler : virtual public MyDataIf {
 public:
  MyDataHandler();

  void GetEntries(std::vector<Entry> & _return, const std::string& user);

};


MyDataHandler::MyDataHandler() {
}


void MyDataHandler::GetEntries(vector<Entry> & _return, const string& user)
{
  vector<string> entries = MyDataStore::getEntries(user);

  for (size_t i = 0; i < entries.size(); i++) {
    Entry e;
    e.user = user;
    e.record = entries[i];
    e.__isset.record = true;

    _return.push_back(e);
  }

}


//-------------------------------------------

int main(int argc, char **argv) {
  using namespace ::apache::thrift;

  shared_ptr<MyDataHandler> handler(new MyDataHandler());
  shared_ptr<TProcessor> processor(new MyDataProcessor(handler));
  shared_ptr<protocol::TProtocolFactory> protocolFactory(new
protocol::TBinaryProtocolFactory());

  // using thread pool with maximum 15 threads to handle incoming requests
//  shared_ptr<concurrency::ThreadManager> threadManager =
concurrency::ThreadManager::newSimpleThreadManager(15);
//  shared_ptr<concurrency::PosixThreadFactory> threadFactory =
shared_ptr<concurrency::PosixThreadFactory>(new
concurrency::PosixThreadFactory());
//  threadManager->threadFactory(threadFactory);
//  threadManager->start();

  server::TNonblockingServer server(processor, protocolFactory, 14341);
  server.serve();

  return 0;

}

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message