Measuring Stack Usage for Linux Multi-Threaded App

Measure CPU usage of multithreaded program

The time(1) man page on my (Ubuntu) Linux system says:

   -f FORMAT, --format FORMAT
Use FORMAT as the format string that controls the output of
time. See the below more information.

:

FORMATTING THE OUTPUT
The format string FORMAT controls the contents of the time output. The
format string can be set using the `-f' or `--format', `-v' or `--ver‐
bose', or `-p' or `--portability' options. If they are not given, but
the TIME environment variable is set, its value is used as the format
string. Otherwise, a built-in default format is used. The default
format is:
%Uuser %Ssystem %Eelapsed %PCPU (%Xtext+%Ddata %Mmax)k
%Iinputs+%Ooutputs (%Fmajor+%Rminor)pagefaults %Wswaps

:

   The resource specifiers, which are a superset of  those  recognized  by
the tcsh(1) builtin `time' command, are:
% A literal `%'.
C Name and command line arguments of the command being
timed.
D Average size of the process's unshared data area, in
Kilobytes.
E Elapsed real (wall clock) time used by the process, in
[hours:]minutes:seconds.
F Number of major, or I/O-requiring, page faults that oc‐
curred while the process was running. These are faults
where the page has actually migrated out of primary memo‐
ry.
I Number of file system inputs by the process.
K Average total (data+stack+text) memory use of the
process, in Kilobytes.
M Maximum resident set size of the process during its life‐
time, in Kilobytes.
O Number of file system outputs by the process.
P Percentage of the CPU that this job got. This is just
user + system times divided by the total running time. It
also prints a percentage sign.
R Number of minor, or recoverable, page faults. These are
pages that are not valid (so they fault) but which have
not yet been claimed by other virtual pages. Thus the
data in the page is still valid but the system tables
must be updated.
S Total number of CPU-seconds used by the system on behalf
of the process (in kernel mode), in seconds.
U Total number of CPU-seconds that the process used direct‐
ly (in user mode), in seconds.
W Number of times the process was swapped out of main memo‐
ry.
X Average amount of shared text in the process, in Kilo‐
bytes.
Z System's page size, in bytes. This is a per-system con‐
stant, but varies between systems.
c Number of times the process was context-switched involun‐
tarily (because the time slice expired).
e Elapsed real (wall clock) time used by the process, in
seconds.
k Number of signals delivered to the process.
p Average unshared stack size of the process, in Kilobytes.
r Number of socket messages received by the process.
s Number of socket messages sent by the process.
t Average resident set size of the process, in Kilobytes.
w Number of times that the program was context-switched
voluntarily, for instance while waiting for an I/O opera‐
tion to complete.
x Exit status of the command.

So you can get CPU percentage as %P in the format.

Note that this is for the /usr/bin/time binary -- the shell time builtin is usually different (and less capable)

Determine stack usage of a posix pthread?

I have a multi-threaded program where one of the stacks is blowing up, but I can't figure out which one.

Let the program crash and leave a core file. Load that core into a debugger, and it will tell you right away which thread crashed.

The thread that crashed is not necessarily the one with the overflow.

It's true that there are scenarios where one thread overflows its stack, but another thread crashes because of it.

However, such scenarios are exceedingly rare (at least for non-user allocated thread stacks -- the pthread library will normally provide a stack guard page(s) to protect agains this). I can only think of one such scenario, and it's very unlikely in practice.

I'm looking for a portable approach using a pthreads call or something similar.

There is no portable way to achieve what you want. On Linux, you could use pthread_getattr_np and pthread_attr_getstack to find boundaries of the current thread stack, and easily compute current stack use from there.

Determine a thread's stack size and location

Here's a different method of doing this, involving reading /proc/self/maps. Unlike some of the other methods, it doesn't require special instrumentation at the start of your program and gives you an exact position for the end of the stack.

If you try cat /proc/self/maps, you get something like this:

00400000-0040c000 r-xp 00000000 08:01 6039736              /usr/bin/cat
0060b000-0060c000 r--p 0000b000 08:01 6039736 /usr/bin/cat
0060c000-0060d000 rw-p 0000c000 08:01 6039736 /usr/bin/cat
00908000-00929000 rw-p 00000000 00:00 0 [heap]
7fcdb1c68000-7fcdb1e01000 r-xp 00000000 08:01 6032628 /usr/lib/libc-2.21.so
7fcdb1e01000-7fcdb2000000 ---p 00199000 08:01 6032628 /usr/lib/libc-2.21.so
7fcdb2000000-7fcdb2004000 r--p 00198000 08:01 6032628 /usr/lib/libc-2.21.so
7fcdb2004000-7fcdb2006000 rw-p 0019c000 08:01 6032628 /usr/lib/libc-2.21.so
7fcdb2006000-7fcdb200a000 rw-p 00000000 00:00 0
7fcdb200a000-7fcdb202c000 r-xp 00000000 08:01 6032717 /usr/lib/ld-2.21.so
7fcdb21f5000-7fcdb21f8000 rw-p 00000000 00:00 0
7fcdb2209000-7fcdb222b000 rw-p 00000000 00:00 0
7fcdb222b000-7fcdb222c000 r--p 00021000 08:01 6032717 /usr/lib/ld-2.21.so
7fcdb222c000-7fcdb222d000 rw-p 00022000 08:01 6032717 /usr/lib/ld-2.21.so
7fcdb222d000-7fcdb222e000 rw-p 00000000 00:00 0
7ffe78c41000-7ffe78c62000 rw-p 00000000 00:00 0 [stack]
7ffe78dba000-7ffe78dbc000 r--p 00000000 00:00 0 [vvar]
7ffe78dbc000-7ffe78dbe000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

As you can see, there is a [stack] entry. This is probably what you're looking for.

An example program to parse this line out:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[]) {
FILE *file = fopen("/proc/self/maps", "r");
char line[1024];
void *result = NULL;
while (!feof(file)) {
if (fgets(line, sizeof(line) / sizeof(char), file) == NULL) {
break;
}
unsigned long start, end, offset;
unsigned int devma, devmi, ino;
char perms[6];
char path[128];
if (sscanf(line, "%lx-%lx %5s %lx %d:%d %d %127s", &start, &end, &perms, &offset, &devma, &devmi, &ino, &path) != 8) {
continue; // could not parse. fail gracefully and try again on the next line.
}
if (strcmp(path, "[stack]") == 0) { // use [stack:TID] for a thread besides the main thread
printf("Stack found from %lx to %lx\n", start, end);
break;
}
}
fclose(file);
return 0;
}

This will print something like:

Stack found from 7fff91834000 to 7fff91855000

This is probably fairly close to what you're looking for.

Can I measure the CPU usage in Linux by thread into application

While this is an old question it came up as the top related hit on my own Google search. So I'll provide the answer I came up with.

Assuming you're using pthreads or a library that uses it, such as Boost libraries.

You can use pthread_getcpuclockid and clock_gettime.

Man page links pthread_getcpuclockid, clock_gettime.

Here is a simple example that return the current time as a double.

double cpuNow( void ) {
struct timespec ts;
clockid_t cid;

pthread_getcpuclockid(pthread_self(), &cid);
clock_gettime(cid, &ts);
return ts.tv_sec + (((double)ts.tv_nsec)*0.000000001);
}


Related Topics



Leave a reply



Submit