How to use strace

strace is a tool that shows you the system calls and signals called by a program. It is a very useful tool, especially to check what files and libraries are opened, read or written by a program.

  • Installing strace is easy:
$ sudo apt install strace
  • To view the system calls made by the execution of a program named foobar:
$ strace ./foobar

You will see that strace prints out every system call made by the program, with its input arguments and its output. However, since this verbose listing is printed to the console, you will find it difficult to view the actual output of the program or to interact with it.

  • Usually, strace is asked to write its output to a log file:
$ strace -o strace.log ./foobar
  • Anything but the simplest program will usually fork itself into child processes. By default, strace only traces the parent process launched initially. To request it to trace all child processes, use the -f option:
$ strace -f -o strace.log ./foobar
  • To trace only a few specific system calls, say open and close:
$ strace -e trace=open -o strace.log ./foobar
$ strace -e trace=open,close -o strace.log ./foobar
  • To trace only system calls from a specific category, say those calls that take filename as argument:
$ strace -e trace=file -o strace.log ./foobar

The other categories include process, network, signal, ipc, desc and memory. See the strace manpage for more details on these categories.

  • To trace only specific signals:
$ strace -e signal=sigkill,sigint -o strace.log ./foobar

The full list of signals can be seen in man 7 signal.

  • A very useful option is to trace calls that access a particular path. This can be done using the -P option:
$ strace -P /home/joe/somefile -o strace.log ./foobar

Note that strace is clever enough to show all calls related to the file descriptor produced by the particular path too.

  • By default, the input argument structures to the calls are abbreviated. To view the full structures, use the verbose option:
$ strace -v -o strace.log ./foobar
  • By default, all strings that are read or written are displayed, but only the first 32 characters. To view more of the strings, specify how many characters you want to see to the -s option:
$ strace -s 100 -o strace.log ./foobar
  • Another formatting option that I find useful is to align the output values of all calls to a particular column, say 100:
$ strace -a 100 -o strace.log ./foobar
  • Looking at file descriptors in strace output can be confusing. To ask strace to show the path associated with each file descriptor whenever it prints a file descriptor, use the -y option:
$ strace -y -o strace.log ./foobar

Tried with: strace 4.11 and Ubuntu 16.04

Advertisements

Signify plugin for Vim

If you use version control systems like Git or Mercurial and you use Vim to edit your source files, then you might find the Signify plugin very useful. When you edit a version controlled file, Signify shows which lines are changed using signs (or markers) in the gutter on the left side.

  • Signify can be installed using your favorite plugin manager from: https://github.com/mhinz/vim-signify

  • By default, Signify works with a large number of version controls systems. If you only use one or a few of those, then you can speed up Signify a bit by informing it to only check those VCS. For example, I only use Git and Mercurial, so I add this line to my vimrc:

let g:signify_vcs_list = [ 'git', 'hg' ]
  • You can also override the default marker characters it uses for its signs. For example, to change its delete character:
let g:signify_sign_delete = "-"

Tried with: Vim 7.4 and Ubuntu 16.04

How to create weekly view board in JIRA

JIRA is an issue tracking tool that is popular with software developers. It allows you to create boards with swimlanes, each of which represents the different status of your issues.

For my boards, I find it useful to get a weekly view of my issues. In particular, I like to see the issues that were due last week, are due this week and next week.

Doing that is easy in JIRA. Just add three filters with these filter definitions to any board that you are using:

How to install and use GLog

GLog is the logging library from Google for C++. It makes it real easy for you to add logging to any C++ application.

  • Install: Installing GLog header files and library files is easy:
$ sudo apt install libgoogle-glog-dev
  • Header file: The header file to include in your source file is glog/logging.h

  • Initialization: You will need to call google::InitGoogleLogging method with the name of your program as the input parameter to start logging.

  • Levels: There are 4 levels for logging messages in increasing order of severity: INFO, WARNING, ERROR and FATAL. These severity levels have values 0, 1, 2 and 3 respectively.

  • Log function: To log a message, use the LOG macro, similar to how you use cout. For example, this example shows logging messages of different severity:

#include <glog/logging.h>

int main(int argc, char* argv[])
{
    google::InitGoogleLogging(argv[0]);

    LOG(INFO) << "This is an info  message";
    LOG(WARNING) << "This is a warning message";
    LOG(ERROR) << "This is an error message";
    LOG(FATAL) << "This is a fatal message";

    return 0;
}
  • Library: To compile a source file using GLog, you will need to link using -lglog.

  • Log files: By default, when you run your program, 3 new log files will be created in /tmp directory. The filenames are of this format:

foobar.home-machine.ashwin.log.ERROR.20171026-220607.21911
foobar.home-machine.ashwin.log.INFO.20171026-220607.21911
foobar.home-machine.ashwin.log.WARNING.20171026-220607.21911

Format:
program_name.hostname.user_name.log.level.date.time.pid

The file with INFO in its name has log messages of levels INFO and above. The file with WARNING int its name has log messages of levels WARNING and above. Similarly, for the file with ERROR in its name.

In addition, 3 symbolic links are created in the same logging directory pointing to the latest log files. These 3 filenames are of the format:

