Обратный вызов, выбрасывающий segfault из общего объекта - PullRequest
1 голос
/ 23 мая 2011

Насколько я понимаю, когда мой .so загружается с использованием dlopen, общий объект отображается в адресном пространстве вызывающего процесса.Я могу вызывать функции и обращаться к глобальным переменным .so без ошибок.Однако всякий раз, когда я передаю функции .so указатель обратного вызова на функцию в основной программе, происходит следующее:

  • Функция .so попадает в стек вызовов, как и ожидалось.
  • Адрес обратного вызова изменяется с 0x400F09 (как видно в основной программе) на 0x6052A0 (как видно в .so).
  • Когда я пытаюсь вызвать обратный вызов, возникает ошибка.

Это какая-то фундаментальная проблема с отображением памяти или есть что-то более хитрое в движении?

Спасибо.


Редактировать:

Здесьэто оскорбительный кодВ основной программе:

static unsigned char      innerFunc_1(unsigned char      x) { return x+1; }
static unsigned short     innerFunc_2(unsigned short     x) { return x+1; }
static unsigned int       innerFunc_4(unsigned int       x) { return x+1; }
static unsigned long long innerFunc_8(unsigned long long x) { return x+1; }

static void *restrict innerFuncs[] =
{
    innerFunc_1,
    innerFunc_2,
    innerFunc_4,
    innerFunc_8
};

typedef void(*IterFunc)(void *context, void *innerFunc);

static IterFunc *restrict fptrIter;

// ...

fptrIter[fptrIterOffset()] = dlsym(libhandle, name);

// ...

unsigned (*fptrInner)(unsigned) = innerFuncs[dimElmSize.index];
fptrInner(10); // does not segfault
fptrIter[fptrIterOffset()](pcontext, fptrInner);

В .so:

typedef unsigned (*InnerFunc_4)(unsigned x);

void iter_pointstoarray_4_1loop_lrud
    (InnerFunc_4 innerFunc)
{
    innerFunc(0); // Segfaults
}

1 Ответ

1 голос
/ 28 мая 2011

Оказывается, внутренняя функция имела неправильный прототип функции.Исправление прототипа и способ, которым он был назван, исправили ошибку.Такова опасность компиляции вещей таким образом, что они не могут быть тщательно проверены компилятором.

...