Add to an array of structs using mmap

1

I would like to dispatch some tasks out via fork, and collect some information about the results of those tasks in an array.

My thought is to use mmap to share a data structure between the two, and have the child process update the array of structs with the result of the activity, but i'm having some issues.

#include <time.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>


typedef struct message_s {
    int status;
    char message[256];
} message_t;


void child(message_t **result) {


    result[0]->status = 2;
    sprintf((char *) &result[0]->message, "Hello World!");
    usleep(1);

}

void parent() {
    printf("Parent\n");
    usleep(1);
    return;
}


int main() {
    size_t result_size = 1000 * sizeof(message_t);


    message_t **result_ar = mmap(NULL, result_size,
                                 PROT_READ | PROT_WRITE,
                                 MAP_SHARED | MAP_ANON, -1, 0);


    pid_t child_pid = fork();

    switch (child_pid) {
        case 0:
            child(result_ar);
            exit(0);

        case -1:
            exit(-1);
            break;
        default:
            parent();
    }

    int child_status;
    waitpid(child_pid, &child_status, 0);


    printf("\nRESULT: %i: %s\n\n", result_ar[0]->status, result_ar[0]->message);

    msync(result_ar, result_size, MS_SYNC);
    munmap(result_ar, result_size);

    return 0;
}

I'm really sort of lost here, and while i can find "similar" questions on SO, they either do not have answers or are plagued with other issues, or both.

When the code above runs, i get the following concatenated result.

Process:               concurrent_test [2537]
Path:                  /Users/USER/Library/Caches/*/concurrent_test
Identifier:            concurrent_test
Version:               0
Code Type:             X86-64 (Native)
OS Version:            Mac OS X 10.10.5 (14F1509)
Report Version:        11

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000

VM Regions Near 0:
--> 
    __TEXT                 000000010144a000-000000010144c000 [    8K] r-x/rwx SM=COW  /Users/USER/Library/Caches/*

Application Specific Information:
crashed on child side of fork pre-exec

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   concurrent_test                 0x000000010144bb33 child + 35
1   concurrent_test                 0x000000010144bc1f main + 127
2   concurrent_test                 0x000000010144b5a9 _start + 247
3   concurrent_test                 0x000000010144b4b1 start + 33

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000000  rbx: 0x00007fff5e7b5908  rcx: 0x000000010144beb3  rdx: 0xffffffffffffffff
  rdi: 0x0000000000000000  rsi: 0x0000000000000000  rbp: 0x00007fff5e7b5730  rsp: 0x00007fff5e7b5720
   r8: 0x0000000000000303   r9: 0x0000000000000000  r10: 0x0000000000000030  r11: 0x0000000000000206
  r12: 0x00007fff5e7b57e0  r13: 0x0000000000000000  r14: 0x00007fff5e7b57f0  r15: 0x0000000000000001
  rip: 0x000000010144bb33  rfl: 0x0000000000010246  cr2: 0x0000000000000000

Logical CPU:     6
Error Code:      0x00000006
Trap Number:     14

And I'm using:

Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
c
arrays
fork
c99
mmap
asked on Stack Overflow Jan 9, 2016 by lscoughlin

1 Answer

2

You have one indirection too much in your code. Try message_t *result_ar = mmap(...); and result[0].status = 2; to fix this issue. Also, don't forget the error checking! mmap() can fail.

answered on Stack Overflow Jan 9, 2016 by fuz

User contributions licensed under CC BY-SA 3.0