What does mean Thread 0x7fffc57fa700 (LWP 31671) exited] in gdb? - c++

I develop and debug some program on Ubuntu 18.04 using C and C++.
At some point my multithreaded program crashes. In gdb I also see:
Thread 0x7fffc57fa700 (LWP 31671) exited]
What means 0x7fffc57fa700 and LWP 31671 ? I guess it is something like thread id. I need get it in C code. But when I tried std::this_thread::get_id() it returned int value, not 0x7fffc57fa700.

"LWP 31671" is the "Light Weight" process ID of the thread which ended. It inside the Linux kernel represents the thread. It's an implementation detail appearing on Linux, just ignore it.
"0x7fffc57fa700" is the hexadecimal representation of the thread's ID, namely what is return be the thread class' member function get_id() for C/C++ threads or pthread_self() for POSIX threads.

Address probably refers to either pthread_t (can be obtained with pthread_self) or to thread entry point, while LWP ( Light Weight Process) id can be obtained with syscall(SYS_gettid).
Note that the value returned by this_thread::get_id() is not necessary related to those system values, it is just an identifier with different values among all the thread objects representing a running thread that can be used to distinguish between threads.

Related

Can the same thread ID be reused within the same process?

I'm storing information per thread in a map (map's key is the thread ID).
However, I'm wondering if this is really a good idea. I see that every thread has a different ID, but does that really mean "every thread" or just "every live thread". I mean, within the same process, can a new thread use the same ID as an old thread that ended?
I experience that on Android, for two different threads, strangely syscall(__NR_gettid) are different while boost::this_thread::get_id() are identical. Is it a "bug", or is it just likely to occur.
The documentation for pthread (which both std::thread and boost::thread use) says,
Thread IDs are guaranteed to be unique only within a process. A thread ID may be reused after a terminated thread has been joined, or a detached thread has terminated.
http://man7.org/linux/man-pages/man3/pthread_self.3.html
So, yes, a new thread may reuse an ID from a dead thread inside the same process.
On Linux boost::this_thread::get_id returns the result of pthread_self():
Thread IDs are guaranteed to be unique only within a process. A thread ID may be reused after a terminated thread has been joined, or a detached thread has terminated.
The thread ID returned by pthread_self() is not the same thing as the kernel thread ID returned by a call to gettid(2).

gdb nostop SIGSEGV on a specific thread

I have a program that purposely segfaults on one threads, but I have a problem that the other thread is segfaulting, I'd like to catch it with GDB, I saw that I can:
handle SIGSEGV nostop noprint
but I'd like to do that only on the thread that purposely does that.. is it possible?
I'll explain:
I have 2 threads, one thread is segfaulting(and recovers(mprotect read only and then releasing memory)), that works fine, the other thread does something else, but sadly, there is a bug and it is segfaulting, I want to catch that segfault, and not the other ones that occur in the other thread.
As I know, depending on the OS, and I assume linux for my answer and the answer is 'NO'!
Posix exceptions can have a sigmask per thread but only one handler per task. So it is not possible to set different handling for each thread. sigaction will handle it for the complete process. So I see no way for gdb to change this.
I'll explain: I have 2 threads, one thread is segfaulting(and recovers(mprotect read only and then releasing memory)), that works fine, the other thread does something else, but sadly, there is a bug and it is segfaulting, I want to catch that segfault, and not the other ones that occur in the other thread
You have to tell gdb to ignore the first SIGSEGV signal. So after the first sagfault use the signal 0 command in this thread. Your program will resume execution under gdb and that is that you want. Then it will stop at the second segfault in your second thread and this is what you want to inspect.
(gdb) help signal
Continue program with the specified signal.
Usage: signal SIGNAL
The SIGNAL argument is processed the same as the handle command.
An argument of "0" means continue the program without sending it a signal.
This is useful in cases where the program stopped because of a signal,
and you want to resume the program while discarding the signal.
So
Do not use handle SIGSEGV nostop noprint. Run your program under
gdb.
When it segfaults in the first threead do signal 0. Your program
resumes execution.
Then it segfaults in another thread. Now use backtrace to see the
problem.
Or if your two thread are not dependent on each other you can wait in the thread that first segfaulted while another segfault happen. Just do call sleep(60) in the first thread as soon as it causes a segfault and wait for another segfault in another thread. Your first thread will wait:
Program received signal SIGFPE, Arithmetic exception.
[Switching to Thread 0x7ffff7fde700 (LWP 25744)]
0x000000000040075d in my_thread_func1 (arg=0x0) at my_test_2.cpp:17
17 ptr1 = ptr1 / 0;
(gdb) call sleep(60)
Thread 140737343510272:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff75dd700 (LWP 25745)]
0x00000000004007a3 in my_thread_func2 (arg=0x0) at my_test_2.cpp:27
27 *ptr2 = *ptr2 + 2;
The program received a signal in another thread while
making a function call from GDB.
Evaluation of the expression containing the function
(sleep) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb)

