Building and Debugging with Interix


This section presents a C source code line-counting application written by T. E. Dickey. The source can be downloaded from the following url: http://dickey.his.com/c_count/c_count.html

This source code provides an example of how to use Interix to build and run an application.

The process involves three stages:

  1. Run a configuration script.

  2. Build the application.

  3. Debug the application.

By creating the application s makefile, a configuration script adapts the source code to the program s execution environment, that is, the hardware and operating system. Configuration scripts convey configuration information to the application package by defining preprocessor variables , indicating the presence or absence of specific features. Typically, the make variable CFLAGS provides this information. However, the information can also be put into a file named config.h. With the config.h solution, all the configuration information is in one location. The config.h method is provided by the c_count program.

The config.h file contains information similar to this listing for the c_count program:

 /*  * $Id: config_h.in,v 7.1 1994/06/12 23:48:18 tom Exp $  * config_h.in is a template file used by configure to produce config.h.  * config_h is then transformed (by using config.status) into the header file  * config.h  Kevin Buettner.  */ #define const #define HAVE_STDLIB_H   1 #define HAVE_GETOPT_H   1 #define HAVE_STRING_H   1 #define HAVE_MALLOC_H   1 #define DECLARED_GETOPT 1 

The config.h listing for c_count shows that the configuration information defines some compile-time macros to be true (1). These are used in the c_count.c program (by including system.h) as arguments to preprocessor #ifdef commands. Thus, they include some specific library header files, such as stdlib.h.

To verify that Interix provides these header files, an administrator can perform specific searches, for example:

 % find /usr -name stdlib.h -print /usr/include/stdlib.h 

Or the administrator can list the contents of the main header directory. This is a good check to perform before execution of the configuration script. For example:

 ls /usr/include alloca.h       float.h     mpool.h                rpc            typeinfo ar.h           fnmatch.h   ndbm.h                 search.h       tzfile.h arpa           form.h      netdb.h                setjmp.h       ucontext.h assert.h       fts.h       netinet                signal.h       ulimit.h cpio.h         ftw.h       new                    stdarg.h       unctrl.h ctype.h        g++         new.h                  stddef.h       unistd.h curses.h       glob.h      nl_types.h             stdio.h        utime.h db.h           gnu         nl_types_private.h     stdlib.h       utmpx.h dirent.h       grp.h       opennt                 string.h       va_list.h dlfcn.h        interix     panel.h                strings.h      varargs.h err.h          libgen.h    paths.h                stropts.h      vis.h errno.h        limits.h    poll.h                 sys            wait.h eti.h          locale.h    protocols              syslog.h       wchar.h exception      malloc.h    pty.h                  tar.h          xti.h excpt.h        math.h      pwcache.h              term.h fcntl.h        memory.h    pwd.h                  termios.h features.h     menu.h      regex.h                time.h 

Because the following configuration script is not a GNU configure script, it needs to be executed as shown. The script first checks for system-supported features. It then creates the config.status file (used to make the config.h file) and the makefile script to compile and link the application.

 ./configure prefix=/usr/local host=intel-pclocal-interix loading cache ./config.cache checking for gcc... (cached) cc checking whether we are using GNU C... (cached) no checking for a BSD compatible install... (cached) ./install.sh -c checking how to run the C preprocessor... (cached) cc -E checking whether make sets ${MAKE}... (cached) no checking for working const... (cached) no checking whether cross-compiling... (cached) yes checking for ANSI C header files... (cached) no checking for stdlib.h... (cached) yes checking for getopt.h... (cached) yes checking for string.h... (cached) yes checking for malloc.h... (cached) yes checking for strchr... (cached) no checking for getopt... (cached) no checking if compiler supports prototypes... (cached) no checking if getopt is declared... (cached) yes creating ./config.status creating makefile creating config_h creating config.h removing config_h 

Because configuration scripts are used for a number of application packages, it is helpful to create the following script to run configure scripts as part of the build environment setup. This script sets the compilation flags for C, C++, and CPP.It also includes the /usr/local directory for both include and library files.

 $ cat /usr/local/bin/runconfig set -x CPPFLAGS="-D_ALL_SOURCE -I/usr/local/include" \ CXXFLAGS="-D_ALL_SOURCE -I/usr/local/include" \ CFLAGS="-D_ALL_SOURCE -I/usr/local/include" \ LDFLAGS="-L/usr/local/lib" \ ./configure prefix=/usr/local \ host=intel-pclocal-interix $* 

Next , try the make command:

 % make cc -c -I. -I. -DHAVE_CONFIG_H -g c_count.c mv c_count oc_count mv: rename c_count to oc_count: No such file or directory *** Error code 1 (ignored) cc  -o c_count c_count.o 

