Ошибка сегментации отладки gdb, счетчик аргументов показывает ложь

Я пытаюсь отладить ошибку сегментации программы меню, написанной на «C», и основная функция показана на снимке экрана ниже.

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);
}

когда я пытаюсь выполнить отладку (запустить с помощью gdb) без каких-либо аргументов, я останавливаюсь на 0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6, как показано ниже. if (ac>0) становится истинным, только когда я передаю какие-либо аргументы. но я не передал никаких аргументов времени выполнения. тем не менее, этот блок 'f выполняется и вызывается функция atoi(av[1]), что приводит к ошибке сегментации. Я не могу понять это. как действовать дальше, чтобы определить и исправить проблему, чтобы я мог успешно запустить программу меню. может ли кто-нибудь дать какие-либо предложения по этому поводу?

-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)

Обновлять Вышеупомянутая проблема решена. Вот еще одно столкновение с ошибкой сегментации. из этой трассировки системных вызовов в WriteTrace (cEntryText=0x6f4d20 <cLogText> в моей основной функции приводит к вызову fputs() из библиотечного файла /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)

Ниже приведена декларация cLogText

char        cLogText[250];

Ниже приведен код для 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 */
}

Что такое WriteTrace? Что такое clogText?

Haris 10.01.2023 07:36

Что такое CtraceFile? Что такое cTrcopenflag?

Haris 10.01.2023 07:55
GetTimeStamp( &cTimeStamp[0], sizeof(cTimeStamp), &cTimeFormat[0] ); Это в основном правильно, но редко. Эти массивы уже распадаются на указатели при передаче в функцию. Вместо этого вы можете написать GetTimeStamp( cTimeStamp, sizeof(cTimeStamp), cTimeFormat);, что более распространено.
Gerhardh 10.01.2023 09:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

if (ac > 0) {
 iDebug = atoi(av[1]);  // out of bounds here, when you run `./scrmenu`
}

когда вы бежите ./scrmenu, у вас будут ac=1 и av[0]=./scrmenu

Вы можете неправильно понять ac и av значение в функции main.

как исправить:

if (ac == 2) {
 iDebug = atoi(av[1]);  // parse the second argument
}

то вы можете запустить: ./scrmenu или ./scrmenu 1 что-то вроде этого.

вы можете проверить этот пост об аргументе командной строки

спасибо @TiapingHsu. Сейчас работает в этом направлении. Я столкнулся с другой ошибкой сегментации для вызова fputs() из библиотеки. Я обновил свой вопрос. Не могли бы вы проверить один раз

Mahesh Babu Tatineni 10.01.2023 07:32
Ответ принят как подходящий

Из С11:

Значение argc должно быть неотрицательным. argv[argc] должен быть нулевым указатель. Если значение argc больше нуля, элементы массива argv[0] по argv[argc-1] включительно должны содержать указатели на строки, которым хост присваивает значения, определенные реализацией среду перед запуском программы. Цель состоит в том, чтобы поставлять информация о программе, определенная до запуска программы из другого места в размещенной среде. Если хост-среда не поддерживает снабжая строки буквами как в верхнем, так и в нижнем регистре, реализация должна гарантировать, что строки будут получены в нижний регистр.

Если значение argc больше нуля, строка указанный argv[0] представляет имя программы; argv[0][0] должен быть нулевой символ, если имя программы недоступно с хоста среда. Если значение argc больше единицы, строки указанный argv[1] через argv[argc-1] представляет программу параметры.

Состояние ( ac > 0 ) было бы истинным, даже если бы вы предоставили 0 аргументы программы, где argv[0] указывало бы на имя программы (если оно было доступно).

Это утверждение:

atoi( av[1] );

пытается получить доступ к av[1], который Стандарт определяет как NULL, когда аргументы программы не были предоставлены. Отсюда сигнал нарушения сегментации.


fopen возвращает NULL, чтобы указать на ошибку.

TrcFile = fopen( cTraceFile, cTrcOpenFlag );

Вы не проверяете его возвращаемое значение здесь, прежде чем передать его в fprintf.

Возможно:

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

спасибо @Haris, теперь это работает в этом аспекте. Я столкнулся с другой ошибкой сегментации для вызова fputs() из библиотеки. Я обновил свой вопрос. Не могли бы вы проверить один раз

Mahesh Babu Tatineni 10.01.2023 07:33

В коде, который вы нам предоставили, нет вызова fputs. Пожалуйста, отредактируйте вопрос, включив в него минимальный воспроизводимый пример, содержащий всю необходимую информацию.

Haris 10.01.2023 07:34

Другие вопросы по теме