Exemplo n.º 1
0
static void command_get_signal_list(char * token, Channel * c) {
    int err = 0;
    char id[256];
    pid_t pid;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    pid = id2pid(id, NULL);
    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    /* pid is ignored, same signal list for all */

    write_errno(&c->out, err);
    if (err) {
        write_stringz(&c->out, "null");
    }
    else {
        int i = 0;
        int n = 0;
        write_stream(&c->out, '[');
        for (i = 0; i < 32; i++) {
            char * name = signal_name(i);
            char * desc = signal_description(i);
            if (name != NULL || desc != NULL) {
                if (n > 0) write_stream(&c->out, ',');
                write_stream(&c->out, '{');
                json_write_string(&c->out, "Index");
                write_stream(&c->out, ':');
                json_write_long(&c->out, i);
                if (name != NULL) {
                    write_stream(&c->out, ',');
                    json_write_string(&c->out, "Name");
                    write_stream(&c->out, ':');
                    json_write_string(&c->out, name);
                }
                if (desc != NULL) {
                    write_stream(&c->out, ',');
                    json_write_string(&c->out, "Description");
                    write_stream(&c->out, ':');
                    json_write_string(&c->out, desc);
                }
                write_stream(&c->out, ',');
                json_write_string(&c->out, "Code");
                write_stream(&c->out, ':');
                json_write_ulong(&c->out, signal_code(i));
                write_stream(&c->out, '}');
                n++;
            }
        }
        write_stream(&c->out, ']');
        write_stream(&c->out, 0);
    }

    write_stream(&c->out, MARKER_EOM);
}
Exemplo n.º 2
0
/* This function is the SIGSEGV handler for the virtual memory system.  If the
 * faulting address is within the user-space virtual memory pool then this
 * function responds appropriately to allow the faulting operation to be
 * retried.  If the faulting address falls outside of the virtual memory pool
 * then the segmentation fault is reported as an error.
 *
 * While a SIGSEGV is being processed, SIGALRM signals are blocked.  Therefore
 * a timer interrupt will never interrupt the segmentation-fault handler.
 */
static void sigsegv_handler(int signum, siginfo_t *infop, void *data) {
    void *addr;
    page_t page;

    /* Only handle SIGSEGVs addresses in range */
    addr = infop->si_addr;
    if (addr < vmem_start || addr >= vmem_end) {
        fprintf(stderr, "segmentation fault at address %p\n", addr);
        abort();
    }

    num_faults++;

    /* Figure out what page generated the fault. */
    page = addr_to_page(addr);
    assert(page < NUM_PAGES);

#if VERBOSE
    fprintf(stderr,
        "================================================================\n");
    fprintf(stderr, "SIGSEGV:  Address %p, Page %u, Code %s (%d)\n",
           addr, page, signal_code(infop->si_code), infop->si_code);
#endif

    /* We really can't handle any other type of code.  On Linux this should be
     * fine though.
     */
    assert(infop->si_code == SEGV_MAPERR || infop->si_code == SEGV_ACCERR);

    /* Map the page into memory so that the fault can be resolved.  Of course,
     * this may result in some other page being unmapped.
     */

    /* Handle unmapped address (SEGV_MAPERR). */
    if (infop->si_code == SEGV_MAPERR) {
        /* Evict a page. */
        assert(num_resident <= max_resident);
        if (num_resident == max_resident) {
            page_t victim = choose_victim_page();
            assert(is_page_resident(victim));
            unmap_page(victim);
            assert(!is_page_resident(victim));
        }

        /*
         * There should now be space, so load the new page. No permissions
         * initially.
         */
        assert(num_resident < max_resident);
        map_page(page, PAGEPERM_NONE);
    }

    /* Handle unpermitted access (SEGV_ACCERR). */
    else {
        /* Regardless of attempted read or write, it is now accessed. */
        set_page_accessed(page);
        assert(is_page_accessed(page));

        switch(get_page_permission(page)) {
            case PAGEPERM_NONE:
                /*
                 * Tried to read or write. Give read access, if it was a write
                 * then it will segfault again and read-write access will be
                 * given then.
                 */
                set_page_permission(page, PAGEPERM_READ);
                break;
            case PAGEPERM_READ:
                /* Tried to write, so make it read-write access. */
                set_page_permission(page, PAGEPERM_RDWR);
                /* Since it is a write it is also dirty. */
                set_page_dirty(page);
                assert(is_page_dirty(page));
                break;
            case PAGEPERM_RDWR:
                fprintf(stderr, "sigsegv_handler: got unpermitted access error \
                    on page that already has read-write permission.\n");
                abort();
                break;
        }
    }
}