Ошибка сегментации SIGSEGV в отношении файла pwd.c?

#c #linux

#c #linux

Вопрос:

 #include <unistd.h>
#include <pwd.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


uid_t userIdFromName(char *name)
{
    struct passwd* pwd;
    

    pwd=getpwnam(name);
    if(pwd==NULL)
    {
        perror("gepwnamn");
        exit(EXIT_FAILURE);
    }
    return pwd->pw_uid;
}

int main(int argc, char* argv[])
{
    uid_t uid;
    int totalEntries=0;
    DIR* dir;
    struct dirent* newFile;
    char strUID[65];
    if(argc<1)
    {
        fprintf(stderr,"The format is: %s name",argv[0]);
        exit(EXIT_FAILURE);
    }

    uid=userIdFromName(argv[1]);
    dir=opendir("/proc/");
    sprintf(strUID,"%d",uid);
    
    while((readdir(dir))!=NULL)
    {
        totalEntries  ;
    }
    
    char* dirNames[1000];
    char* dirIds[1000];
    int newCount=0;
    dir=opendir("/proc/");


    while((newFile=readdir(dir))!=NULL)
    {
        
        char statusFilePath[65]="/proc/";
        strcat(statusFilePath,newFile->d_name);
        strcat(statusFilePath,"/status");

        FILE* statusFile=fopen(statusFilePath,"r");//one of the file has been opened;
        size_t size;
        char* lineData;
        

        if(statusFile==NULL)
        continue;
        
        int currentPoisition=0;
        while((getline(amp;lineData,amp;size,statusFile))!=-1)
        {
            
            
            if(strncmp("Uid:",lineData,strlen("Uid:"))==0)
            {   
                
                char* dataLine;
                currentPoisition=ftell(statusFile);
                fseek(statusFile,0,SEEK_SET);
                

                if(strstr(lineData,strUID)!=NULL)
                {
                    
                    
                    int forName=0,forPid=0;
                    while((getline(amp;dataLine,amp;size,statusFile))!=-1)
                    {
                        
                        
                        if(strncmp("Name:",dataLine,strlen("Name:"))==0)
                        {
                            printf("%sn",dataLine);
                            dirNames[newCount]=dataLine;
                            forName=1;
                           

                        }

                        if(strncmp("Pid:",dataLine,strlen("Pid:"))==0)
                        {
                            printf("%sn",dataLine);
                            dirIds[newCount]=dataLine;
                            forPid=1;
                        }

                        if(forName==1amp;amp;forPid==1)
                        {
                            newCount  ;
                        }
                        
                    }
                }
                fseek(statusFile,0,SEEK_SET);
                fseek(statusFile,currentPoisition,SEEK_SET);
            }

        }
        
    }


   /* int runner=0;
    while(runner<newCount)
    printf("%sn",dirNames[runner  ]);*/
}
  

Я не смог понять дампы ядра, созданные для этой программы.Программа завершает работу на полпути. Вот информация о дампе ядра:

Программа завершилась сигналом SIGSEGV, ошибка сегментации. #0 0x00007f4ed8699d9c в _nss_files_getpwnam_r (name =0x0, result= 0x7f4ed8896140 , buffer= 0x559f75c7e2a0 «root», buflen=1024, errnop = 0x7f4ed889a4c0) в nss_files/files-pwd.c:32 32 nss_files /files -pwd.c: Такого файла или каталога нет.

Я благодарю вас за вашу помощь.

Комментарии:

1. Я считаю, что это: getline(amp;lineData,amp;size,statusFile)) lineData перед таким использованием необходимо указать память и адрес…

Ответ №1:

Вы уточнили содержимое argv[1] , прежде чем использовать его здесь?

 uid=userIdFromName(argv[1]);
  

Также, среди прочих проблем, использование переменной, созданной как:

 char* lineData;
  

в такой функции, как:

 while((getline(amp;lineData,amp;size,statusFile))!=-1)
  

Вероятно, вызовет a seg-fault , поскольку вы пытаетесь выполнить запись в местоположение, которое вам не принадлежит.

То же самое для:

 char *dataLine;
...
while((getline(amp;dataLine,amp;size,statusFile))!=-1)  
  

и т.д.

Перед использованием создайте память и адрес для них (и любых других подобных им).

например:

  size_t size = 1000;
 char *lineData  = malloc(size*(sizeof(*lineData));
 if(lineDate)
 {
     //continue to use lineData 
     free(lineData);//when done using it 
     ... 
  

Комментарии:

1. То же самое и с malloc. Я предположил, что это происходит из-за того, что free фактически не освобождает память. Я использовал контролируемые данные и установил argv [1] для имени пользователя, которое будет принято.