Execl возвращает неверный адрес - PullRequest
0 голосов
/ 09 января 2012

Я бы очень хотел помочь с отладкой.Я работаю над этим с утра и до 4 утра.(Я полагаю, что доставить это за 7 часов [11:00])

Все в main.c работает, но когда я создаю некоторые дочерние процессы для запуска скомпилированного файла compute.c с execl, он не делает этого и отправляетошибка "Bad Address".

Я прикрепил 3 ссылки на pastebin с main.c и compute.c и txt-файл, содержащий таблицы, которые я упомянул ниже.

Предполагается, что программапрочитайте 2 таблицы с целыми числами из файла с именем pinakes.txt, а затем с помощью API разделяемой памяти POSIX поместите эти таблицы в общую память и создайте процессы для вычисления из них суммы 'row * column' и помещения этой суммы в другую таблицу.

sum += A[row][i] * B[i][column] = C[row][column]

Все до тех пор, пока строка из main.c не будет работать должным образом (я неоднократно отлаживал).

ppid = getpid();

скомпилируйте и запустите

./main pinakes.txt

main.c

188 строк кода

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <errno.h>

int pinA_X = 0, pinA_Y = 0, pinB_X=0, pinB_Y=0;
int pinA[10][10], pinB[10][10], pinC[10][10];

main(int argc, char *argv[]){
    int pid, ppid;
    FILE *stream;
    // general variables
    int i, c, j, rc, converted, lines = 0;
    //flags
    int flagV=0, flagW=0, flagX=0, flagY=0, flagZ=0;

    //shared memory
    int dumpedArray[101];
    int size = sizeof(dumpedArray);
    int sid1 = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
    int sid2 = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
    int sid3 = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
    int* shared_A = (int*) shmat(sid1, NULL, 0);
    int* shared_B = (int*) shmat(sid2, NULL, 0);
    int* shared_C = (int*) shmat(sid3, NULL, 0);

    if(argc!=2){
        printf("wrong number of arguments\n");
        return -1;
    }else{
        stream = fopen(argv[1] , "r");
                while((c = getc(stream))!= EOF){
            if(flagZ == 0){
                if(flagX == 1){pinA_X = c - 48;flagX = 0;}
                if(c == 88){flagX = 1;}
                if(flagY == 1){pinA_Y = c - 48;flagY = 0;}
                if(c == 89){flagY = 1;}
                if(c == 90){flagZ = 1;}
            }else if(flagZ == 1){
                if(flagX == 1){pinB_X = c - 48;flagX = 0;}
                if(c == 88){flagX = 1;}
                if(flagY == 1){pinB_Y = c - 48;flagY = 0;}
                if(c == 89){flagY = 1;}
            }
        }

        fclose(stream);

        printf("pinA[%d][%d] * pinB[%d][%d] = C[%d][%d]\n\n", pinA_X, pinA_Y, pinB_X, pinB_Y, pinA_X, pinB_Y);

        // get A
        stream = fopen(argv[1] , "r");
        i=0;j=0;
        while((c = getc(stream))!= EOF){
            if(i <= pinA_X && j <= pinA_Y){
                if(flagW == 0){
                    if(c == 87){
                        flagW = 1;
                    }
                }else{
                    if(c > 47 && c < 58){
                        pinA[i][j] = c - 48;
                        j++;
                    }
                    if(c == 13){
                        j=0;
                        i++;
                    }
                }
            }
        }
        fclose(stream);

        // get B
        stream = fopen(argv[1] , "r");
        i=0;j=0;
        while((c = getc(stream))!= EOF){
            if(i <= pinB_X && j <= pinB_Y){
                if(flagV == 0){
                    if(c == 86){
                        flagV = 1;
                    }
                }else{
                    if(c > 47 && c < 58){
                        pinB[i][j] = c - 48;
                        j++;
                    }
                    if(c == 13){
                        j=0;
                        i++;
                    }
                }
            }
        }
        fclose(stream);

        // print A

        printf("A={\n");
        for(j=0; j<pinA_X;j++){
            for(i=0;i<pinA_Y;i++){
                printf(" %d", pinA[j][i]);
            }
            printf("\n");
        }
        printf("}\n\n");

        // print B

        printf("B={\n");
        for(j=0; j<pinB_X;j++){
            for(i=0;i<pinB_Y;i++){
                printf(" %d", pinB[j][i]);
            }
            printf("\n");
        }
        printf("}\n");

        // Save pinA to shared Memory
        converted = 0;

        for(i=0;i<10;i++){
            for(j=0;j<10;j++){
                converted = (i * 10) + j;
                shared_A[converted] = pinA[i][j];
            }
        }


        // Save pinA to shared Memory
        converted = 0;

        for(i=0;i<10;i++){
            for(j=0;j<10;j++){
                converted = (i * 10) + j;
                shared_B[converted] = pinB[i][j];
            }
        }

        // Push size of arrays in shared memory
        shared_A[100] = pinA_X;
        shared_A[101] = pinA_Y;
        shared_B[100] = pinB_X;
        shared_B[101] = pinB_Y;

        ppid = getpid();

        for(i=0; i<pinA_X; i++){
            for(j=0; j<pinB_Y; j++){
                if(ppid == getpid()){
                    pid = fork();
                    if(pid==0){
                        if(execl("./compute", "compute", i, j, sid1, sid2, sid3, NULL) == -1){
                            printf("error exec\n");
                            printf("Error opening file: %s\n", strerror(errno));
                        };
                    }else if(pid<0){
                        printf("\nDen egine h fork!\n");
                    }else{
                        wait(0);
                    }
                }
            }
        }

        //print C
        converted = 0;

        printf("C={\n");
        for(i=0;i<10;i++){
            for(j=0;j<10;j++){
                converted = (i * 10) + j;
                pinC[i][j] = shared_C[converted];
                printf(" %d", pinC[i][j]);
            }
            printf("\n");
        }
        printf("}\n");
    }
}

Ни compute.c, ни pintakes.txt не являетсяимеет непосредственное отношение к ответу на этот вопрос.

Ответы [ 2 ]

6 голосов
/ 09 января 2012

Проблема с неправильным адресом возникает из-за того, что вы запускаете:

for(i=0; i<pinA_X; i++){
    for(j=0; j<pinB_Y; j++){
        if(ppid == getpid()){
            pid = fork();
            if(pid==0){
                if(execl("./compute", "compute", i, j, sid1, sid2, sid3, NULL) == -1){

Аргументы для execl() должны быть строками; i и j явно не являются строками (а sid1, sid2 и sid3 являются идентификаторами для трех блоков разделяемой памяти).

Преобразуйте эти значения в строки и повторите попытку.

Ваша программа создает разделяемую память с помощью IPC_PRIVATE, поэтому ваш код в compute.c (который выполняется через execl() будет трудным для выполнения работы. Вы можете избежать передачи идентификаторов разделяемой памяти подобным образом; я я не уверен.

Думаю, я бы использовал один сегмент общей памяти.

Также выглядело, как будто ваш код чтения будет считывать одни и те же данные в два массива - но я, возможно, неправильно их прочитал.

Наконец, срок действия примеров PasteBin истекает через 23 часа. Это ограничивает полезность вашего вопроса. Вы должны действительно перенести данные в вопрос - я полагаю, что для вкладок и табуляции не установлено значение 8, а 8 (или используйте больше функций для предотвращения такого глубокого отступа.)

4 голосов
/ 09 января 2012

Вы передаете int s execl, все они должны быть строками с 0-символами.Кроме того, финал NULL должен быть приведен к Char*.

...