-1

尝试编译我的程序时出现此错误:

Field '__jmpbuf' could not be resolved

我花了几个小时寻找解决方案,但似乎无法找出罪魁祸首。

Thread.h文件包含类的标题。它有私有成员:

sigjmp_buf _env;

实现在 Thread.cpp 中:

#include "Thread.h"
#include <setjmp.h>
#include "translateAdd.h"
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>

#define COUNTER_INIT -1

int Thread::_idCounter = COUNTER_INIT;

Thread::Thread(void (*threadsFunc)(void))
: threadsFunction(threadsFunc), _stack(new char[STACK_SIZE]), _quantums(1)
{
      address_t sp, pc;

      sp = (address_t)_stack + STACK_SIZE - sizeof(address_t);
      pc = (address_t)threadsFunc;
      // set environment for later return
      sigsetjmp(_env, 1);
      (_env->__jmpbuf)[JB_SP] = translate_address(sp);
      (_env->__jmpbuf)[JB_PC] = translate_address(pc);
      sigemptyset(&_env->__saved_mask);

    _id = ++_idCounter;

    _state = READY;

}

编辑:在 ubuntu 32bit 下使用 eclipse 作为 IDE

编辑:另一个无法在我的机器上编译的完整示例:

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>

#define SECOND 1000000
#define STACK_SIZE 4096

char stack1[STACK_SIZE];
char stack2[STACK_SIZE];

sigjmp_buf env[2];

#ifdef __x86_64__
/* code for 64 bit Intel arch */

typedef unsigned long address_t;
#define JB_SP 6
#define JB_PC 7

/* A translation is required when using an address of a variable.
   Use this as a black box in your code. */
address_t translate_address(address_t addr)
{
    address_t ret;
    asm volatile("xor    %%fs:0x30,%0\n"
        "rol    $0x11,%0\n"
                 : "=g" (ret)
                 : "0" (addr));
    return ret;
}

#else
/* code for 32 bit Intel arch */

typedef unsigned int address_t;
#define JB_SP 4
#define JB_PC 5 

/* A translation is required when using an address of a variable.
   Use this as a black box in your code. */
address_t translate_address(address_t addr)
{
    address_t ret;
    asm volatile("xor    %%gs:0x18,%0\n"
        "rol    $0x9,%0\n"
                 : "=g" (ret)
                 : "0" (addr));
    return ret;
}

#endif

void switchThreads(void)
{
  static int currentThread = 0;

  int ret_val = sigsetjmp(env[currentThread],1);
  printf("SWITCH: ret_val=%d\n", ret_val); 
  if (ret_val == 1) {
      return;
  }
  currentThread = 1 - currentThread;
  siglongjmp(env[currentThread],1);
}

void f(void)
{
  int i = 0;
  while(1){
    ++i;
    printf("in f (%d)\n",i);
    if (i % 3 == 0) {
      printf("f: switching\n");
      switchThreads();
    }
    usleep(SECOND);
  }
}

void g(void)
{
  int i = 0;
  while(1){
    ++i;
    printf("in g (%d)\n",i);
    if (i % 5 == 0) {
      printf("g: switching\n");
      switchThreads();
    }
    usleep(SECOND);
  }
}

void setup(void)
{
  address_t sp, pc;

  sp = (address_t)stack1 + STACK_SIZE - sizeof(address_t);
  pc = (address_t)f;
  sigsetjmp(env[0], 1);
  (env[0]->__jmpbuf)[JB_SP] = translate_address(sp);
  (env[0]->__jmpbuf)[JB_PC] = translate_address(pc);
  sigemptyset(&env[0]->__saved_mask);     

  sp = (address_t)stack2 + STACK_SIZE - sizeof(address_t);
  pc = (address_t)g;
  sigsetjmp(env[1], 1);
  (env[1]->__jmpbuf)[JB_SP] = translate_address(sp);
  (env[1]->__jmpbuf)[JB_PC] = translate_address(pc);
  sigemptyset(&env[1]->__saved_mask);         
}

int main(void)
{
  setup();      
  siglongjmp(env[0], 1);
  return 0;
}
4

1 回答 1

0

如果您确实需要使用内部字段(仅对系统上的编译器有效),您需要检查类型:

typedef struct __jmp_buf_tag sigjmp_buf[1];

这意味着它sigjmp_buf不是一个指针,而是一个包含单个结构的数组。因此,您可以像使用普通的结构数组一样使用它:

sigjmp_buf _env;

_env[0].__jmpbuf[x] = y;

我真的建议不要使用这个结构的内部字段。Linux具有其他功能来简化协作线程(您似乎正在实现)。

于 2013-04-14T08:26:36.497 回答