简体   繁体   English

段故障? 你能找到吗? 因为我不能

[英]Seg fault? Can you find it? cause I can't

I've looked over this about 15 times by now to no avail. 到目前为止,我已经查看了大约15次,但均无济于事。 I cannot understand why this is seg faulting? 我不明白为什么这是段错误? It doesn't even get to the "print" statement which makes no sense. 甚至没有意义的“ print”语句。 the error codes actually do work tho (when I dont have a shared memory present) I have a load.c program but it works perfectly (im 100% sure of this) 错误代码实际上起作用了(当我没有共享内存时)我有一个load.c程序,但是它运行得很好(我对此有100%的把握)

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
#include "header.h"

//BEGIN MAIN FUNCTION
main()
{
    int id;             //ID to data shmem
    struct StudentInfo *infoptr;    //ptr to data
    int found = 0;          //found 'boolean'
    char input[15];         //user input buffer
    struct StudentInfo *beginptr;   //ptr to beginning of data
    int rcid;           //Read count ID to shmem
    int *rcptr;         //RC ptr
    int sema_set;           //ID to shared semaphores

    //Find the shmem at our ID
        id = shmget(KEY,SEGSIZE,0);
        if(id < 0)
        {
                perror("Query: shmget failed");
                exit(1);
        }

    //set the ptr to our shared mem and attach to program
        infoptr = (struct StudentInfo *)shmat(id,0,0);
        if(infoptr <= (struct StudentInfo *)(0))
        {
                perror("Query: shmat failed");
                exit(1);
        }

    //Get our RC in shared memory 
    rcid = shmget(RCKEY,READCOUNT,0);
    if(rcid < 0)
    {
        perror("Query: shmget failed");
        exit(1);
    }
    //Set ptr to shmem and attach to process
    rcptr = (int*)shmat(rcid,0,0);
    if(rcptr <= (int*)(0))
    {
        perror("Print: Shmat failed");
        exit(1);
    }

    //Get semaphores
    sema_set = semget(SEMA_KEY,NUM_SEMAPHS,0);
    if(sema_set < 0)
    {
        perror("Query: Semget failed");
        exit(1);
    }   

    //Set program to queue up to wait
    Wait(sema_set,1);

    //Increment the read counter
    *rcptr += 1;

    //If we are the first reader, stop writers
    if(*rcptr == 1)
    Wait(sema_set,0);

    //Signal readers
    Signal(sema_set,1);

    //Set our begin ptr
    beginptr = infoptr;

    //Begin user input loop
    while(1)
    {
    //Ask user for input IT DOESN"T EVEN GET TO HERE <--
    printf("Please input a student ID :");
    scanf("%s",input);

    //While the record is not found search  
    while(strcmp(infoptr->Name,"")!=0 && found != 1)
    {
        //If record found, print the record
        if((strncmp(input,infoptr->ID,9)) == 0)
        {
            //Set found
            found = 1;

            printf("\n%s\n",infoptr->Name);
                    printf("%s\n",infoptr->telNumber);
                    printf("%s\n",infoptr->Address);
                    printf("%s\n\n",infoptr->ID);
        }
        else
            infoptr++;
    }

    //If not found, print error message
    if(found == 0)
        printf("Record not found.\n");

    //Wait on readers
    Wait(sema_set,1);
    //Decrement
    *rcptr--;
    //If no readers left
    if(*rcptr == 0)
        Signal(sema_set,0); //Signal writers
    //Signal readers
    Signal(sema_set,1);
    exit(0);        
    }
}

HEADER HEADER

#define KEY  ((key_t)(11111)) /*change it to last five digits of your SSN*/
#define SEGSIZE  sizeof(struct StudentInfo)

#define NUM_SEMAPHS 2
#define SEMA_KEY   ((key_t)(1111)) /* change this to last four digits of SSN */

#define READCOUNT sizeof(int)   //Set the size of shmem for read count
#define RCKEY ((key_t)(4003))   //Set the key of the shmem for RCount

