2

I am learning pthread, the following is my simple code:

  1 #include <pthread.h>
  2 #include <cstdlib>
  3 #include <iostream>
  4 #include <string>
  5 #include <sstream>
  6
  7 using namespace std;
  8
  9 struct ThreadParam
 10 {
 11     int thread_id;
 12     string message;
 13 };
 14
 15 string int2string(int i)
 16 {
 17     stringstream s;
 18     s << i;
 19     return s.str();
 20 }
 21
 22 void * Hello(void * param)
 23 {
 24     ThreadParam * threadParam = (ThreadParam*)param;
 25
 26     int tid = threadParam->thread_id;
 27     string msg = threadParam->message;
 28     string output = msg + " In thread " + int2string(tid);
 29
 30     cout << output << endl;
 31     pthread_exit(NULL);
 32 }
 33
 34 int main()
 35 {
 36     const int count = 30;
 37     ThreadParam params[count];
 38
 39     pthread_t threads[count];
 40     int rc;
 41     for(int t=0; t < count; t++)
 42     {
 43         cout << "In main: creating thread " << t << endl;
 44
 45         params[t].thread_id = t;
 46         params[t].message = "Hello " + int2string(t) + "!";
 47
 48         rc = pthread_create(&threads[t], NULL, Hello, (void*)&params[t]);
 49
 50         if(rc)
 51         {
 52             cout << "Error! Return code is " << rc << endl << flush;
 53             exit(-1);
 54         }
 55     }
 56     pthread_exit(NULL);
 57 }

I got segmentation fault after creating the last thread. The output is:

In main: creating thread 0
In main: creating thread 1
In main: creating thread 2
In main: creating thread 3
In main: creating thread 4
In main: creating thread 5
In main: creating thread 6
In main: creating thread 7
In main: creating thread 8
In main: creating thread 9
In main: creating thread 10
In main: creating thread 11
Hello 0! In thread 0
Hello 1! In thread 1
Hello 2! In thread 2
Hello 3! In thread 3
Hello 4! In thread 4
In main: creating thread 12
In main: creating thread 13
In main: creating thread 14
In main: creating thread 15
In main: creating thread 16
In main: creating thread 17
In main: creating thread 18
In main: creating thread 19
In main: creating thread 20
In main: creating thread 21
In main: creating thread 22
In main: creating thread 23
In main: creating thread 24
In main: creating thread 25
In main: creating thread 26
In main: creating thread 27
In main: creating thread 28
In main: creating thread 29
Segmentation fault

I cannot figure out why, any clue?

wallyk
  • 56,922
  • 16
  • 83
  • 148
Ryan
  • 1,963
  • 3
  • 25
  • 35
  • 3
    Did you try calling `pthread_join` ? – cnicutar Sep 13 '12 at 20:51
  • Did you use gdb to debug your problem and see where you get a seg fault and why? We can't help you until you do thart. – bmargulies Sep 13 '12 at 20:53
  • According to http://stackoverflow.com/questions/3559463/is-it-ok-to-call-pthread-exit-from-main `pthread_exit` in main should make it unnecessary to join threads. So I wonder if `cout << output` is thread unsafe and can cause problems: http://stackoverflow.com/questions/6374264/is-cout-synchronized-thread-safe – Serge Balyuk Sep 13 '12 at 21:00

3 Answers3

3

Looking at your code I can tell that after you create the last thread you destroy the main one (the "creator" thread). This leads to the stack of that thread to be freed. But because you use pointers to the main thread stack memory (ThreadParam params[count]; to be precise; you pass pointers to it to pthread_create function) you then try to read the invalid data in other threads. The memory pages allocated for the main thread stack were marked as "unused" or "unallocated" after the destruction of the main thread so you get the segfault while trying to access them.

UPD: As others said, you should use pthread_join function to wait for all threads to finish and then destroy the main thread.

UnknownGosu
  • 854
  • 6
  • 9
  • +1 for `ThreadParam params[count]` being destroyed before a thread accesses its `param` – Serge Balyuk Sep 13 '12 at 21:05
  • Oh I see. I made a silly error. The example code I read make that array a global one. I do not like global variables and declared it in the main and lead to this error. – Ryan Sep 13 '12 at 21:25
2

You have to wait for threads to finish before exiting the program. If you don't — a lot of bad things could happen. To join a thread, use pthread_join(). You may also run into "detached" threads in API documentation — don't bother trying to use it, it does not work, at least not in Linux.

Other that that — debugger is the best candidate to tell why your process is segfaulting, could be a lot of reasons and guessing does not help on this front.

  • The problem with debugging and multiple threads is that due to the different timings many problems in the productive code don't appear while debugging. – phlogratos Sep 13 '12 at 20:59
  • @phlogratos: for that reason there are core dumps. Enable optimization, leave debug symbols, crash the process, then run a debugger with a core. –  Sep 13 '12 at 21:11
2

Your main thread should wait till your secondary threads finish execution. This is leading to a seg fault.

Main thread should join on the other threads.

Jay D
  • 3,263
  • 4
  • 32
  • 48