[Clfs-dev] Sanity checks

Akira Urushibata afu at wta.att.ne.jp
Sun Sep 20 21:28:12 PDT 2009


It is not possible to run checks that come with the packages during the
early stages of CLFS.  As a result, errors may go unnoticed for a while.
When they show up, one has to go back and do things over again.  When the
exact cause of the error cannot be determined, one has to start anew from
the beginning.

I'd like to share some techniques to address this problem.
  

First I'd like to outline what the typical errors are.

1)  Simple typos
    example:  ./configure --prefix=/ussr

3)  Skipping a specific command
    example: omitting "make install"

2)  Skipping an entire page

3)  Confusing pages from different stages
    GCC is built four times in CLFS 1.1.
    Binutils is built three times.
    
The tests (for CLFS 1.1) listed below should help bring mistakes to light.


1. Examine installed binary executables with file.

Programs in /clfs/cross-tools/bin are executables for the host system.
Programs in /clfs/tools/bin are for the target system.

If you build a 64-bit target system on a 32-bit host system,
/cross-tools/bin should contain 32 bit executables and /tools/bin
should contain 64-bit executables.  You can check this with the file
utility, which is built at the beginning of chapter 5.


2. Execute programs and make sure that they work.

Programs in /clfs/cross-tools/bin should run on the host system.
You can check them by doing things like:

/clfs/cross-tools/bin/file --version
/clfs/cross-tools/bin/**-**-**-cc --version


3.  Trying out GCC with a trivial test program.

First write a short program, say one that just prints a message.
Example "test.c":

main(){ printf("Hello! %d\n"); }

The static cross-gcc built in 5.8 should get to the assembly stage:

$ /mnt/clfs/cross-tools/bin/**-**-**-gcc -m64 -S test.c

This will emit one warning:

test.c: In function 'main':
test.c:1: warning: incompatible implicit declaration of built-in function 'printf'

You should see 64 bit registers %rsp, %rbp, etc. in the assembly listing
"test.s" .

The final cross-gcc from 5.11 produces a working binary executable.
Use the file utility to check that the resulting output is in the right format:

$ /mnt/clfs/cross-tools/bin/**-**-**-gcc -m64 test.c -o test
$ /mnt/clfs/cross-tools/file test


If you already have a 64-bit system somewhere, you can take the binary
executable there and try running it on it.

We want a stand-alone executable so we compile static:

$ /mnt/clfs/cross-tools/bin/**-**-**-gcc -m64 --static test.c -o test


4:  Examining the linkmap

The linkmap is a file optionally produced by the link-loader (ld) which
contains information on what files were loaded to resolve external symbols.
We can use this feature to check the cross-compiler built in 5.11.

The following makes a link map file named "Linkmap":

$ /mnt/clfs/cross-tools/bin/**-**-**-gcc test.c \
  -Xlinker "-Map" -Xlinker "Linkmap"
$ grep "LOAD" Linkmap    # Reports loaded object files and libraries
$ rm a.out
$ rm Linkmap

Here is a shortcut:

$ /mnt/clfs/cross-tools/bin/**-**-**-gcc test.c -o /dev/null \
  -Xlinker "-M" | grep "LOAD"


No library files from the host system should be reported here.
The library files should be the ones in "/tools/": "/tools/lib" and
so on.  We also see some files from "/cross-tools/".  These are run-time
initialization files ("crti.o" and such) and libraries which come with
the GCC package.

It is instructive to compile the same test.c with your host-system gcc,
create a link map and observe the changes.

$ /usr/bin/gcc test.c -o /dev/null -Xlinker "-M"  | grep "LOAD"

Also try this at right after boot or chroot, after installation of the
final GCC, and after the specs file modification.


5. Check for existence of utilities with whereis.

5.1  Check for well-known utilities:

$ for i in as od strip gprof gcc bash \
  ls date md5sum diff find locate \
  gawk awk msgfmt grep gzip zcat \
  make patch sed tar info lsmod \
  hwclock \
  flex ps perl ping ftp vim less man
    do
    whereis -b $i -B /bin /sbin /tools/bin /tools/sbin
    done

Do this after boot or chroot, to assure that all the necessary utilities
are in place.  You can throw in whatever else you please.

At the end of chapter 10, do it again, but change one line:

    whereis -b $i -B /bin /sbin /usr/bin /usr/sbin


These programs are not available just after boot/chroot:

  flex ps perl ping ftp vim less man 


5.2  Thorough whereis test.

This is like the one above, only that it scans through the book to find
"installed programs".

$ sed -n '/Installed programs:/,/<\/span>$/p' CLFS-BOOK.html |
  grep -v "Installed programs" |
  sed -e 's@</span>@,\n@' -e 's@<span class="segbody">@\n@' |
  tr '\n' ' ' |
  sed -e 's/,\| and /\n/g' |
  sed -e '/^ *$/d' -e 's/^ *//' -e 's/  */ /g' > list

$ cut -d' ' -f 1 list | while read i           # cut, not cat; see below
    do
    whereis -b $i
    done

The file "list" above reports links like this:

  c++
  cc (link to gcc)
  cpp

The whereis utility is in the Util-linux-ng package.

Doing the above, I discovered that tack (from Ncurses) and resizecons (Kbd)
are not installed, contrary to what is written in the Book.



6.  Examine linked libraries with readelf.

find /bin /sbin /etc /lib /lib64 /usr -type f -perm /111 | while read i
  do
  readelf -h $i > /dev/null 2>&1 && echo -n $i && readelf -e $i |
  fgrep "[Requesting";  echo ""
  done

Make sure there are no binaries linked to libraries in "/tools/".

Some files will report no library link request.  These are libraries
themselves or statically linked executables.



7.  Turning off write permission of "/cross-tools/" and "/tools/"

No new files are written into "/cross-tools/" in Chapter 6 and onward.

After boot or chroot, no files in "/cross-tools/" are accessed.

No new files are created in "/tools/" in Chapter 10 and onward.  Only one
write access to "/tools/" happens during Chapter 10, namely the specs file
adjustment in 10.9.

The above can be checked by examining the ctime and atime.  A more certain
way would be to turn off read/write permission at the directory stem
at the appropriate moment.  The latter is recommended for access time
is by no means easy to keep track of.

Several actions trigger access.  When you check file type with file,
it counts as a read access.  If you strip symbols off an executable, the
event is recorded as a creation of new file.  Any copy is a read access,
and each an every ls is a directory read access.  We can't keep track of
all this so we encounter numerous "mysterious accesses" when we give
"ls -l --time=a" a try - and then (usually) give up.  For details consult
the manual pages of "file", "strip", "ls", etc.

---

Thank you for reading.  I hope this helps.  I feel people need tangible
methods to check progress as they work through the build process.

As I am new to this list, I'd very much appreciate instructions on how
this material can be incorporated into coming versions of CLFS books.
Though the above is for CLFS 1.1, I am sure some parts are valid for
(plain) LFS as well.





More information about the Clfs-dev mailing list