Posts Tagged ‘multithread’

A hack to strace -f

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: , ,

man 3 sleep

The 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: ,

&errno as thread identifier

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: ,

Acquire and Release Semantics

The 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 b before the increment of a.

[T]he InterlockedIncrementAcquire routine 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 a before the increments of b and c.

Likewise, the InterlockedIncrementRelease routine 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 a and b before the increment of c.

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: ,