Wednesday, October 7, 2015

Determine kernel version of the Linux kernel just built


You just successfully built Linux kernel (but have not installed yet) and wish to find out (and may be want to use) the version number of the newly generated kernel, then running following command in the kernel source root directory:
make kernelversion
will print something like:
4.3.0-rc4

However, this is not the complete version if you have enabled CONFIG_LOCALVERSION_AUTO in the your configuration (.config)

After some search within the kernel tree, complete kernel version was found placed in the file utsrelease.h (by the build process). Further research suggested that the location of the file utsrelease.h has moved within the kernel source tree since some year around 2011. So here is a series of chain command, keeping that in mind, that would output the complete Linux kernel version (and just that) that you could use:

$ grep UTS_RELEASE $(find -name utsrelease.h) | cut -d \" -f 2
4.3.0-rc4-12566-gf670268

 I found this useful to make a copy of .config of the just built kernel in the /boot directory, like so:
$ export newkernelver=$(grep UTS_RELEASE $(find -name utsrelease.h) | cut -d \" -f 2)
$ echo $newkernelver
4.3.0-rc4-12566-gf670268
$ sudo cp .config /boot/config-$newkernelver
$ ls /boot/config-4.3*
/boot/config-4.3.0-rc4-12566-gf670268

Do leave me a comment, if you know a better way to do the same.

UPDATE:
Found discussed elsewhere that following command gives out the complete kernel version too:
$ file arch/x86/boot/bzImage
arch/x86/boot/bzImage: Linux kernel x86 boot executable bzImage, version 4.3.0-rc4-12566-gf670268 (someuser@somehost) #3 S, RO-rootFS, swap_dev 0x5, Normal VGA

Following chain command will extract just the version part that could be used elsewhere:
$ file arch/x86/boot/bzImage | awk -F "version " '{print $2}' | cut -d \  -f 1
4.3.0-rc4-12566-gf670268
Any better solutions ? Leave me a comment.

Listing 'make targets' related to Linux Kernel

The README file in the root of linux kernel source tree lists and explains only most commonly used 'make targets' supported by the kernel Makefile, but does not list them all.

So after playing a little with grep I concluded following would be useful for listing all possible 'make targets' (ignoring some false positives) in the Linux kernel Makefile.

grep  ^.*: Makefile | grep -v = | grep  -v ^#
Snipped output:
help:
prepare: ;
scripts: ;
clean: $(clean-dirs)
tags TAGS cscope gtags: FORCE
includecheck:
versioncheck:
coccicheck:
namespacecheck:
export_report:
checkstack:
kernelrelease:
kernelversion:
image_name:
Note: I have a feeling that better solution(s) than this exists to list the same, so please leave in comments.

Thursday, September 3, 2015

valgrind: failed to start tool 'memcheck' for platform 'x86-linux'
There comes a time in life of a developer when one gets this error
valgrind: failed to start tool 'memcheck' for platform 'x86-linux'


I do not see myself as an expert Valgrind user, but I understand output of Valgrind enough to catch memory leaks in my C programs.

The other day I launched a personal project in assembly language and used standard C memory routines (calloc, realloc, free) for its
memory requirements. The program grew complex  and I wanted to be sure I am not leaking any memory (and also to be sure I am
leaking memory where I know I am leaking at that stage - amid development), and was also driven by the curiosity to see how well
Valgrind handled a program written in Assembly. After all, I have had never used Valgrind before for program written in any language
other than C.

So I launched Valgrind like so, and got that error - completely unexpected:
$
$ valgrind ./atail32_80 test.txt
valgrind: failed to start tool 'memcheck' for platform 'x86-linux': No such file or directory
$
Thought never crossed my mind that the error was due to Assembly language front-end - and I was on the right track with that!

I hypothesized that the error was due to the fact that the program being debugged was a 32-bit program* on a 64-bit platform
(see below).
$
$ uname -i
x86_64

$ file ./atail32_80
./atail32_80: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xf3e3af4712a9382cb2b793f580a26a6797d64d1f, not stripped
$
*I was building that program as a 32-bit executable on purpose (further discussion about that would be irrelevant to this post).

I launched an investigation console and performed this small experiment to confirm my hypothesis.
$ echo "void main(){}" > testme.c
$
$ gcc  -m32  -o testme32  testme.c
$
$ gcc  -m64  -o testme64  testme.c
$
$ file testme32
testme32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x305f621662204c0289ee57e927c0221af84e4597, not stripped
$
$ file testme64
testme64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x285da18d5e71346dfd958b260fccfe3717cd2b99, not stripped
$
$ valgrind ./testme64
==28701== Memcheck, a memory error detector
==28701== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==28701== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==28701== Command: ./testme64
==28701==
==28701==
==28701== HEAP SUMMARY:
==28701==     in use at exit: 0 bytes in 0 blocks
==28701==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==28701==
==28701== All heap blocks were freed -- no leaks are possible
==28701==
==28701== For counts of detected and suppressed errors, rerun with: -v
==28701== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
$
$ valgrind ./testme32
valgrind: failed to start tool 'memcheck' for platform 'x86-linux': No such file or directory
The same error message on the last line above confirmed the cause of the error; but what was happening really ?

Knowing some tools helps; strace seemed liked the right one at this moment.
$
$ strace  -e trace=file valgrind  ./testme32
execve("/usr/bin/valgrind", ["valgrind", "./testme32"], [/* 67 vars */]) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("./testme32", O_RDONLY)            = 3
readlink("/proc/self/exe", "/usr/bin/valgrind", 4096) = 17
execve("/usr/lib64/valgrind/memcheck-x86-linux", ["valgrind", "./testme32"], [/* 68 vars */]) = -1 ENOENT (No such file or directory)
valgrind: failed to start tool 'memcheck' for platform 'x86-linux': No such file or directory
+++ exited with 1 +++

$
The execve() line just above the error message, that is now familiar to us, gives it away. Valgrind is trying to launch
/usr/lib64/valgrind/memcheck-x86-linux which seems to be missing.

Let us confirm:
$
$ ls /usr/lib64/valgrind/memcheck*
/usr/lib64/valgrind/memcheck-amd64-linux  /usr/lib64/valgrind/memcheck-x86-linux
$
It is there ! But the file IS there - and at the very location expected by Valgrind ! Then why the failure ?

Wait, before concluding, recall that on *nix, we have all learned either the hard or the soft way, "When in doubt, think symbolic link".
On those lines:
$
$ cd /usr/lib64/valgrind/
$
$ pwd
/usr/lib64/valgrind
$
$ ls -l memcheck*
-rwxr-xr-x. 1 root root 3449056 Apr 25  2013 memcheck-amd64-linux
lrwxrwxrwx. 1 root root      37 Jun 10 04:42 memcheck-x86-linux -> ../../lib/valgrind/memcheck-x86-linux
$
$ ls -l ../../lib/valgrind/memcheck-x86-linux
ls: cannot access ../../lib/valgrind/memcheck-x86-linux: No such file or directory
$
So, memcheck-86-linux is indeed a symbolic link, and the target of which is missing.

Looking further, we can confirm that symbolic link /usr/lib64/valgrind/memcheck-x86-linux is created by/belongs to Valgrind package.
No surprises there!

$
$ yum provides /usr/lib64/valgrind/memcheck-x86-linux
Loaded plugins: langpacks, refresh-packagekit
google-chrome/filelists                                                                                         | 1.8 kB  00:00:00    
1:valgrind-3.8.1-15.fc19.x86_64 : Tool for finding memory management bugs in programs
Repo        : fedora
Matched from:
Filename    : /usr/lib64/valgrind/memcheck-x86-linux

1:valgrind-3.8.1-15.fc19.x86_64 : Tool for finding memory management bugs in programs
Repo        : installed
Matched from:
Filename    : /usr/lib64/valgrind/memcheck-x86-linux
$



Digging further, we find that two memcheck* symbolic links created by valgrind.x86_64 are broken.
$
$ rpm -ql valgrind | grep memcheck
/usr/lib64/valgrind/memcheck-amd64-linux
/usr/lib64/valgrind/memcheck-x86-linux
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so
/usr/lib64/valgrind/vgpreload_memcheck-x86-linux.so
$
$
$ rpm -ql valgrind | grep memcheck | xargs file
/usr/lib64/valgrind/memcheck-amd64-linux:  ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=0x82b75aa9e8494556aa050869e5e7ed20e9522137, stripped

/usr/lib64/valgrind/memcheck-x86-linux:  broken symbolic link to `../../lib/valgrind/memcheck-x86-linux'
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0xdd994ac2a32bece59363fadc2003e49a1b8c3539, stripped
/usr/lib64/valgrind/vgpreload_memcheck-x86-linux.so:  broken symbolic link to `../..
/lib/valgrind/vgpreload_memcheck-x86-linux.so'
$


Let us continue the expedition and find out what other Valgrind packages are available that could possibly bring in the missing files
that those symbolic links are pointing to:
$
$ yum list valgrind*
Loaded plugins: langpacks, refresh-packagekit
Installed Packages
valgrind.x86_64                                       1:3.8.1-15.fc19                                            installed
Available Packages
valgrind.i686                                           1:3.8.1-15.fc19                                            fedora  
valgrind-devel.i686                                 1:3.8.1-15.fc19                                            fedora  
valgrind-devel.x86_64                             1:3.8.1-15.fc19                                            fedora  
valgrind-openmpi.x86_64                       1:3.8.1-15.fc19                                            fedora
$

It is evident that we have 64-bit Valgrind package installed on the system, and 32-bit counter part of the Valgrind package is available (but
not installed on the system).

The solution to my problem seems within arm's reach - Install the package valgrind.i686
But I want to confirm two things before I install that package.
(a) valgrind.i686 will bring in (at least) those two missing files
(b) valgrind.i686 will not overwrite important valgrind binaries with 32-bit versions and break testing of my 64-bit executables.

Let us confirm (a) first:
$
$ repoquery -l valgrind.i686 | grep memcheck
/usr/lib/valgrind/memcheck-x86-linux
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so
$

Sure, the targets of those two broken symbolic link matches the path and file names of these two files.
That confirms that valgrind.i686 will bring in missing files.

Now, let us confirm (b):
$
$ repoquery -l valgrind.x86_64 | grep bin
/usr/bin/callgrind_annotate
/usr/bin/callgrind_control
/usr/bin/cg_annotate
/usr/bin/cg_diff
/usr/bin/cg_merge
/usr/bin/ms_print
/usr/bin/valgrind
/usr/bin/valgrind-listener
/usr/bin/vgdb
$
$ repoquery -l valgrind.i686 | grep bin
/usr/bin/callgrind_annotate
/usr/bin/callgrind_control
/usr/bin/cg_annotate
/usr/bin/cg_diff
/usr/bin/cg_merge
/usr/bin/ms_print
/usr/bin/valgrind
/usr/bin/valgrind-listener
/usr/bin/vgdb
$
$ repoquery -l valgrind.x86_64 | grep bin | xargs file
/usr/bin/callgrind_annotate: Perl script, ASCII text executable
/usr/bin/callgrind_control:    Perl script, ASCII text executable
/usr/bin/cg_annotate:            Perl script, ASCII text executable
/usr/bin/cg_diff:                      Perl script, ASCII text executable
/usr/bin/cg_merge:                 ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x5228b41ce865c922a7948698c40a6ed1b7c7cf1c, stripped
/usr/bin/ms_print:                  Perl script, ASCII text executable
/usr/bin/valgrind:                   ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x19186524e13c9eaaacdc8bec0144b3d82bb0800a, stripped
/usr/bin/valgrind-listener:     ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x5c9a1aa7055c71fcb7cab739509940deb4594464, stripped
/usr/bin/vgdb:                         ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xcbcdb0a010739b8ebfbff0abd508683987646c30, stripped
$

That seems like an issue.
There are duplicate executable files between the 64-bit and 32-bit versions, four of which are binary files.
I estimated - at worst, 32-bit package would overwrite these binary files and, as anticipated, break testing of 64-bit executables; but the damage would be easily reversible with two steps: (a) Uninstall valgrind.i686 (b) Reinstall valgrind.x86_64

With that I was ready to plunge on with a plan -  If things broke, I would to make copy of those two symbolic link's target files, uninstall 32-bit package, reinstall 64-bit package, and finally manually restore broken symbolic links to fix the issue I originally started with.

So I did (sudo yum install valgrind.i686), and as it happens so, valgrind.i686 does not overwrite 64-bit executables.
$
$ rpm -ql valgrind.i686 | grep bin | xargs file
/usr/bin/callgrind_annotate: Perl script, ASCII text executable
/usr/bin/callgrind_control:  Perl script, ASCII text executable
/usr/bin/cg_annotate:          Perl script, ASCII text executable
/usr/bin/cg_diff:                    Perl script, ASCII text executable
/usr/bin/cg_merge:              ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x5228b41ce865c922a7948698c40a6ed1b7c7cf1c, stripped
/usr/bin/ms_print:                Perl script, ASCII text executable
/usr/bin/valgrind:                 ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x19186524e13c9eaaacdc8bec0144b3d82bb0800a, stripped
/usr/bin/valgrind-listener:   ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x5c9a1aa7055c71fcb7cab739509940deb4594464, stripped
/usr/bin/vgdb:                       ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xcbcdb0a010739b8ebfbff0abd508683987646c30, stripped
$

I can not explain this behaviour at this stage without looking into .rpm packaging script logic of this package.

Let us see if rest is as expected. Let us confirm that broken symbolic links are repaired:
$
$ rpm -ql valgrind.x86_64 | grep memcheck | xargs file
/usr/lib64/valgrind/memcheck-amd64-linux:    ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=0x82b75aa9e8494556aa050869e5e7ed20e9522137, stripped
/usr/lib64/valgrind/memcheck-x86-linux:         symbolic link to `../../lib/valgrind/memcheck-x86-linux'
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0xdd994ac2a32bece59363fadc2003e49a1b8c3539, stripped
/usr/lib64/valgrind/vgpreload_memcheck-x86-linux.so:   symbolic link to `../../lib/valgrind/vgpreload_memcheck-x86-linux.so'
$

Sure they are.


Now, like you I was curious to see if valgrind could test 32-bit executables now (without breaking 64-bit executables tests):
$
$ valgrind ./testme32
==7914== Memcheck, a memory error detector
==7914== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7914== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7914== Command: ./testme32
==7914==
==7914==
==7914== HEAP SUMMARY:
==7914==     in use at exit: 0 bytes in 0 blocks
==7914==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==7914==
==7914== All heap blocks were freed -- no leaks are possible
==7914==
==7914== For counts of detected and suppressed errors, rerun with: -v
==7914== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$
$ valgrind ./testme64
==8176== Memcheck, a memory error detector
==8176== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==8176== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==8176== Command: ./testme64
==8176==
==8176==
==8176== HEAP SUMMARY:
==8176==     in use at exit: 0 bytes in 0 blocks
==8176==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==8176==
==8176== All heap blocks were freed -- no leaks are possible
==8176==
==8176== For counts of detected and suppressed errors, rerun with: -v
==8176== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
$
Good. Valgrind is now capable to test both: 64-bit as well as 32-bit executables.

$ valgrind ./atail32_80 test.txt
<snip>
==13468==
==13468== HEAP SUMMARY:
==13468==     in use at exit: 266 bytes in 10 blocks
==13468==   total heap usage: 18 allocs, 8 frees, 623 bytes allocated
==13468==
==13468== LEAK SUMMARY:
==13468==    definitely lost: 262 bytes in 9 blocks
<snip>
Testing my project binary with valgrind did catch expected memory leaks on the first run, along with couple of unexpected memory
access related bugs (not shown here). Now that is going to keep me busy for some time.

Leave any comments/suggestions below.

Wednesday, June 24, 2015

Deleting Files With Little Extra Care On Linux Command Shell !

SeaMonkey 2.31 Release Notes We know that deleting files on a Linux command prompt is an irreversible process. Whilst files deleted from a GUI file manager are usually moved to recycle-bin from where they can be recovered later if they are deemed to have been deleted mistakenly, such fortune is not available to files deleted on the command prompt. Once deleted using command `rm` they are lost permanently (while there tricks and tools to recover them are available, process is not easy and full-proof).

Command `rm` has two command-line switches that can prevent you from accidentally deleting files that you do not intend to. It does so by prompting you.

Both these switches are explained below.


Switch -i

Usage:
  $ rm -i FILES ...

EXAMPLE:
 $ touch a b c d e f 
 $
 $ ls ?
 a b c d e f
 $
 $ rm -i a b c d e f
 rm: remove regular empty file ‘a’? y
 rm: remove regular empty file ‘b’? n
 rm: remove regular empty file ‘c’? y
 rm: remove regular empty file ‘d’? n
 rm: remove regular empty file ‘e’? y
 rm: remove regular empty file ‘f’? n
 $
 $ ls ?
 b d f
 $

The above example demonstrates that -i switch deletes files interactively. In other words, it asks you whether or not you are sure of your action before removing each file.

Switch -i can slow you down if you are heavy into housekeeping and mostly know what you are doing. The next switch -I can be your friend if you are one of the above.


Switch   -I  (Note: that is uppercase I as in Icecream, not lowercase l as in linux)

Usage:
 $ rm -I FILES ...


OBSERVE THE NEXT SET OF EXAMPLES CAREFULLY:

EXAMPLE - Deleting More Than 3 Files
$ touch a b c d e f
$
$ ls ?
$
a  b  c  d  e  f
$
$ rm -I a b c d e f       # Deleting more than 3 files, would prompt (only Once)
rm: remove all arguments? y
$
$ ls ?
ls: cannot access ?: No such file or directory



EXAMPLE - Deleting 3 Or Less Files
$ touch a b c d e f
$
$ ls ?
a  b  c  d  e  f
$
$ rm -I a b c     # Would not prompt for less than or equal to 3 files
$
$ ls ?
d  e  f
$




EXAMPLE - Deleting Files Recursively
$touch a b c d e f
$
$ mkdir -p dir1/dir2
$
$ touch dir1/file1 dir1/dir2/file2
$
$ ls -R dir1
dir1:
dir2  file1

dir1/dir2:
file2
$
$ rm -R -I dir1 # Prompts because of recursion, regardless of the total number of files
rm: remove all arguments recursively? y
$
$ ls -R dir1
ls: cannot access dir1: No such file or directory
$


Above examples demonstrate that -I switch prompts only under two cases:
 (a) Prompts (only once) if the number of files being asked to be deleted on the command prompt are more than 3
 OR
 (b) Prompts (only once) if the files are requested to be deleted recursively through sub-directories (recursive = -R switch)


Switch   -v
In addition to -i or -I, one can add another switch -v (Verbose), as shown below, and receive feedback as to which files were actually deleted (!!) by the command `rm`.

USAGE:
$ rm -v -i FILES ...

OR

$ rm -v -I FILES ...


EXAMPLE:
$ touch a b c d e f
$
$ ls ?
a  b  c  d  e  f
$
$ rm -v -I a b c d e f
rm: remove all arguments? y
removed ‘a’
removed ‘b’
removed ‘c’
removed ‘d’
removed ‘e’
removed ‘f’
$
$ ls ?
ls: cannot access ?: No such file or directory
$

If typing extra command-line switches following the `rm` command every time seem tedious, then we can use `alias` command to ease that. I will soon write a blog on `alias` command, come back and check.


Hope this helps.  Enjoy your time exploring and learning Linux.