//Struct student info
struct StudentInfo{
  char Name[20];
  char ID[15];
  char Address[50];
  char telNumber[15];
};

//Checks the semaphore whether or not to wait
void Wait(int semaph, int n);
//Signals that it's ok to run
void Signal(int semaph, int n);
//Gets the semaphore information
int GetSemaphs(key_t k, int n);

Your problem might come from your use of shmat . 您的问题可能来自使用shmat In C, never cast the return type of such a function. 在C语言中,切勿强制转换此类函数的返回类型。 That you felt the need for it probably means that you had a spurious error message that came from the fact that you are missing the "sys/shm.h" header. 您认为有必要,可能意味着您收到了一个虚假的错误消息,该错误消息是由于缺少“ sys / shm.h”标头而造成的。

What happens in such cases is that gcc takes the return type for an int , usually a 32 bit quantity, and re-interprets it as a pointer. 在这种情况下,发生的情况是gcc接受int的返回类型(通常为32位量)并将其重新解释为指针。 So the upper half of your address that shmat gives you is lost. 因此shmat给您的地址的上半部分丢失了。

As a general rule, don't cast away problems. 一般来说,不要抛弃问题。 Cast are rarely needed in C if all your headers are properly written. 如果正确编写了所有标头,则在C中很少需要进行强制转换。 Casting the return type of a system function is almost always wrong. 强制转换系统函数的返回类型几乎总是错误的。

Valigrind and GDB are your friend Valigrind和GDB是您的朋友

Please provide the entire code so we can compile it and help you out. 请提供完整的代码,以便我们进行编译并为您提供帮助。 Staring at source isn't a magic approach to debuggin :) 盯着源代码并不是调试的一种神奇方法:)

Ensure you are compiling with the debugging options (-g etc) on your compiler. 确保使用编译器上的调试选项(-g等)进行编译。

Otherwise, checkout valgrind's memcheck. 否则,请检查valgrind的memcheck。 When you have your compiled program, run: 编译了程序后,运行:

valgrind ./myprogram

And you may get output similar to the following: 并且您可能会获得类似于以下内容的输出:

==584== Use of uninitialised value of size 8
==584==    at 0x400480: segfaultme (p.c:6)
==584==    by 0x40049B: main (p.c:13)
==584== 
==584== Invalid write of size 4
==584==    at 0x400480: segfaultme (p.c:6)
==584==    by 0x40049B: main (p.c:13)
==584==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==584== 
==584== 
==584== Process terminating with default action of signal 11 (SIGSEGV)
==584==  Access not within mapped region at address 0x0
==584==    at 0x400480: segfaultme (p.c:6)
==584==    by 0x40049B: main (p.c:13)
==584==  If you believe this happened as a result of a stack
==584==  overflow in your program's main thread (unlikely but
==584==  possible), you can try to increase the size of the
==584==  main thread stack using the --main-stacksize= flag.
==584==  The main thread stack size used in this run was 10485760.

Crack out GDB with: 使用以下方法破解GDB:

gdb ./myprog then enter r return gdb ./myprog然后输入r 返回

And you will get some more information on exactly where the segfault occurs: 您将获得有关段错误发生确切位置的更多信息:

(gdb) r
Starting program: /home/aiden/tmp/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400480 in segfaultme (p=0x0) at p.c:6
6       *p = 22;
Missing separate debuginfos, use: debuginfo-install glibc-2.11.2-1.x86_64
(gdb) bt
#0  0x0000000000400480 in segfaultme (p=0x0) at p.c:6
#1  0x000000000040049c in main () at p.c:13

Entering b t return will give you a backtrace too. 输入b t return也将给您回溯。 In the above example we can see that line 6 of pc in segfaultme() where I dereference p is the problem, and it shows segfaultme() was called by main() . 在上面的示例中,我们可以看到segfaultme()pc第6行是我解引用p的问题,它表明segfaultme()main()调用了。

Hope this helps! 希望这可以帮助! Remember to get as much exposure to tools that help you! 记住要尽可能多地使用对您有帮助的工具!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM