Search code examples
cpointerssegmentation-faultgdb

gdb debugging segmentation fault, arguments count showing false


I am trying to debug the segmentation fault of a menu program written in 'C' and the main function is shown in the below screen shot.

int main( int ac, char **av ) {


/* TDT,II - 02 May 2006 - Added this check to see if there is a Debug level passed in */
    if ( ac > 0 ) {
        iDebug = atoi( av[1] );
        sprintf( cLogText, "Setting Debug Level to ~%d~", iDebug );
        WriteTrace( cLogText );
    };

    initscr();
    clear();

    t1=time(NULL);
    local =localtime(&t1);
    Svc_Login();

    for ( ; ; ) {
        cases_on_pc=FALSE;
        if ( !Process_security() ) break;
        menu1();
    };

    wrap_up(0);
    endwin( );
    exit(0);
}

when i try to debug (run using gdb), without any arguments, getting halted at 0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6 as shown below. if(ac>0) becomes true, only when i pass any arguments. but i haven't passed any runtime arguments. still that 'f block is being executed and function atoi(av[1]) is called and resulted in segmentation fault. I am unable to figure it out. how to proceed further to identify and correct the issue so that i could run the menu program successfully. could somebody give any suggestions on this?

-rw-rw-r--. 1 MaheshRedhat MaheshRedhat 2275270 Jan 10 03:09 caomenu.c
-rw-rw-r--. 1 MaheshRedhat MaheshRedhat       0 Jan 10 03:09 caomenu.lis
-rwxr-xr-x. 1 root         root          796104 Jan 10 03:10 scrmenu
[MaheshRedhat@azureRHEL MenuPrograms]$
[MaheshRedhat@azureRHEL MenuPrograms]$ gdb ./scrmenu

(gdb) run
Starting program: /home/MaheshRedhat/MenuPrograms/scrmenu
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6
Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-189.5.0.1.el8_6.x86_64 libnsl-2.28-189.5.0.1.el8_6.x86_64 ncurses-libs-6.1-9.20180224.el8.x86_64
(gdb) 
(gdb) bt
#0  0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6
#1  0x00007ffff34bfce4 in atoi () from /lib64/libc.so.6
#2  0x0000000000401674 in main (ac=1, av=0x7fffffffe228) at caomenu.pc:541
(gdb)

Update The above issue has been resolved. Here is another encounter of segmentation fault. from this backtrace of system calls, in WriteTrace (cEntryText=0x6f4d20 <cLogText> in my main function lead to call fputs() from library file /lib64/libc.so.6

Starting program: /home/MaheshRedhat/MenuPrograms/scrmenu 1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff34f7f5c in fputs () from /lib64/libc.so.6
(gdb)
(gdb) bt
#0  0x00007ffff34f7f5c in fputs () from /lib64/libc.so.6
#1  0x0000000000472efc in WriteTrace (cEntryText=0x6f4d20 <cLogText> "Setting Debug Level to ~1~") at caomenu.pc:18394
#2  0x00000000004016a0 in main (ac=2, av=0x7fffffffe208) at caomenu.pc:543
(gdb)

The below is the declaration of cLogText

char        cLogText[250];

The below is code for WriteTrace:

/**************************************************************************
 routine to write an entry in the trace file
 **************************************************************************/
void WriteTrace( char *cEntryText ) {

    char cTimeStamp[40];                         /* time stamp variable */
    char cTimeFormat[]="%H:%M:%S: ";             /* time stamp format */

    GetTimeStamp( &cTimeStamp[0], sizeof(cTimeStamp), &cTimeFormat[0] );
    TrcFile = fopen( cTraceFile, cTrcOpenFlag ); /* open the file */
    cTrcOpenFlag[0] = 'a';                       /* after first, always app} */
    fprintf(TrcFile, "%s",   cTimeStamp);        /* write the time stamp */
    fprintf(TrcFile, "%s\n", cEntryText);        /* write the entry */
    fclose(TrcFile);                             /* close the trace file */
    return;                                      /* return to caller */
}

Solution

  • From C11:

    The value of argc shall be nonnegative. argv[argc] shall be a null pointer. If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.

    If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.

    The condition ( ac > 0 ) would be true even if you provided 0 program arguments, with argv[0] pointing to the program name (if it was available).

    This statement:

    atoi( av[1] );
    

    tries to access av[1] which the Standard defines to be NULL when no program arguments were provided. Hence the segmentation violation signal.


    fopen returns NULL to indicate failure.

    TrcFile = fopen( cTraceFile, cTrcOpenFlag );
    

    You do not check its return value here, before passing it to fprintf.

    Perhaps:

    TrcFile = fopen( cTraceFile, cTrcOpenFlag );
    if (!TrcFile) {
        deal with error here..
    }