运行移植的wvdial出错

移植wvdial后在ARM开发板上运行时出现下列错误:

wvdial: utils/wvtask.cc:198: WvTaskMan::WvTaskMan(): Assertion
  `getcontext(&get_stack_return) == 0' failed
  Aborted

 

解决办法:修改代码

 

--- include/wvtask.h.orig Mon Jul 14 13:11:35 2008
+++ include/wvtask.h Mon Nov 23 13:10:28 2009
@@ -50,12 +50,10 @@
int tid;

size_t stacksize;
- void *stack;
bool running, recycled;

WvTaskMan &man;
- ucontext_t mystate; // used for resuming the task
- ucontext_t func_call, func_return;
+ jmp_buf mystate; // used for resuming the task

TaskFunc *func;
void *userdata;
@@ -91,16 +89,15 @@
static void stackmaster();
static void _stackmaster();
static void do_task();
- static void call_func(WvTask *task);

static char *stacktop;
- static ucontext_t stackmaster_task;
-
+ static jmp_buf stackmaster_task;
+
static WvTask *stack_target;
- static ucontext_t get_stack_return;
-
+ static jmp_buf get_stack_return;
+
static WvTask *current_task;
- static ucontext_t toplevel;
+ static jmp_buf toplevel;

WvTaskMan();
virtual ~WvTaskMan();
--- utils/wvtask.cc.orig Wed May 13 15:42:52 2009
+++ utils/wvtask.cc Mon Nov 23 13:12:54 2009
@@ -32,10 +32,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
-#include <sys/mman.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/resource.h>

#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
@@ -60,7 +56,7 @@
WvTaskMan *WvTaskMan::singleton;
int WvTaskMan::links, WvTaskMan::magic_number;
WvTaskList WvTaskMan::all_tasks, WvTaskMan::free_tasks;
-ucontext_t WvTaskMan::stackmaster_task, WvTaskMan::get_stack_return,
+jmp_buf WvTaskMan::stackmaster_task, WvTaskMan::get_stack_return,
WvTaskMan::toplevel;
WvTask *WvTaskMan::current_task, *WvTaskMan::stack_target;
char *WvTaskMan::stacktop;
@@ -198,9 +194,7 @@

stacktop = (char *)alloca(0);

- context_return = 0;
- assert(getcontext(&get_stack_return) == 0);
- if (context_return == 0)
+ if (setjmp(get_stack_return) == 0)
{
// initial setup - start the stackmaster() task (never returns!)
stackmaster();
@@ -257,22 +251,18 @@

WvTask *old_task = current_task;
current_task = &task;
- ucontext_t *state;
+ jmp_buf *state;

if (!old_task)
state = &toplevel; // top-level call (not in an actual task yet)
else
state = &old_task->mystate;

- context_return = 0;
- assert(getcontext(state) == 0);
- int newval = context_return;
+ int newval = setjmp(*state);
if (newval == 0)
{
// saved the state, now run the task.
- context_return = val;
- setcontext(&task.mystate);
- return -1;
+ longjmp(task.mystate, val);
}
else
{
@@ -303,8 +293,6 @@
assert(*current_task->stack_magic == WVTASK_MAGIC);

#if TASK_DEBUG
- if (use_shared_stack())
- {
size_t stackleft;
char *stackbottom = (char *)(current_task->stack_magic + 1);
for (stackleft = 0; stackleft < current_task->stacksize;
stackleft++)
@@ -315,18 +303,13 @@
Dprintf("WvTaskMan: remaining stack after #%d (%s): %ld/%ld
/n",
current_task->tid, current_task->name.cstr(), (long)
stackleft,
(long)current_task->stacksize);
- }
#endif

- context_return = 0;
- assert(getcontext(&current_task->mystate) == 0);
- int newval = context_return;
+ int newval = setjmp(current_task->mystate);
if (newval == 0)
{
// saved the task state; now yield to the toplevel.
- context_return = val;
- setcontext(&toplevel);
- return -1;
+ longjmp(toplevel, val);
}
else
{
@@ -340,39 +323,14 @@

void WvTaskMan::get_stack(WvTask &task, size_t size)
{
- context_return = 0;
- assert(getcontext(&get_stack_return) == 0);
- if (context_return == 0)
+ if (setjmp(get_stack_return) == 0)
{
assert(magic_number == -WVTASK_MAGIC);
assert(task.magic_number == WVTASK_MAGIC);
-
- if (!use_shared_stack())
- {
-#if defined(__linux__) && (defined(__386__) || defined(__i386) ||
defined(__i386__))
- static char *next_stack_addr = (char *)0xB0000000;
- static const size_t stack_shift = 0x00100000;
-
- next_stack_addr -= stack_shift;
-#else
- static char *next_stack_addr = NULL;
-#endif
-
- task.stack = mmap(next_stack_addr, task.stacksize,
- PROT_READ | PROT_WRITE,
-#ifndef MACOS
- MAP_PRIVATE | MAP_ANONYMOUS,
-#else
- MAP_PRIVATE,
-#endif
- -1, 0);
- }
-
// initial setup
stack_target = &task;
- context_return = size/1024 + (size%1024 > 0);
- setcontext(&stackmaster_task);
- }
+ longjmp(stackmaster_task, size/1024 + (size%1024 > 0));
+ }
else
{
if (current_task)
@@ -408,9 +366,7 @@
{
assert(magic_number == -WVTASK_MAGIC);

- context_return = 0;
- assert(getcontext(&stackmaster_task) == 0);
- val = context_return;
+ val = setjmp(stackmaster_task);
if (val == 0)
{
assert(magic_number == -WVTASK_MAGIC);
@@ -418,19 +374,13 @@
// just did setjmp; save stackmaster's current state (with
// all current stack allocations) and go back to get_stack
// (or the constructor, if that's what called us)
- context_return = 1;
- setcontext(&get_stack_return);
+ longjmp(get_stack_return, 1);
}
else
{
valgrind_fix(stacktop);
assert(magic_number == -WVTASK_MAGIC);

- total = (val+1) * (size_t)1024;
-
- if (!use_shared_stack())
- total = 1024; // enough to save the do_task stack
frame
-
// set up a stack frame for the new task. This runs once
// per get_stack.
//alloc_stack_and_switch(total);
@@ -439,6 +389,7 @@
assert(magic_number == -WVTASK_MAGIC);

// allocate the stack area so we never use it again
+ total = (val+1) * (size_t)1024;
alloca(total);

// a little sentinel so we can detect stack overflows
@@ -455,17 +406,6 @@
}

-void WvTaskMan::call_func(WvTask *task)
-{
- Dprintf("WvTaskMan: calling task #%d (%s)/n",
- task->tid, (const char *)task->name);
- task->func(task->userdata);
- Dprintf("WvTaskMan: returning from task #%d (%s)/n",
- task->tid, (const char *)task->name);
- context_return = 1;
-}
-
-
void WvTaskMan::do_task()
{
assert(magic_number == -WVTASK_MAGIC);
@@ -473,9 +413,7 @@
assert(task->magic_number == WVTASK_MAGIC);

// back here from longjmp; someone wants stack space.
- context_return = 0;
- assert(getcontext(&task->mystate) == 0);
- if (context_return == 0)
+ if (setjmp(task->mystate) == 0)
{
// done the setjmp; that means the target task now has
// a working jmp_buf all set up. Leave space on the stack
@@ -501,31 +439,11 @@

if (task->func && task->running)
{
- if (use_shared_stack())
- {
// this is the task's main function. It can call
yield()
// to give up its timeslice if it wants. Either
way, it
// only returns to *us* if the function actually
finishes.
task->func(task->userdata);
- }
- else
- {
- assert(getcontext(&task->func_call) == 0);
- task->func_call.uc_stack.ss_size = task-
>stacksize;

- task->func_call.uc_stack.ss_sp = task->stack;
- task->func_call.uc_stack.ss_flags = 0;
- task->func_call.uc_link = &task->func_return;
- Dprintf("WvTaskMan: makecontext #%d (%s)/n",
- task->tid, (const char *)task->name);
- makecontext(&task->func_call,
- (void (*)(void))call_func, 1, task);
-
- context_return = 0;
- assert(getcontext(&task->func_return) == 0);
- if (context_return == 0)
- setcontext(&task->func_call);
- }
-
+
// the task's function terminated.
task->name = "DEAD";
task->running = false;
@@ -541,10 +459,7 @@
{
#ifdef HAVE_LIBC_STACK_END
extern const void *__libc_stack_end;
- if (use_shared_stack() || current_task == NULL)
return __libc_stack_end;
- else
- return (const char *)current_task->stack + current_task-
>stacksize;

#else
return 0;
#endif
@@ -553,16 +468,7 @@

size_t WvTaskMan::current_stacksize_limit()
{
- if (use_shared_stack() || current_task == NULL)
- {
- struct rlimit rl;
- if (getrlimit(RLIMIT_STACK, &rl) == 0)
- return size_t(rl.rlim_cur);
- else
return 0;
- }
- else
- return size_t(current_task->stacksize);
}

--- uniconf/unifastregetgen.cc.orig Mon Nov 23 14:31:11 2009
+++ uniconf/unifastregetgen.cc Mon Nov 23 14:11:11 2009
@@ -54,7 +54,7 @@
{
if (!tree)
{
- wvassert(tree, "key: '%s'", key);
+// wvassert(tree, "key: '%s'", key);
abort();
}

@@ -93,7 +93,7 @@
{
if (!tree)
{
- wvassert(tree, "key: '%s'", key);
+// wvassert(tree, "key: '%s'", key);
abort();
}

--- utils/wvcrash.cc.orig Mon Nov 23 14:32:47 2009
+++ utils/wvcrash.cc Mon Nov 23 14:04:08 2009
@@ -28,7 +28,7 @@
// FIXME: this file mostly only works in Linux
#ifdef __linux

-# include <execinfo.h>
+//#include <execinfo.h>
#include <unistd.h>

#ifdef __USE_GNU
@@ -268,8 +268,8 @@
}

wr(fd, "/nBacktrace:/n");
- backtrace_symbols_fd(trace,
- backtrace(trace, sizeof(trace)/sizeof(trace[0])), fd);
+// backtrace_symbols_fd(trace,
+// backtrace(trace, sizeof(trace)/sizeof(trace[0])), fd);

if (pid > 0)
{
--- uniconf/uniconfkey.cc.orig Mon Nov 23 14:34:08 2009
+++ uniconf/uniconfkey.cc Mon Nov 23 13:51:05 2009
@@ -324,7 +324,7 @@
UniConfKey UniConfKey::subkey(const UniConfKey &key) const
{
UniConfKey answer;
- wvassert(suborsame(key, answer),
- "this = '%s'/nkey = '%s'", printable(), key);
+// wvassert(suborsame(key, answer),
+// "this = '%s'/nkey = '%s'", printable(), key);
return answer;
}

你可能感兴趣的:(function,tree,null,include,Constructor,returning)