Posts Tagged ‘multithread’
A hack to strace -f
By chys on March 25th, 2011
I have a multithreaded program which I would like to strace for debugging purpose. My program sometimes calls (fork and exec) an external program, which in turn calls a setuid program.
Because my program is multithreaded, I cannot omit the “-f” flag (also trace child threads and processes) when using strace. And because all children, including the setuid program, are traced, setuid fails. (Yes, I am aware that strace claims it is possible to trace setuid programs, but the trick does not work for me, probably because the setuid program is not directly executed by strace.)
Fortunately, the clone system call has many useful flags. It works fine for me when I substitute calls to fork() with:
(pid_t) syscall (__NR_clone, CLONE_UNTRACED|SIGCHLD, NULL);
(Yes, SIGCHLD, not CLONE_SIGCHLD. It’s not a typo.)
I guess there may be better solutions, without modifying the program being traced?
Tags: dev, Linux, multithread
man 3 sleep
By chys on October 17th, 2010The man page of sleep(3) used to say:
sleep() makes the calling process sleep until seconds seconds have elapsed or a signal arrives which is not ignored. [Old version; color added]
Now it says:
sleep() makes the calling thread sleep until seconds seconds have elapsed or a signal arrives which is not ignored. [New version]
Alas, they finally did the right thing – we have waited for at least 5 years. This change happened some time between versions 3.23 and 3.26.
There is indeed no reason to use “process” anymore, at least since the emergence of Linux 2.6 and NPTL. As far as I know, this very sentence has confused many newbie Linux programmers who are not familiar with the history of Linux multithreading, and has led some to firmly believe there is no “real” thread or threads are actually processes under Linux, a statement which was probably right for the obsolete implementation LinuxThreads, but definitely wrong today.
Tags: Linux, multithread
&errno as thread identifier
By chys on March 13th, 2010
Thread identifiers may have different types in different systems – pthread_t under POSIX; uintptr_t or HANDLE under Windows. They are usually integers or pointers, but POSIX actually allows structures though not usually found. This leads to a little difficulty in portability.
A trick, used by OpenSSL (if not overridden by calling CRYPTO_set_id_callback), is to use &errno as the thread identifier.
Per C standard, errno must be a modifiable lvalue, and thus we can safely take its address – &errno. And under any practically usable thread implementation, errno must be thread-local, which means &errno is different in different threads.
Note: It seems OpenSSL defaults to &errno only since 0.9.8m. Earlier versions always require the user to call CRYPTO_set_id_callback.
Tags: multithread, portability
Acquire and Release Semantics
By chys on March 2nd, 2010The concept of acquire and release semantics is important for multi-threaded programs that run on more than one physical core or processor. MSDN has a clear and concise explanation of then.
Consider the following code example:
a++;
b++;
c++;From another processor’s point of view, the preceding operations can appear to occur in any order. For example, the other processor might see the increment of
bbefore the increment ofa.…
[T]he
InterlockedIncrementAcquireroutine uses acquire semantics to increment a variable. If you rewrote the preceding code example as follows:
InterlockedIncrementAcquire(&a);
b++;
c++;other processors would always see the increment of
abefore the increments ofbandc.Likewise, the
InterlockedIncrementReleaseroutine uses release semantics to increment a variable. If you rewrote the code example once again, as follows:
a++;
b++;
InterlockedIncrementRelease(&c);other processors would always see the increments of
aandbbefore the increment ofc.
The operation of acquiring a lock must have acquire semantics; and the operation of releasing a lock must have release semantics. This is probably where they get their names.
Tags: dev, multithread
