2016-04-15 15 views
1

Aus irgendeinem Grund erhalte ich einen Segmentierungsfehler, bevor irgendeiner meiner Codes tatsächlich in der main() -Funktion ausgeführt wird. Ich habe versucht, der Ausführungsreihenfolge zu folgen, indem ich printfs einfüge, aber nichts wird wirklich ausgeführt. Ich sehe nichts in meinem Programm, das einen Stapelüberlauf verursachen würde, da ich kaum Speicher verwende.Segmentierungsfehler, bevor main ausgeführt wird

Wenn jemand bessere Augen als ich hat und diesen Fehler entdecken kann, würde es sehr geschätzt werden!

Main:

#include "../inc/protos.h" 


HistogramData *histogram_data; 
bool signal_caught = false; 
sem_t *semaphore_id; 
int letter_count[kLetterCount] = { 0 }; 
int wait_time = 0; 

int main(void) 
{ 
    int shared_memory_id = 0; 
    key_t shared_memory_key = 0; 
    char buffer[kBufferLength] = { 0 }; 
    int heads = 0; 
    int tails = 0; 

    printf("1"); 

    histogram_data->signal_caught = false; 

    signal(SIGINT, signal_handler); 

    printf("2"); 

    //Get the key to the allocated shared memory 
    shared_memory_key = ftok("/tmp", 'M'); 
    if(shared_memory_key == -1) 
    { 
     printf("(CONSUMER) Cannot allocate key.\n"); 
     return 1; 
    } 

    printf("3"); 

    //Look for shared memory every 10 seconds until it finds it 
    while(true) 
    { 
     if((shared_memory_id = shmget(shared_memory_key, sizeof(histogram_data), 0)) == -1) 
     { 
      printf("4"); 
      printf("(CONSUMER) Shared Memory does not exist. Please run the Producer program.\n"); 

      sleep(kSleepTime); 
     } 
     else 
     { 
      printf("5"); 
      break; 
     } 
    } 

    printf("(CONSUMER) Our Shared Memory ID is %d.\n", shared_memory_id); 

    //Attach the structure to the shared memory 
    histogram_data = (HistogramData*) shmat(shared_memory_id, NULL, 0); 
    if(histogram_data == NULL) 
    { 
     printf("(CONSUMER) Cannot attach to Shared Memory.\n"); 
     return 3; 
    } 

    semaphore_id = sem_open("/HISTOGRAM_SEM", O_CREAT, S_IRUSR | S_IWUSR, 1); 

    signal(SIGALRM, alarm_handler); 

    //Set the watchdog timer to 2 seconds. 
    alarm(kAlarmSeconds); 

    //Detach from shared memory 
    shmdt(histogram_data); 

    return 0; 
} 



void signal_handler(int signal_number) 
{ 
    printf ("(CONSUMER) Received a signal. SIGINT ID is %d\n", signal_number); 

    histogram_data->signal_caught = true; 

    // Send SIGINT to Producer2 
    kill(histogram_data->producer2_pid, SIGINT); 

    // Send SIGINT to Producer1 
    kill(histogram_data->producer1_pid, SIGINT); 
} 


void print_line(int num) 
{ 
    int hundreds = num/100; 
    num = num % 100; 
    int tens = num/10; 
    num = num % 10; 
    int ones = num; 


    int i = 0; 
    for(i = 0; i < hundreds; i++) 
    { 
     printf("*"); 
    } 
    for(i = 0; i < tens; i++) 
    { 
     printf("+"); 
    } 
    for(i = 0; i < ones; i++) 
    { 
     printf("-"); 
    } 

    printf("\n"); 
} 


void display_histogram(int letter_count[]) 
{ 
    int i = 0; 

    printf("\n********** HISTOGRAM **********\n"); 
    for(i = 0; i < kLetterCount; i++) 
    { 
     printf("%c-%03d ", i + 65, letter_count[i]); 
     print_line(letter_count[i]); 
    } 
} 


