Skip to content

Entries from February 2011.

Process list with hierarhy: ps re-discovered

Want to easily track list of processes with hierarchy on your linux box? Nothing easiest unless you don't know about few very useful "ps" command line switches. Here they are:

  • "x": show also processes without TTY attached (running in background)
  • "f": ascii-art process hierarchy

And a sample from my box that builds some interesting (at least for me) stuff (lines shortened slightly):

$ ps xf
  PID TTY      STAT   TIME COMMAND
21618 ?        S      0:00 su - dccb
21621 ?        S      0:00  \_ -su
 4460 ?        R+     0:00      \_ ps xf
28962 ?        S      0:00 sh daemon-dev.sh
28963 ?        S      0:00  \_ sh ../utils/create_mw_ui_rootfs_drop.sh full daemon-dev.sh
 7465 ?        S      0:00      \_ make
28756 ?        S      0:00          \_ /bin/sh -c cd src/libs/dtvservice/ && make -f Makefile
28757 ?        S      0:00              \_ make -f Makefile
 3895 ?        S      0:00                  \_ sh4-oe-linux-g++ -c -pipe -isystem /usr/local/dcc-0.9/sh4/v
 3896 ?        R      0:00                      \_ /usr/local/dcc-0.9/sh4/vip1960/bin/../libexec/gcc/sh4-o
 3920 ?        S      0:00                      \_ /usr/local/dcc-0.9/sh4/vip1960/bin/../lib/gcc/sh4-oe-li
17341 ?        S      0:00 sh daemon-RELEASE_0.9_branch.sh
16644 ?        S      0:00  \_ sleep 5m
15554 ?        S      0:00 sh daemon-RELEASE_0.10_branch.sh
16743 ?        S      0:00  \_ sleep 5m
13448 ?        S      0:00 sh daemon-master.sh
31613 ?        S      0:00  \_ sh ../build.sh full daemon-master.sh ns4012uc
  411 ?        S      0:00      \_ make
  637 ?        S      0:00          \_ /bin/sh -c . /usr/local/dcc/mipsel/ns4012uc/env.sh; make -C api all
  638 ?        S      0:00              \_ make -C api all
 2839 ?        S      0:00                  \_ make -C src/hal
 7442 ?        S      0:00                      \_ make -C hal
 4159 ?        S      0:00                          \_ mipsel-oe-linux-uclibc-g++ -MMD -fPIC -DPIC -isyste
 4162 ?        R      0:00                              \_ /opt/toolchains/crosstools_hf-linux-2.6.18.0_gc
 4165 ?        S      0:00                              \_ /opt/toolchains/crosstools_hf-linux-2.6.18.0_gc
 5414 ?        S      0:00 sh daemon-int-0.11.sh
 8067 ?        S      0:00  \_ sh ../utils/create_mw_ui_rootfs_drop.sh full daemon-int-0.11.sh /home/dccb/
21950 ?        S      0:00      \_ make
 1309 ?        S      0:00          \_ /bin/sh -c cd CoreApplications/ && make -f Makefile
 1310 ?        S      0:00              \_ make -f Makefile
 4396 ?        S      0:00                  \_ /bin/sh -c cd PVRPlayback/ && make -f Makefile
 4433 ?        S      0:00                      \_ make -f Makefile

Profiling C++ apps with oprofile

If you are hitting some performance problems (related to CPU) there is very powerfull tool that can help you with diagnostics: oprofile. Below I'm summarizing some hints for efficient oprofile usage (not all are very obvious). First of all: some basic commands:

  • opcontrol: starts/stops statistics collection
  • opreport: reporting tool

For applications that use shared libraries you have to add "--separate=lib" switch to opcontrol call:

opcontrol --start --separate=lib --vmlinux /boot/vmlinux
opcontrol --stop

Without this option you will see only main binary activities (without time spent in shared libraries).

Looking at raw opreports is not very useful. Sometimes "light" method will call another "heavy" method and you won't be able to locate the caller from report (very lov CPU usage). But sometimes caller should be located and modified to fix the performance problem. That's why "call graphs" were added for oprofile. In order to report using current stack contents you have to initialize oprofile properly:

opcontrol --start --callgraph=10 --vmlinux /boot/vmlinux
opcontrol --stop

Then besides raw data you can see code locations found on stack (callers and code called from function that eats most CPU):

  9        16.0714  libCommonWidgets.so.1.0.0 widgets::ActionItemWidget::isFocused() const
  11       19.6429  CoreApplication          _fini
  24       42.8571  libCommonWidgets.so.1.0.0 QPainter::drawPixmap(int, int, QPixmap const&)
4413     13.6452 libQtGuiE.so.4.7.1       /usr/lib/libQtGuiE.so.4.7.1
  4413     100.000 libQtGuiE.so.4.7.1       /usr/lib/libQtGuiE.so.4.7.1 [self]

As you can see there's one non-indented line. This is our CPU-heavy method. We also see callers (with percentage assigned - oprofile is a statistic profiler). We can guess probably drawPixmap() should be optimised here.

If you are tracking embedded systems you can perform reporting on host machine. Architecture can be totally different, but oprofile versions must match (there might be differences in internal oprofile format). I'm running reports by the following command:

opreport --image-path=/usr/local/sh4/some-arch/rootfs \
    --session-dir=/usr/local/sh4/some-arch/rootfs/var/lib/oprofile

As you can see you have to point to binaries location and /var/lib/oprofile (both are on rootfs mounted by NFS in my case). Using host for reports is much faster (and you have no problems with limited embedded device memory).

Linux command line most useful keyboard shortcuts

I don't like when computer limits my performance. When some "manual" process is slower that my thinking process it's a very frustrating situation. That's why I love command line and keyboard shortcuts (versus GUI and mouse based interfaces).

Under Linux we have readline library that implements command line editing with history and many other useful features.

First: allow to effectively search history by prefix (just enter some text and pressing UP/DOWN keys to select commands starting with that string):

~/.inputrc
"\e[A":history-search-backward
"\e[B":history-search-forward

Then some shortcuts that may be useful (I assume you have at least cursor keys on your terminal, so filtering them out from full list):

  • Moving around
    • CTRL+a: beginning of line
    • CTRL+b: end of line
    • ALT+b: one word left
    • ALT+f: one word right
  • Copy/Paste
    • CTRL+k: cut to end of line
    • CTRL+u: cut to beginning of line
    • CTRL+w: delete word
    • CTRL+y: paste at cursor position ("yank" in Emacs terminology)
  • Completion
    • TAB: complete current text (bash uses filesystem contents here)

Easy IPhone MP4 converter on Ubuntu

Sometimes I would like to watch my favourite movies on my cell phone during a trip (I recommend this movie for beginners). Some phones, however, will not allow you to watch flv directly (video format supported by youtube Flash player). Also you will have problems with directly rendering Xvid/DivX format. A conversion is needed.

I'm using simple script that checks for new files in one directory, converts to suitable format and moves the file to another directory. The process is fully automated and starts on system shutdown (conversion will take some time). Any errors during conversion will be reported by e-mail using local delivery (Postfix, BTW).

#!/bin/sh
SRC=$1
DST=$2
for a in $SRC/*
do
    if ! test -f "$a"
    then
        exit 0
    fi
    base=`basename "$a"`
    out="$DST/$base.mp4"
    if test -f "$out"
    then
        continue
    fi
    echo "Processing $a -> $out"
    if nice ffmpeg -threads 2 -i "$a" -f mp4 -vcodec mpeg4 -b 250000 \
        -r 15 -s 320x200 -acodec libfaac -ar 24000 -ab 64000 -ac 2 "$out" \
        2> /tmp/stderr.txt
    then
        rm "$a"
    else
        rm "$out"
        cat /tmp/stderr.txt | mail $LOGNAME -s "Conversion of $a failed"
    fi
done

Additionally you have to install some packages in your OS:

# apt-get install ffmpeg