title: Unknown cause of SIGSEGV in threaded C client-server chat application
body: <p>I'm a third-year college student in Software Engineering, taking an Operating Systems course.</p>
  
  <p>I've been working on a client-server chat application in C, using pthreads and sockets. I've been attempting to use pthreads to promote concurrency of client handling without the overhead of forking. (If it matters, I'm developing on Ubuntu 11.04 x86).</p>
  
  <p>Rather than storing everything as static or global/local variables, I've created two structured data types, <code>serverInfo_t</code> and <code>clientInfo_t</code>, which store a mutex, file descriptors, a connection flag, and other such information. The client list is implemented as a simple, singly-linked list stored in the <code>serverInfo_t</code>, which is locked and unlocked during modifications.</p>
  
  <p>When starting the server application, I first call <code>createServer()</code>, which establishes the server and, eventually, kicks off a child thread whose responsibility is to listen for new connections. This function returns a pointer to the newly-allocated <code>serverInfo_t</code> instance, which is then passed into a call to <code>createClient(serverInfo_t* pServer, int out_fd)</code> to make an "admin" client, allowing the server to be used as a client in itself. This is where I have a problem, as it seems to be producing a segfault as soon as it calls <code>createClient()</code>. (Some trimmed code of this is below:)</p>
  
  <pre><code>int main(int argc, char** argv)
  {
      // ...
      // Get listenPort from argv[1].
  
      // Initialize the server.
      serverInfo_t* pServer = createServer(listenPort);
  
      // If createServer() failed, exit.
      if (!pServer) {
          fatal_error("ERROR: Unable to create server!"); // exit program
      }
  
      // Create and register the admin client.
      clientInfo_t* pAdmin = createClient(pServer, STDOUT_FILENO); // Outputs directly to stdout
  
      // ...
  }
  </code></pre>
  
  <p>While debugging the program with gdb, I was walking through main() and noticed some interesting output:</p>
  
  <pre><code>(gdb) n
  22      serverInfo_t* pServer = createServer(listenPort);
  (gdb) n
  [New Thread 0xb7e53b70 (LWP 7986)]
  25      if (!pServer) {
  (gdb) n
  30      clientInfo_t* pAdmin = createClient(pServer, FD_STDOUT);
  (gdb) n
  server4: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *)
  &amp;((av)-&gt;bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) &amp;&amp;
  old_size == 0) || ((unsigned long) (old_size) &gt;= (unsigned long)((((__builtin_offsetof
  (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) &amp; ~((2 *
  (sizeof(size_t))) - 1))) &amp;&amp; ((old_top)-&gt;size &amp; 0x1) &amp;&amp; ((unsigned long)old_end &amp;
  pagemask) == 0)' failed.
  
  Program received signal SIGABRT, Aborted.
  0xb7fe1424 in __kernel_vsyscall ()
  (gdb) n
  Single stepping until exit from function __kernel_vsyscall,
  which has no line number information.
  [Thread 0xb7e53b70 (LWP 7986) exited]
  
  Program terminated with signal SIGABRT, Aborted.
  The program no longer exists.
  (gdb)
  </code></pre>
  
  <p>What is going on here? It looks to me as though the program skipped the call to createServer() entirely, even though the NULL-check passed. Did GDB refuse to step into the createServer() function, or was it simply bypassed due to some compiler optimization issue? If that's the case, then what's with the <code>[New Thread 0xb7e53b70 (LWP 7986)]</code> output? And what on earth is causing a failed assertion in <code>malloc.c</code>?</p>
  
  <p>I would appreciate any sort of assistance on this issue that you can provide. Please let me know if there is an issue with my methodology or with the information I've provided. I am willing to post my full Makefile and source code if necessary, though some modification (ie. changing the Makefile's $(OUTDIR) variable) is necessary to run the makefile.</p>
  
  <p><strong>EDIT:</strong> I think I've found the cause of the problem.</p>
  
  <p>In <code>createClient()</code>:</p>
  
  <pre><code>// ...
  clientInfo_t* client = (clientInfo_t*)malloc(sizeof(clientInfo_t*)); // Accidental typo.
  </code></pre>
  
  <p>Fixed:</p>
  
  <pre><code>// ...
  clientInfo_t* client = (clientInfo_t*)malloc(sizeof(clientInfo_t)); 
  </code></pre>
  
  <p>Yep, that fixed it. I apologize for the waste of time, but thank you for the assistance, everyone.</p>