The compile-time macro definition specifies that there is a config.h file. An erroris generated, but only because the makefile script attempts to save an old c_count program file to oc_count by using an mv command. This is the first build; therefore, an old c_count program does not exist. The error will not occur on subsequent builds.

This initial test uses the program to perform a self-analysis, which yields the following results:

 % ./c_count c_count.c   1015   347   c_count.c ----------------------   1015   347              total lines/statements    147       lines had comments          14.5 %     36       comments are inline         -3.5 %     78       lines were blank            7.7 %     41       lines for preprocessor      4.0 %    785       lines containing code       77.3 %   1015       total lines                 100.0 %   4335       comment-chars               18.5 %    922       nontext-comment-chars       3.9 %   5014       whitespace-chars            21.3 %    643       preprocessor-chars          2.7 %  12577       statement-chars             53.5 %  23491       total characters            100.0 %   1770       tokens, average length      4.85   0.33       ratio of comment:code 

The word count command performs a simple check:

 % wc c_count.c     1015    3309   23491 c_count.c 

Notice the agreement with the total number of lines and characters in c_count.c.

This program also includes a self-test script, which yields the following output:

 % cd testing % ./run_test.sh ** **      Case 1: Count lines in test-files (which have both unbalanced quotes and **              "illegal" characters: **      (ok) ** **      Case 2: Suppressing unbalanced-quote: **      (ok) ** **      Case 3: Counting by names given in standard-input: warning: this program uses gets(), which is unsafe. **      (ok) ** **      Case 4: Counting bulk text piped in standard-input: **      (ok) ** **      Case 5: Counting history-comments **      (ok) ** **      Case 6: Display as a spreadsheet **      (ok) ** **      Case 7: Display as a spreadsheet (per-file) **      (ok) 

In case the application detects a problem, the gdb debugger is available in the Interix SDK.However, gdb has certain limitations in Interix. It provides useful information for object files compiled with gcc and g++ , but not for files compiled with cc or c89 . It also does not implement watch points.

The Interix implementation of the gdb debugger works with shared libraries. It also includes some additional commands. For more information, see gdb Help for the shared and info shared commands.

The gdb debugger can be used on a program or an object file only if the program was created with debugging information, that is, compiled with the -g option.The g option stores symbol information and line numbers . The debugger refersto the source code only if the source code is available on the system. By default, gdb looks for the source files in the directory from which gdb was executed.Also, gdb can be used to examine the core files created when an application faults.

The basic steps for debugging a program are:

  1. Include debugging information when compiling and linking the program.

  2. Start gdb .

  3. Debug the program.

The following shows the output from the gdb command when executing the c_count application:

 % gdb c_count GNU gdb 4.16.1 Copyright 1997 Free Software Foundation, Inc. gdb is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for gdb. Type "show warranty" for details. This gdb was configured as "i386-pc-interix"... (gdb) file c_count Reading symbols from c_count  Done. (gdb) run c_count.c    (This statement says run the program with argument "c_count.c") Starting program: /usr/examples/c_count/c_count c_count.c   1015   347   c_count.c   1015   347    total lines/statements    147  lines had comments        14.5 %     36  comments are inline       -3.5 %     78  lines were blank           7.7 %     41  lines for preprocessor     4.0 %    785  lines containing code     77.3 %   1015  total lines              100.0 %   4335  comment-chars             18.5 %    922  nontext-comment-chars      3.9 %   5014  whitespace-chars          21.3 %    643  preprocessor-chars         2.7 %  12577  statement-chars           53.5 %  23491  total characters         100.0 %   1770  tokens, average length 4.85   0.33  ratio of comment:code Program exited normally. (Notice the programs output is identical.) (gdb) list 917     int     main (918             _ARG(int,       argc), 919             _ARG(char **,   argv) 920) 921             _DCL(int,       argc) 922             _DCL(char **,   argv) 923     { 924             register int j; 925             auto    char    name[BUFSIZ]; 926             auto    int     opt_all = -1; The gdb list command lists the next 10 lines of source code. (Note: gdb was able  to find source file in the current directory.) (gdb) list 929 (A line number can be specified, to list 10 lines starting 5 lines  before the specified line) 924             register int j; 925             auto    char    name[BUFSIZ]; 926             auto    int     opt_all = -1; 927 928             quotvec = typeCalloc(char *, (size_t)argc); 929             while ((j = getopt(argc,argv,"cdijlo:pq:stv")) != EOF) switch(j) { 930             case 


UNIX Application Migration Guide
Unix Application Migration Guide (Patterns & Practices)
ISBN: 0735618380
EAN: 2147483647
Year: 2003
Pages: 134

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net