協程踩坑記1

今天嘗試着使用ucontext來實現一個輕量級的協程庫,結果運行測試程序時,發生了段錯誤

通過gdb調試發現錯誤是Cannot access memory at address,不過這個信息對我的幫助太小

然後我加入了一些調試用的輸出語句,就找到了真正的錯誤原因:我在創建一個協程時,需要傳入一個執行函數,我對此函數進行了封裝,作爲makecontext的函數入口,這個封裝函數會在原函數執行完畢後,做一些善後工作,譬如釋放協程結構體佔用的內存;可笑的是,我把協程使用的stack作爲成員放入了這個結構體,那麼當協程在運行時,這個stack指向的內存會受到保護,而我嘗試去free它,那麼就報了以上錯誤

struct Coroutine {
    Scheduler *scher;
    CoFunc func;
    void *arg;
    int state;
    ucontext_t ctx;
    char stack[DEFAULT_STACK_SZIE];          ----------------------> 協程運行使用的棧
};

// makecontext的函數入口
static void _coroutine_entry(uintptr_t *arg) {
    Scheduler *s = (Scheduler *)arg;
    assert(s != NULL);
    int cid = s->running;
    assert(cid >= 0 && cid < s->capacity);
    Coroutine *co = s->cos[cid];
    co->func(co->arg);
    // coroutine done
    free(co);                                ----------------------> 出錯原因
    s->cos[cid] = NULL;
    s->running = -1;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章