到目前为止,我已经查看了大约15次但无济于事。我不明白为什么这是断层错误?它甚至没有得到“印刷”声明,这是没有意义的。错误代码实际上工作(当我没有共享内存时)我有一个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
#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);
答案 0 :(得分:3)
您的问题可能来自您使用shmat
。在C中,永远不要转换这种函数的返回类型。您觉得需要它可能意味着您有一个虚假的错误消息来自您缺少“sys / shm.h”标头的事实。
在这种情况下会发生的事情是gcc采用int
的返回类型,通常是32位数量,并将其重新解释为指针。因此shmat
给你的地址的上半部分丢失了。
作为一般规则,不要抛弃问题。如果所有标题都已正确写入,则很少需要在C中进行强制转换。转换系统函数的返回类型几乎总是错误的。
答案 1 :(得分:2)
Valigrind和GDB是你的朋友
请提供完整的代码,以便我们编译并帮助您。盯着源代码并不是一种神奇的调试方法:)
确保使用编译器上的调试选项(-g etc)进行编译。
否则,结账valgrind的memcheck。如果有已编译的程序,请运行:
valgrind ./myprogram
您可能会得到类似于以下内容的输出:
==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.
使用以下方法破解GDB:
gdb ./myprog
然后输入 r return
您将获得有关segfault发生位置的更多信息:
(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
输入 b t return 也会给你一个回溯。在上面的示例中,我们可以看到p.c
中segfaultme()
的第6行,其中我解除引用p
是问题所在,它显示segfaultme()
被main()
调用
希望这有帮助!请记住尽可能多地接触可以帮助您的工具!