foobar.ERROR
foobar.INFO
foobar.WARNING
  • Log to display: By default, when you run your program, you will see log messages of ERROR and FATAL on the stderr, so they will appear on the console. Note that the first FATAL message will prompt the killing of your program.

  • If you want the program to log to stderr instead of writing to log files, set this environment variable GLOG_logtostderr=1

  • If you want to change the logging directory from /tmp to some other location, set this environment variable GLOG_log_dir=/some/path

Reference: GLog documentation

Clock skew detected during make

Problem

I was trying to build source files on a remote server using make. The make command would sometimes throw up a clock skew warning like this:

make[2]: Warning: File `foobar.cpp' has modification time 36 s in the future
make[2]: warning:  Clock skew detected.  Your build may be incomplete

Solution

It turns out that these source files were actually shared from another computer to this remote server using NFS. Using the date command at the local computer and the remote server, I found that there was a difference of a few seconds between the two.

More investigation showed that only the local computer was using NTP and so its time was correct. The remote server was not using NTP and so its time was wrong.

To install and enable NTP on the remote server, I used these commands:

$ sudo apt install ntp
$ sudo service ntp reload

Note that it takes a few minutes for the synchronized correct time to show up on the computer after these commands. After the sync, I no longer get the clock skew warnings from make.

Reference: Time Synchronisation with NTP

Tried with: Ubuntu 16.04

How to add NoScrollBar to LightLine

LightLine is a lightweight statusline plugin for Vim. By default, it shows the location of current line relative to the entire file as a percent at the left of the statusbar.

However, I like to the NoScrollBar plugin to get a general sense of the current line in the file. So, I replaced the percent display with the output of NoScrollBar using a tiny function.

I added these lines in Vim to achieve this:

" Replace percent component of Lightline statusline
let g:lightline = {
      \ 'component_function': {
      \   'percent': 'NoScrollbarForLightline'
      \ }
      \ }

" Instead of % show NoScrollbar horizontal scrollbar
function! NoScrollbarForLightline()
    return noscrollbar#statusline()
endfunction

Tried with: Vim 7.4 and Ubuntu 16.04

How to show full file path in LightLine

LightLine is a lightweight statusline plugin for Vim. By default, it shows only the filename on the left side of the statusbar. I like to have the full file path displayed instead. It turns out that is easy to do.

The statusline has many components, and the component that shows the filename is called filename. We override this in LightLine with a tiny function that uses the expand function in Vim to get the full file path.

I added these lines in Vim to achieve this:

" Replace filename component of Lightline statusline
let g:lightline = {
      \ 'component_function': {
      \   'filename': 'FilenameForLightline'
      \ }
      \ }

" Show full path of filename
function! FilenameForLightline()
    return expand('%')
endfunction

Tried with: Vim 7.4 and Ubuntu 16.04

How to install X client on server

Many people prefer to install Ubuntu Server instead of Ubuntu Desktop on servers. The Server variant does not come with any X11 client or server by default. So, if you SSH to the server (with X11 forwarding) and run any X or GUI application, it cannot show a window on your local computer.

What is needed to run X11 or GUI apps on the server through SSH is an X11 client. Installing that is easy:

$ sudo apt install xauth

Reference: ServerGUI

Tried with: Ubuntu 16.04

How to install and use FZF

FZF is a fuzzy finder that can be used to autocomplete and find stuff at the shell. It has a beautiful ncurses interface, sensible keybindings and is blazing fast. It truly supercharges your shell use and you will not be able to live without it after.

  • To install FZF and install its hooks into Bash, Zsh and Fish shells:
$ git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
$ ~/.fzf/install
  • Find files and directories: At the shell prompt, press Ctrl+T and FZF scans the files and directories inside your current directory and starts filling up its list. Type a few characters of the file or directory you want to autocomplete. The characters do not need to be an exact substring. That is the fuzzy feature of this finder. Use up and down keys to navigate the list. You can even use the mouse to pick items from the list by clicking and Ctrl-clicking. Finally press Enter to pick the entry you want. Press Esc to dismiss FZF any point.

  • Find directories: At the shell prompt, press Alt+C to autocomplete and find only directories. The rest of the interaction is same as that for Ctrl+T shown above.

  • Find from history: Ctrl+R does the fuzzy finding for commands from your shell history. This works in Bash, but seems to be disabled in Fish. No worries cause Fish already has powerful history search.

  • Find process to kill: Figuring out the PID of a process you want to kill is painful. With FZF, all you need to do is type kill, press TAB and you get a list of processes with full details. You can type some characters to find the process you want or scroll the list. For each item, it also shows the full command line at the bottom, enabling you choose the right program to kill. Press Enter to choose the process. Its PID will be added to your kill command.

Tried with: FZF 0.17.1 and Ubuntu 16.04

add-apt-repository command not found

Problem

I was trying to add an PPA repository and got this error on a server:

$ sudo add-apt-repository ppa:blah/foobar
sudo: add-apt-repository: command not found

Solution

The add-apt-repository comes from the software-properties-common package. Installing it solved the problem:

$ sudo apt install software-properties-common

Tried with: Ubuntu 16.04