I was experiencing segfaults at startup for likwid-perfctr in 3.1.2 on Haswell
with GCC 4.8.1. But when I tried to debug the problem, it seemed like my
changes did not take effect until I ran 'make distclean'. I eventually
discovered that the issue is that the arguments used to create the static
library 'liblikwid.a' are incorrect, and the changed files are appended to the
library rather than used to replace the originals. Absolutely insidious! This
has probably been the cause of lots of random inexplicable misery on your end.
What steps will reproduce the problem?
$ wget http://ftp.fau.de/pub/likwid/likwid-3.1.2.tar.gz
$ tar -xzf likwid-3.1.2.tar.gz
$ cd likwid-3.1.2/
$ make
$ ./likwid-perfctr -C2 ls
Segmentation fault (core dumped)
$ cp likwid-perfctr likwid-perfctr.orig
$ cp liblikwid.a liblikwid.a.orig
$ emacs src/affinity.c
# add a debugging statement at line 131 to print 'counter'
# fprintf(stderr, "counter: %d\n", counter);
$ make
$ ./likwid-perfctr -C2 ls
Segmentation fault (core dumped)
$ diff
$ ls -l liblikwid.a
-rw-rw-r-- 1 nate nate 2464232 Aug 31 13:52 liblikwid.a.orig
-rw-rw-r-- 1 nate nate 4928490 Aug 31 13:57 liblikwid.a
# note that the new library is clearly different but much larger
$ ls -l likwid-perfctr*
-rwxrwxr-x 1 nate nate 1126318 Aug 31 13:57 likwid-perfctr
-rwxrwxr-x 1 nate nate 1126318 Aug 31 13:47 likwid-perfctr.orig
# no size difference for supposedly new version of app
$ diff -s likwid-perfctr likwid-perfctr.orig
Files likwid-perfctr and likwid-perfctr.orig are identical
# library has changed but app is unchanged
$ rm liblikwid.a
$ make
$ ls -l liblikwid.a*
-rw-rw-r-- 1 nate nate 2464392 Aug 31 14:12 liblikwid.a
-rw-rw-r-- 1 nate nate 2464232 Aug 31 13:52 liblikwid.a.orig
# note that library is back to original size
$ diff -s likwid-perfctr likwid-perfctr.orig
Binary files likwid-perfctr and likwid-perfctr.orig differ
What is the expected output? What do you see instead?
$ grep \{AR} Makefile
$(Q)${AR} -cq $(STATIC_TARGET_LIB) $(OBJ)
$ man ar
# q Quick append; Historically, add the files member... to the end of
archive, without
# checking for replacement.
# c Create the archive. The specified archive is always created if it did
not exist,
# when you request an update. But a warning is issued unless you
specify in advance
# that you expect to create it, by using this modifier.
Incredibly, this combination of options does not recreate the library rather
the changed files are just appended to the existing library, and then not used!
I'm not certain what the best arguments for 'ar' should be, but clearly this
is not the behaviour we want. 'ar -crus' would seem to be a good choice:
Create, Replace, Update, (S)index. At the least, we need to add "r" for
replace, and drop "q" for quick.
$ diff -u Makefile~ Makefile
--- Makefile~ 2014-06-02 09:55:05.000000000 -0400
+++ Makefile 2014-08-31 14:27:58.299935166 -0400
@@ -197,7 +197,7 @@
$(STATIC_TARGET_LIB): $(OBJ)
@echo "===> CREATE STATIC LIB $(STATIC_TARGET_LIB)"
- $(Q)${AR} -cq $(STATIC_TARGET_LIB) $(OBJ)
+ $(Q)${AR} -crus $(STATIC_TARGET_LIB) $(OBJ)
$(DYNAMIC_TARGET_LIB): $(OBJ)
@echo "===> CREATE SHARED LIB $(DYNAMIC_TARGET_LIB)"
Finally we can try to figure out the underlying segfault without going crazy!
$ ./likwid-perfctr -C2 ls
counter: 4
counter: 3
counter: 2
counter: 1
counter: 0
counter: -1
counter: -2
counter: -3
counter: 4
counter: 3
counter: 2
counter: 1
counter: 0
counter: -1
counter: -2
counter: -3
counter: 4
counter: 3
counter: 2
counter: 1
counter: 0
counter: -1
counter: -2
counter: -3
counter: 4
counter: 3
counter: 2
counter: 1
counter: 0
counter: -1
counter: -2
counter: -3
Segmentation fault (core dumped)
Those negative numbers don't look good. See next bug for details.
Original issue reported on code.google.com by n...@verse.com on 31 Aug 2014 at 6:38
Original issue reported on code.google.com by
n...@verse.com
on 31 Aug 2014 at 6:38