This English post was published on November 23, 2015. It contains 538 words and should take no more than 3 minutes to read.
You can also read the previous post, or view the list of all posts, or continue to the next post.

Basic analysis of segmentation fault on Linux platforms

I was adding a few lines of new code to pkcs11-logger library on Windows last week and when I was happy with the result I wanted to test the code on Linux. It built nicely but when I tried to use the resulting library with pkcs11-tool I got segmentation fault.

jariq@ubuntu:~$ pkcs11-tool --module pkcs11-logger-x64.so -I
*** Error in `pkcs11-tool': munmap_chunk(): invalid pointer: 0x00007ffdd7830b6b ***
Aborted (core dumped)

Segfault indicates memory access violation and the displayed error will almost never reveal which library and/or function should be blamed for it. Luckily linux kernel has the ability to dump the memory of faulting process into a core file.

Core file gets generated automatically when segfault occurs and its size does not overflow corresponding ulimit. Maximum allowed size of core file can be displayed with ulimit -c command and the limit can be completely removed with ulimit -c unlimited command.

jariq@ubuntu:~$ ulimit -c
0
jariq@ubuntu:~$ ulimit -c unlimited
jariq@ubuntu:~$ ulimit -c
unlimited

Failing program needs to be executed once again after the size limit has been removed. Right after the segfault there will be core file generated in a current directory.

jariq@ubuntu:~$ pkcs11-tool --module pkcs11-logger-x64.so -I
*** Error in `pkcs11-tool': munmap_chunk(): invalid pointer: 0x00007ffc6808db6b ***
Aborted (core dumped)
jariq@ubuntu:~$ ls –la | grep core
-rw-------  1 jariq jariq 729088 nov 21 07:50 core

Saved core file can be opened for example with GNU Debugger:

jariq@ubuntu:~$ gdb pkcs11-tool core
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from pkcs11-tool...(no debugging symbols found)...done.
[New LWP 2925]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `pkcs11-tool --module pkcs11-logger-x64.so -I'.
Program terminated with signal SIGABRT, Aborted.
#0  0x00007fe9e8250cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb)

Backtrace of all stack frames can be printed with where command issued in gdb shell:

(gdb) where
#0  0x00007fe9e8250cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007fe9e82540d8 in __GI_abort () at abort.c:89
#2  0x00007fe9e828d394 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7fe9e839bb28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007fe9e82980f7 in malloc_printerr (action=<optimized out>, str=0x7fe9e839bea8 "munmap_chunk(): invalid pointer", ptr=<optimized out>) at malloc.c:4996
#4  0x00007fe9e7df236c in pkcs11_logger_init_read_env_var (env_var_name=env_var_name@entry=0x7fe9e7dfa349 "PKCS11_LOGGER_LIBRARY_PATH") at ../../src/init.c:237
#5  0x00007fe9e7df23b1 in pkcs11_logger_init_parse_env_vars () at ../../src/init.c:132
#6  0x00007fe9e7df2565 in pkcs11_logger_init_orig_lib () at ../../src/init.c:75
#7  0x00007fe9e7df3529 in C_GetFunctionList (ppFunctionList=0x618f18) at ../../src/pkcs11-logger.c:191
#8  0x000000000040efc1 in ?? ()
#9  0x0000000000402ef0 in ?? ()
#10 0x00007fe9e823bec5 in __libc_start_main (main=0x402d80, argc=4, argv=0x7ffc6808c5c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffc6808c5b8) at libc-start.c:287
#11 0x0000000000406072 in ?? ()

Displayed backtrace clearly identified line 237 of init.c file as a source of the failure. I have examined the code and I found out that I was trying to free statically allocated memory returned by getenv() function. OMG :)

You can also read the previous post, or view the list of all posts, or continue to the next post.

License: Unless otherwise stated, all content on this website is licensed under CC BY 4.0.
Contact: Feel free to drop me an e-mail to jimrich@jimrich.sk if you have any questions or comments.
Disclaimer: The views expressed on this website are my own and do not reflect the views of my employer or any organizations with which I am or have been associated.
Technology: This website is maintained in its own Git repository and brought to life by the Hugo static site generator.
Legalities: This website does not use cookies.