void alarm_handler(int signal_number) 
{ 
    int wait_time = 0; 

    sem_wait(semaphore_id); 

    int i = 0; 
    for(i = 0; i < kDCReads; i++) 
    { 
     int* read_index = &histogram_data->read_index; 

     if(histogram_data->circular_buffer[*read_index] != 0) 
     { 
      int read_data = histogram_data->circular_buffer[*read_index]; 
      histogram_data->circular_buffer[*read_index] = 0; 
      ++letter_count[read_data - 65]; 

      if(*read_index == kCircleBufferSize) 
      { 
       *read_index = 0; 
      } 

      if(*read_index == histogram_data->write_index) 
      { 
       break; 
      } 
     } 
    } 

    if(signal_caught == true) 
    { 
     //Read and write indexes from the histogram data structure 
     int* read_index = &histogram_data->read_index; 
     int* write_index = &histogram_data->write_index; 

     //Read data from buffer 
     while(*read_index != *write_index) 
     { 
      if(histogram_data->circular_buffer[*read_index]) 
      { 
       //Data read in from the circular buffer 
       int read_data = histogram_data->circular_buffer[*read_index]; 

       //Mark element as read 
       histogram_data->circular_buffer[*read_index] = 0; 
       ++letter_count[read_data - 65]; 

       //Increment the elements 
       (*read_index)++; 
       if(*read_index == 256) 
       { 
        *read_index = 0; 
       } 
       if(*read_index == *write_index) 
       { 
        break; 
       } 
      } 
     } 

     //Display a histogram listing 
     display_histogram(letter_count); 
     return; 
    } 

    wait_time++; 
    if(wait_time >= 5) 
    { 
     wait_time = 0; 
     display_histogram(letter_count); 
    } 

    //Release semaphore lock 
    sem_post(semaphore_id); 

    //Set the alarm for the watchdog to be two seconds 
    alarm(kAlarmSeconds); 

    //Reactivate watchdog signal 
    signal(signal_number, alarm_handler); 
} 

protos.h:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdbool.h> 
#include <unistd.h> 
#include <time.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <fcntl.h> 
#include <signal.h> 
#include <semaphore.h> 

#define kCircleBufferSize 256 
#define kBufferLength 126 
#define kLetterCount 20 
#define kDCReads 60 
#define kAlarmSeconds 2 
#define kSleepTime 10 

typedef struct HistogramData HistogramData; 

struct HistogramData 
{ 
    int read_index; 
    int write_index; 
    int is_wrap_around; 
    pid_t producer1_pid; 
    pid_t producer2_pid; 

    char circular_buffer[kCircleBufferSize]; 

    bool signal_caught; 
}; 


void signal_handler(int signal_number); 
void print_line(int num); 
void display_histogram(int letter_count[]); 
void alarm_handler(int signal_number); 
+2

Setzen Sie eine 'newline' in jedes Debugging-Cue wie' printf ("1 \ n"); 'Dies stellt sicher, dass der Ausgabepuffer nicht verworfen wird, wenn der segfault auftritt. –

+1

run it with gdb –

+2

Wenn Sie printf verwenden müssen, setzen Sie 'fflush()' danach, um sicherzustellen, dass der Puffer an die Ausgabe gesendet wurde, bevor Sie fortfahren. – sabbahillel

Antwort

0

Sie erstellen histogram_data als Zeiger auf HistogramData, aber nicht schaffen ein HistogramData Objekt. Wenn Sie in Main dann histogram_data->signal_caught = false aufrufen, programmieren Sie Dereferenzierung einen Nullzeiger.
Reservieren Sie stattdessen Speicher für HistogramData, bevor Sie den Zeiger verwenden (z. B. histogram_data = malloc(sizeof *histogram_data);). Vergiss nicht, es später auch zu befreien.

+2

die OP hätte gefunden, wenn sie durch den Debugger laufen :(--- Gib einem Mann einen Fisch, yada yada yada – KevinDTimm

+0

Guter Fang, aber C nicht C++. –

+0

@Weather Vane, danke, aktualisiert. –

0

Aus irgendeinem Grund bekomme ich einen Segmentierungsfehler, bevor irgendeiner meiner Code tatsächlich in der main() -Funktion ausgeführt wird.

Eine der vorinstallierten Datenstrukturen verursacht wahrscheinlich einen Überlauf im Stapel. Sie haben auch eine Menge Pufferung auf die Ausgabe und zusätzlich haben Sie mehrere Stellen, an denen Sie printf() verwenden, aber nicht die Zeilenumbrüche \n anfügen, um den Konsolenpuffer zu leeren. Alternativ können Sie @ Sabbahillels Kommentar folgen, indem Sie fflush() nach Ihren printf() Aussagen setzen.

Verwandte Themen