2016-04-15 10 views
1

何らかの理由で、セグメンテーションフォルトが発生する前に、main()関数で実際にコードが実行されます。私はprintfsを入れて実行の行に従ってみましたが、実際には何も実行されません。スタックオーバーフローの原因となるプログラムの中には、メモリをほとんど使用していないものはありません。メインが実行される前のセグメンテーションフォルト

誰かが私よりも目がよく、このエラーを見つけることができれば非常に感謝しています!

メイン:

#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

'printf(" 1 \ n ");'のような各デバッグキューに 'newline'を入れて、segfaultが発生したときに出力バッファが破棄されないようにします。 –

+1

gdbで実行する –

+2

printfを使用する必要がある場合は、続行する前にバッファが出力に送られていることを確認するために 'fflush()'を置いてください。 – sabbahillel

答えて

0

あなたはHistogramDataへのポインタとしてhistogram_data作成しますが、HistogramDataオブジェクトを作成しないでください。次に、メインでhistogram_data->signal_caught = falseを呼び出すと、NULLポインタを参照解除します。
代わりに、ポインタを使用する前にHistogramDataのメモリを割り当てます(たとえば、histogram_data = malloc(sizeof *histogram_data);)。後でそれを解放することも忘れないでください。

+2

オペレータがデバッガを実行しているときに見つけたと思われるもの:(---人間に魚を与える、yada yada yada – KevinDTimm

+0

良いキャッチだがC言語でないC++。 –

+0

@Weather Vane、ありがとう、更新済み –

0

私のコードが実際にmain()関数で実行される前に、何らかの理由でセグメンテーション違反が発生しています。

プリロードされたデータ構造の1つが、スタックにオーバーフローを引き起こしている可能性があります。出力にはバッファリングがたくさんありますが、さらにprintf()を使用するいくつかの場所がありますが、改行\nを追加してコンソールバッファをフラッシュしないでください。また、printf()のステートメントの後に@と書いて@ sabbahillelのコメントに従うこともできます。

関連する問題