Check if current thread is main thread

How can i check if the current thread is the main thread on linux? It looks like gettid() only returns an pid but it seems that linux does not guarantee the thread with main() always has a const and uniform pid.
The reason for this is that I have an automatic parallelization going on and I want to make sure pthread_create() is not called in a function that is already running on a thread that's created by pthread_create().
For Linux:
If getpid() returns the same result as gettid() it's the main thread.
int i_am_the_main_thread(void)
{
return getpid() == gettid();
}
From man gettid:
gettid() returns the caller's thread ID (TID). In a single-threaded process, the thread ID is equal to the process ID (PID, as returned by getpid(2)). In a multithreaded process, all threads have the same PID, but each one
has a unique TID.
From man clone:
Thread groups were a feature added in Linux 2.4 to support the
POSIX threads notion of a set of threads that share a single
PID. Internally, this shared PID is the so-called thread
group identifier (TGID) for the thread group. Since Linux
2.4, calls to getpid(2) return the TGID of the caller.
The threads within a group can be distinguished by their
(system-wide) unique thread IDs (TID). A new thread's TID is
available as the function result returned to the caller of
clone(), and a thread can obtain its own TID using gettid(2).
What about using pthread_self()?.
This returns the thread_id of the calling thread. With this function, you can store the main thread id (when you know is main) and compare it later with other values returned from pthread_self() to identify if they are the main thread or another one.
Although I think is wiser to have well structured code. Something like functions to be executed in slave threads and other functions to be executed in the master thread. This is a better approach to this kind of problems.

Is it possible from within a thread in C/C++ to get a parent thread id if it wasn't passed in as an argument on pthread_create?

pthread_self() is to get your own thread id. It doesn't seem like you can get the thread id of the thread which spawned you unless it was given to you during spawning. Or is there a way?
No, all threads are equal in POSIX threads, there is no hierarchy. Even the thread that executes main has no special role and can be terminated without effecting the others.

Keep track of pthread

I put up many threads running. At a later time, I'd like to check if these threads are still alive (i.e., not finished yet and not terminated unexpectedly).
What kind of information should I keep track of regarding the threads in the first place. Thread ID, process ID, etc? How should I get these IDs?
When I need to check the liveness of these threads, what functions should I use? Will pthread_kill work here? pthread_kill takes an opaque type pthread_t as parameter, which I believe is typically an unsigned long. Is pthread_t different from a thread ID? I assume a thread ID would pick up an int as its value. In some tutorials on pthread, they assign an integer to a pthread as its ID. Shouldn't the thread get its ID from the operating system?
A thread's entire identity resides in pthread_t
Initializing a thread returns its pthread_t typed ID to its parent
Each thread can get it's own ID with pthread_self()
You can compare thread IDs using the function:int pthread_equal (pthread_t, pthread_t)
So: Maintain a common data structure where you can store thread status as STARTED, RUNNING, FINISHED using the pthread_t IDs and pthread_equal comparison function to differentiate between the threads. The parent sets the value to STARTED when it starts the thread, the thread itself sets its own state to RUNNING, does its work, and sets itself to FINISHED when done. Use a mutex to make sure values are not changed while being read.
EDIT:
You can set up a sort of 'thread destructor' using pthread_cleanup_push:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cleanup_pop.html
i.e. register a routine to be called when the thread exits (either itself, or by cancellation externally). This routine can update the status.
When you call pthread_create, the first argument is a pointer to a pthread_t, to which pthread_create will assign the thread ID of the newly created thread. If you want to get the thread ID of the current thread, use pthread_self(). This is the only identifying piece of information you need for the thread because all threads created this way share the same process ID.
The way you would check whether a thread is alive depends on what you need this information for. If you just want to wait until the thread has completed, you call pthread_join with the thread ID as the first argument and a pointer to a location for the return value of the thread function as the second argument. Unless you detach the threads you create by calling pthread_detach(pthread_self()) in the thread, you need to call pthread_join on them eventually so that they don't continue to hold on to their stack space.
If for some reason you want to do something while the thread is running, you could create a global variable for each thread that that thread changes when it terminates, and check that variable with the main thread. In that case, you would probably want to detach the threads so that you don't also have to join them later.