【问题标题】:SIGSEGV segmentation fault with regards to the pwd.c file?关于 pwd.c 文件的 SIGSEGV 分段错误?
【发布时间】:2020-09-16 19:02:45
【问题描述】:
#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("gepwnam\n");
        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(&lineData,&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(&dataLine,&size,statusFile))!=-1)
                    {
                        
                        
                        if(strncmp("Name:",dataLine,strlen("Name:"))==0)
                        {
                            printf("%s\n",dataLine);
                            dirNames[newCount]=dataLine;
                            forName=1;
                           

                        }

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

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

        }
        
    }


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

我无法理解为此程序生成的核心转储。程序中途崩溃。这是核心转储信息:

程序以 SIGSEGV 信号终止,分段错误。 #0 0x00007f4ed8699d9c in _nss_files_getpwnam_r (name=0x0, result=0x7f4ed8896140, buffer=0x559f75c7e2a0 "root", buflen=1024, errnop=0x7f4ed889a4c0) at nss_files/files-pwd.c:32 32 nss_files/files-pwd.c: 没有这样的文件或目录。

感谢您的帮助。

【问题讨论】:

  • 我相信这一点:getline(&amp;lineData,&amp;size,statusFile)) 要求lineData 需要在使用之前获得内存和地址......

标签: c linux


【解决方案1】:

argv[1]的内容在这里使用前你有没有限定?

uid=userIdFromName(argv[1]);

此外,除其他问题外,使用创建为的变量:

char* lineData;

在一个函数中,例如:

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

可能会导致seg-fault,因为您正尝试写入不属于您的位置。

同样适用于:

char *dataLine;
...
while((getline(&dataLine,&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 
     ... 

【讨论】:

  • 与malloc相同。我认为,这是因为 free 实际上不会释放内存。我一直在使用受控数据并将 argv[1] 设置为将被接受的用户名。
猜你喜欢
  • 1970-01-01
  • 2020-06-26
  • 2020-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
  • 2011-01-28
  • 1970-01-01
相关资源
最近更新 更多