Как избавится от ошибки?
Как избавится от ошибки?
Начал делать курсач в коммандной строке, используя для графики ncurses.
Меня задолбала ошибка Segmentation fault
При компиляции никаких ошибок нет.
Притом что самое досадное, теперь когда я убрал фрагмент кода, вызывающий ошибку, старая часть программы, работающая до этого нормально, тоже вызывает ее.
Не знаю что делать?
Заново не хочется писать, причем если и напишу, то примерно тоже самое, вдруг опять тоже самое будет?
Не знаю что делать, может кто подскажет что-нибудь?
Меня задолбала ошибка Segmentation fault
При компиляции никаких ошибок нет.
Притом что самое досадное, теперь когда я убрал фрагмент кода, вызывающий ошибку, старая часть программы, работающая до этого нормально, тоже вызывает ее.
Не знаю что делать?
Заново не хочется писать, причем если и напишу, то примерно тоже самое, вдруг опять тоже самое будет?
Не знаю что делать, может кто подскажет что-нибудь?
Max, я что шаман и должен догадаться?
Давай код сюда.
Как вариант - использование printf/scanf до endwin или другое вмешательство в работу ncurses. Если время поджимает - звони 4001738 - посмотрим вместе - я буду в первом копусе сегодня-завтра.
Давай код сюда.
Как вариант - использование printf/scanf до endwin или другое вмешательство в работу ncurses. Если время поджимает - звони 4001738 - посмотрим вместе - я буду в первом копусе сегодня-завтра.
Опыт растет прямо пропорционально выведенному из строя оборудованию
segmentation fault генерирует core dump. Загрузи его в gdb, посмотри стек вызовов функций (команда bt в gdb) - и сразу найдешь ту строку в коде где твоя проблема.
тебе нужно сделать что-то вроде этого:
1. g++ -g 1.cpp
2. ulimit -c unlimited
3. ./a.out
Segmentation fault (core dumped)
4. gdb a.out core.xxx
(gdb) bt
#0 0x4018514c in memcpy () from /lib/libc.so.6
#1 0x08048399 in main (argc=134513528, argv=0x1) at 1.cpp:5
#2 0x4011e917 in __libc_start_main () from /lib/libc.so.6
проблема - файл 1.cpp строка 5.
тебе нужно сделать что-то вроде этого:
1. g++ -g 1.cpp
2. ulimit -c unlimited
3. ./a.out
Segmentation fault (core dumped)
4. gdb a.out core.xxx
(gdb) bt
#0 0x4018514c in memcpy () from /lib/libc.so.6
#1 0x08048399 in main (argc=134513528, argv=0x1) at 1.cpp:5
#2 0x4011e917 in __libc_start_main () from /lib/libc.so.6
проблема - файл 1.cpp строка 5.
Проблема почти всегда в другом месте. gdb показывает где онаAnonymous писал(а):segmentation fault генерирует core dump. Загрузи его в gdb, посмотри стек вызовов функций (команда bt в gdb) - и сразу найдешь ту строку в коде где твоя проблема.
проявилась. А вот чтобы найти место её возникновения, т.е.
почему она вообще есть, используются
memprof, valgrind, ZeroFault, Purify, WorkShop Performance Analyzer
и куча других продуктов.
Если есть "устойчивый" core dump - т.е. программа падает все время в одной и той же точке - в большинстве случаев проблему можно быстро отследить в gdb - анализируя стек.
Да и в других случаях если есть core dump - я всегда для начала загружаю его в gdb и смотрю в какой точке произошел сбой прежде чем переходить к вышеперечисленным средствам (которые тоже не факт что помогут).
Да и в других случаях если есть core dump - я всегда для начала загружаю его в gdb и смотрю в какой точке произошел сбой прежде чем переходить к вышеперечисленным средствам (которые тоже не факт что помогут).
Вот исходный текст:
Посмотрите может кто-чего увидит или подскажет как сделать лучше!!
Код: Выделить всё
#include <ncurses/curses.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <ctype.h>
#include <link.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <unistd.h>
#include <getopt.h>
#include <gnu/libc-version.h>
#include <memory.h>
//*************My Fynctions*****************//
char* ComputerInform(void);
char* SoftInform(void);
char* PaswInform(void);
char* FileSysInform(void);
char* ReadFileInfo(char* path,char* param);
//************Globals**********************//
static char OSVerPath[]="/etc/issue";
static char IPPath[]="/etc/hosts";
static char NWPath[]="/etc/sysconfig/network";
static char NWExPath[]="/etc/sysconfig/networking/ifcfg-lo";
static char PSWPath[]="/etc/login.defs";
static char FSysPath[]="/etc/fstab";
static char compinf[100];
static char softinf[100];
static char fileret[1000];
static char paswinf[100];
static char fsysinf[100];
//************Main Module**************//
static void finish(int sig);
int Menu;
static char* MenuStr[10] = {"Система","Версия ПО","Тип входа","Политика паролей","Файловая система","TCP/IP","Сервисы","Аудит","DDoS","Выход (ESC)"};
static int com;
int main(){
/* инициализируй свои не относящиеся к curses структуры данных здесь */
Menu = 0;
(void) signal(SIGINT, finish); /* подготовить прерывания для завершения */
(void) initscr(); /* инициализировать библиотеку curses */
keypad(stdscr, TRUE); /* разрешить преобразование кодов клавиатуры */
(void) nonl(); /* не делать NL->CR/NL при выводе */
(void) cbreak(); /* читать один символ за раз, не ждать \n */
(void) noecho(); /* не показывать ввод */
if (has_colors())
{
start_color();
/*
* Простое назначение цветов, часто нужное всем.
*/
init_pair(1, COLOR_GREEN, COLOR_BLACK);
init_pair(2, COLOR_MAGENTA, COLOR_BLACK);
}
while(1){
move(0,0);
int x = 0,y = 0,tx=0,ty=0;
if(com==27) break;
switch(com){
case 260:{
if(Menu>0) Menu--;
break;
}
case 261:{
if(Menu<9) Menu++;
break;
}
case 13:{
clear();
move(0,0);
switch(Menu){
case 0:{
printw("Информация о системе:\n",ComputerInform());
getch();
break;
}
}
break;
}}
color_set(1,NULL);
//*****draw menu*****///
for(int i = 0;i<10;i++){
if(Menu ==i){
getyx(stdscr,x,y);
}
printw("%s",MenuStr[i]);
getyx(stdscr,tx,ty);
move(tx,ty+1);
}
move(x,y);
color_set(2,NULL);
printw("%s",MenuStr[Menu]);
com = getch();
clear();
}
finish(0);
return 1; /* мы закончили */
}
static void finish(int sig)
{
endwin();
}
char* ComputerInform()
{
FILE *f;
struct utsname uname_info;
char tmp[256];
bool ip=false,nw=false;
if(uname(& uname_info) == -1)
{
strcat(compinf,"Ошибка при получении информации");
}
strcat(compinf,"Тип операционной системы:\t ");
strcat(compinf,uname_info.sysname);
if((f = fopen(OSVerPath,"rt"))!=NULL){
strcat(compinf,"\nВерсия операционной системы:\t ");
fgets(tmp,256,f);
strcat(compinf,tmp);
memset(tmp,sizeof(tmp),0);
fclose(f);
}
strcat(compinf,"\nПоддержка сети:\t ");
//Здесь вызывается функция и идет ошибка if((strstr(ReadFileInfo(NWPath,"NETWORKING"),"YES")!=NULL)||(strstr(ReadFileInfo(NWPath,"NETWORKING"),"yes")!=NULL)){
strcat(compinf,"да ");
nw = true;
}else{
strcat(compinf,"нет ");
}
strcat(compinf,"\nИмя хоста:\t ");
strcat(compinf,uname_info.nodename);
if((f = fopen(IPPath,"rt"))!=NULL){
strcat(compinf,"\nIP адрес:\t ");
fgets(tmp,256,f);
for(int i = 0;i<256;i++){
if(tmp[i]==9){
tmp[i]='\0';
break;
}
}
strcat(compinf,&tmp[0]);
memset(tmp,sizeof(tmp),0);
fclose(f);
}
if(strstr(compinf,"127.0.0.1")==NULL) ip = true;
strcat(compinf,"\nДомен:\t ");
strcat(compinf,uname_info.domainname);
strcat(compinf,"\nРоль:\t ");
if(nw&&(strstr(uname_info.domainname,"none")!=NULL)) strcat(compinf,"Станция в локальной сети\n");
if(nw&&ip&&(strstr(uname_info.domainname,"none")==NULL)) strcat(compinf,"Контроллер домена\n");
if(!nw) strcat(compinf,"Выделенная станция\n");
return &compinf[0];
}
char* ReadFileInfo(char* path,char* param){
FILE *f;
char buf[256];
char* pParam;
bool beg = false;
char tmp[2] = {0,0};
memset(fileret,sizeof(fileret),0);
if((f = fopen(path,"rt"))==NULL) return "Ошибка чтения файла";
while(!feof(f)){
fgets(buf,256,f);
if(buf[0]=='#') continue;
if((pParam=strstr(buf,param))!=NULL){
int i,k = 0;
while(1){
i++;
tmp[0]= *(pParam+strlen(param)+i-1);
if((!beg)&&((tmp[0]=='\t')||(tmp[0]=='=')||(tmp[0]==' '))) continue;
beg = true;
fileret[k] = *(pParam+strlen(param)+i-1);
k++;
if((tmp[0]=='\n')||(tmp[0]=='\r')) break;
}
fileret[strlen(fileret)-1]='\0';
break;
}
}
fclose(f);
return &fileret[0];
}
char* SoftInform(){
struct utsname uname_info;
if(uname(& uname_info) == -1)
{
strcat(compinf,"Ошибка при получении информации");
}
strcat(softinf,"Версия ядро: \t ");
strcat(softinf,uname_info.release);
strcat(softinf,"\nДата релиза:\t ");
strcat(softinf,uname_info.version);
return &softinf[0];
}
char* PaswInform(void){
/*strcat(paswinf,"\n:Максимальное колличество дней использования пароля \t");
strcat(paswinf,pmaxd);
strcat(paswinf,"\n:Минимальное колличество дней между сменой пароля \t");
strcat(paswinf,pmind);
strcat(paswinf,"\n:Минимально допустимая длинна пароля \t");
strcat(paswinf,pminl);
strcat(paswinf,"\n:Количество дней, после которого подается сообщение об устаревании пароля \t");
strcat(paswinf,pmes);
strcat(paswinf,"\n");*/
return &paswinf[0];
}
char* FileSysInform(void){
/*strcat(fsysinf,"\n:Тип файловой системы \t");
strcat(fsysinf,ReadFileInfo(FSysPath,"PASS_MAX_DAYS"));
strcat(fsysinf,"\n:Точка монтирования \t");
strcat(fsysinf,ReadFileInfo(FSysPath,"PASS_MIN_DAYS"));
strcat(fsysinf,"\n:Тип корневой фаловой системы \t");
strcat(fsysinf,ReadFileInfo(FSysPath,"PASS_MIN_LEN"));*/
return &fsysinf[0];
}
Max,
Ты конечно извини, но этот код похож на пример как не надо
программировать. Обрати внимание на статические массивы,
где размеры указаны цифрами. Ну неужели нету констант в
системных include файлах? Если нету сам сделай -
но только правильно.
passwinf[100] - ты в него загоняешь strcat-ом сколько данных?
fsysinf - то же самое.
Размеры надо учитывать!
Ты же разрушил всю статику, и прога у тебя должна coredump делать.
Ты конечно извини, но этот код похож на пример как не надо
программировать. Обрати внимание на статические массивы,
где размеры указаны цифрами. Ну неужели нету констант в
системных include файлах? Если нету сам сделай -
но только правильно.
passwinf[100] - ты в него загоняешь strcat-ом сколько данных?
fsysinf - то же самое.
Размеры надо учитывать!
Ты же разрушил всю статику, и прога у тебя должна coredump делать.
Не мог бы пояснить.Ты же разрушил всю статику, и прога у тебя должна coredump делать.
Раньше я делал их все char* но постоянно была ошибка Segmentation fault.
Причем сейчас ошибки в основном бывают из-за функции ReadFileInfo(Path,Parametr);
Она исчет в системных файлах параметры и возвращает значения.
Причем самое странное, когда ее вызываешь из main то она все делает правильно, а когда из моих функций, или ерунду или Segmentation fault.
Почему????
Max,
Когда ты пишешь 200 байт в 100 байтный массив, то
перезаписывается что-то другое, которое находится
после этого массива в памяти. Я же не компилятор, не знаю
точно что там находится. Такое обязательно приведет
к coredump, вопрос только когда и где. Оно может даже
работать правильно. Это называется Undefined behaviour.
Для начала замени все 100 на 10000, хотя это и не правильно.
Если не знаешь сколько места понадобится, то получай память
динамически, когда это узнаешь (malloc,calloc,free).
alloca тоже ничего если переносимость не надо и стэка не жаль.
Указатели, это главное достоинство и главная проблема C.
Когда ты пишешь 200 байт в 100 байтный массив, то
перезаписывается что-то другое, которое находится
после этого массива в памяти. Я же не компилятор, не знаю
точно что там находится. Такое обязательно приведет
к coredump, вопрос только когда и где. Оно может даже
работать правильно. Это называется Undefined behaviour.
Для начала замени все 100 на 10000, хотя это и не правильно.
Если не знаешь сколько места понадобится, то получай память
динамически, когда это узнаешь (malloc,calloc,free).
alloca тоже ничего если переносимость не надо и стэка не жаль.
Указатели, это главное достоинство и главная проблема C.