title: fcgi + leveldb = core dump?
body: <p>in RHEL 5.7 x86_64, when fcgi and leveldb run together, max_open_files = 4000, it's getting a segmentation fault when client sent requests. How?</p>
  
  <p>it would not happen when use mysql.</p>
  
  <p>ulimit -n = 655360</p>
  
  <p>gdb:</p>
  
  <pre><code>Program received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0x52b09940 (LWP 47717)]
  0x0000000000000f32 in ?? ()
  (gdb) bt
  #0  0x0000000000000f32 in ?? ()
  #1  0x0000000052b09120 in ?? ()
  #2  0x0000000000000000 in ?? ()
  </code></pre>
  
  <p>Sample code:</p>
  
  <pre><code>vector&lt;pthread_t&gt; mthread;
  const int  THREAD_COUNT = 20;
  static int counts[THREAD_COUNT];
  pthread_t id[THREAD_COUNT];
  int mSocketFd = 0;
  vector&lt;int&gt; mfd;
  static void *doit(void* arg)
  {
      int rc, i;
      pid_t pid = getpid();
      FCGX_Request request;
      char *server_name;
      FCGX_InitRequest(&amp;request, mSocketFd, 0);
      for (;;)
      {
          static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
          static pthread_mutex_t counts_mutex = PTHREAD_MUTEX_INITIALIZER;
  
          /* Some platforms require accept() serialization, some don't.. */
          pthread_mutex_lock(&amp;accept_mutex);
          rc = FCGX_Accept_r(&amp;request);
          pthread_mutex_unlock(&amp;accept_mutex);
  
          if (rc &lt; 0)
              continue;
          server_name = FCGX_GetParam("SERVER_NAME", request.envp);
  
          FCGX_FPrintF(request.out,
                  "Content-type: text/html\r\n"
                  "\r\n"
                  "&lt;title&gt;FastCGI Hello! (multi-threaded C, fcgiapp library)&lt;/title&gt;"
                  "&lt;h1&gt;FastCGI Hello! (multi-threaded C, fcgiapp library)&lt;/h1&gt;"
                  "Thread %d, Process %ld&lt;p&gt;"
                  "Request counts for %d threads running on host &lt;i&gt;%s&lt;/i&gt;&lt;p&gt;&lt;code&gt;",
                  123, pid, THREAD_COUNT, server_name ? server_name : "?");
  
          sleep(2);
  
          pthread_mutex_lock(&amp;counts_mutex);
  //        ++counts[thread_id];
          for (i = 0; i &lt; THREAD_COUNT; i++)
              FCGX_FPrintF(request.out, "%5d " , counts[i]);
          pthread_mutex_unlock(&amp;counts_mutex);
  
          FCGX_Finish_r(&amp;request);
      }
      cout &lt;&lt; "end doit" &lt;&lt; endl;
  
      return NULL;
  }
  class A
  {
  public:
      static void Init()
      {
          if(NULL == db)
          {
              leveldb::Options options;
              options.create_if_missing = true;
              options.max_open_files = 3000;
              leveldb::Status status = leveldb::DB::Open(options,"/disk1/leveldb/rand1y", &amp;db);
              assert(status.ok());
              cout &lt;&lt; status.ToString() &lt;&lt; endl;
          }
      }
      static  leveldb::DB* Get(){return db;}
  private:
          A(){}
          static leveldb::DB* db;
  };
  leveldb::DB* A::db = NULL;
  void* Get(void *arg)
  {
      string value("");
      int rnd = rand()%100000000;
      leveldb::Status status;
      string key("");
      char str[50];
      leveldb::DB* db = A::Get();
      stringstream ss;
      while(1)
      {
          rnd = rand()%100000000;
          sprintf(str, "test$%d-&gt;test$%d", rnd, rnd);
          key = str;
          status = db-&gt;Get(leveldb::ReadOptions(),key, &amp;value);
          if(status.IsNotFound())
              value = "NotFound!";
      }
      cout &lt;&lt; "Open end" &lt;&lt;endl;
  }
  int main(){
      A::Init();
      int err;
      for(int i = 0; i &lt; 20; ++i)
      {
          pthread_t p1;
          err = pthread_create(&amp;p1, NULL, Get, NULL);
          mthread.push_back(p1);
          if(0 != err)
              cout &lt;&lt; "error" &lt;&lt; endl;
      }
      FCGX_Init();
      for (int i = 0; i &lt; THREAD_COUNT; ++i)
      {
          pthread_create(&amp;id[i], NULL, doit, NULL);
      }
      for(int i = 0; i &lt; THREAD_COUNT; ++i)
      {
          pthread_join(id[i], NULL);
      }
      for(unsigned int i = 0; i &lt; mthread.size(); ++i)
      {
          pthread_join(mthread[i], NULL);
      }
      cout &lt;&lt; "end " &lt;&lt; endl;
      return 0;
  }
  </code></pre>