Android NDK: вызов System.loadLibrary приводит к коду SIGSEGV = 1

У меня есть огромная библиотека C / C ++, которую я пытаюсь использовать через JNI для проекта Android. Он состоит из нескольких классов, которые изначально были написаны для MFC, и мы перенесли их для выполнения в среде Android.

Библиотека собирается нормально (по крайней мере, согласно ndk-build). Размер библиотеки составляет 56 МБ.

Когда я вызываю System.loadLibrary, приложение завершается с записью следующего:

Фатальный сигнал 11 (SIGSEGV) в 0x00000004 (код = 1), нить 16123

Я выполнил objdump в своей библиотеке, и на 0004 ничего нет. Вот первые несколько строк дампа:

DYNAMIC SYMBOL TABLE:
00000000      DF *UND*  00000000 __cxa_finalize
002fe600 g    D  .bss   00000000 __dso_handle
002f1e9c g    D  .init_array    00000000 __INIT_ARRAY__
002f20a4 g    D  .fini_array    00000000 __FINI_ARRAY__
0011dc58 g    DF .text  000000ec WideToJava
00000000      DF *UND*  00000000 __android_log_print
0021f460 g    DF .text  00000030 wcslen
00000000      DF *UND*  00000000 malloc
00000000      DF *UND*  00000000 free
0011dd44 g    DF .text  000000e4 WideToJava2
0011de28 g    DF .text  0000004e JavaToWSZ
0027443c g    DF .text  0000001c _Znaj
0011dec4  w   DF .text  00000018

Затем я выполнил readelf, чтобы посмотреть, есть ли другая библиотека, которую нужно загрузить, перечисленная здесь:

Dynamic section at offset 0x2d99e0 contains 28 entries:
Tag        Type                         Name/Value
0x00000003 (PLTGOT)                     0x2fe464
0x00000002 (PLTRELSZ)                   776 (bytes)
0x00000017 (JMPREL)                     0x11d4a0
0x00000014 (PLTREL)                     REL
0x00000011 (REL)                        0x107770
0x00000012 (RELSZ)                      89392 (bytes)
0x00000013 (RELENT)                     8 (bytes)
0x6ffffffa (RELCOUNT)                   11169
0x00000006 (SYMTAB)                     0x128
0x0000000b (SYMENT)                     16 (bytes)
0x00000005 (STRTAB)                     0x31cd8
0x0000000a (STRSZ)                      791389 (bytes)
0x00000004 (HASH)                       0xf3038
0x00000001 (NEEDED)                     Shared library: [liblog.so]
0x00000001 (NEEDED)                     Shared library: [libandroid.so]
0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
0x00000001 (NEEDED)                     Shared library: [libm.so]
0x00000001 (NEEDED)                     Shared library: [libc.so]
0x00000001 (NEEDED)                     Shared library: [libdl.so]
0x0000000e (SONAME)                     Library soname: [libCSEntry.so]
0x00000019 (INIT_ARRAY)                 0x2f1e9c
0x0000001b (INIT_ARRAYSZ)               520 (bytes)
0x0000001a (FINI_ARRAY)                 0x2f20a4
0x0000001c (FINI_ARRAYSZ)               12 (bytes)
0x00000016 (TEXTREL)                    0x0
0x00000010 (SYMBOLIC)                   0x0
0x0000001e (FLAGS)                      SYMBOLIC TEXTREL
0x00000000 (NULL)                       0x0

Затем я добавил эти библиотеки перед вызовом loadLibrary:

public class ApplicationInterface
{
static
{
System.loadLibrary("log");
System.loadLibrary("android");
System.loadLibrary("stdc++");
System.loadLibrary("m");
System.loadLibrary("c");
System.loadLibrary("dl");
// when i call load library it blows up
System.loadLibrary("CSEntry");
}
// code
}

Что более странно, так это то, что существует определенный класс, который взрывает этот код. Когда я закомментировал конструктор для этого класса, библиотека загружается нормально. Я проверил, что конструктор существует в результирующей библиотеке, используя objdump. Затем я продолжил закомментировать код в конструкторе, и он тоже не работает. Вот оскорбительный код в C ++:

// Code
m_pPifFile = new CNPifFile(sPifFilePath);

m_pPifFile->SetAppType(ENTRY_TYPE);
m_pPifFile->SetAppFName(sApplicationFilename);
m_pPifFile->SetBinaryLoad(true);

// load the PIF file
if(m_pPifFile->LoadPifFile())
{
// PIF file loaded create a new Run App
// the offending line
m_pRunAplEntry = new CRunAplEntry(m_pPifFile);
// Code

RunAplEntry.h

class AFX_EXT_CLASS CRunAplEntry : public CRunApl
{
public:
CRunAplEntry(CNPifFile* pPifFile);
~CRunAplEntry();

// code
};

RunApl.h

class CLASS_DECL_ZBRIDGEO CRunApl : public CObject
{
public:
CRunApl();
virtual ~CRunApl();
// code
};

AFX_EXT_CLASS и CLASS_DECL_ZBRIDGEO # определены для пустого пространства.

Мы написали CObject, эквивалентный для Android NDK.

Вот make-файлы:

Application.mk

# set the platform to the latest processor type
APP_ABI                 := armeabi-v7a
# build for GNU STL
APP_STL                 := gnustl_static
# turn on exceptions and runtime type info
APP_CPPFLAGS            += -fexceptions -frtti

Android.mk

LOCAL_LDLIBS            := -llog -landroid $(BOOST_LIBS) -lgnustl_static
LOCAL_LDFLAGS           := -L$(BOOST_PATH)/lib/arm
LOCAL_CFLAGS            := -D__GLIBC__=1
LOCAL_CFLAGS            += -D_GLIBCXX_USE_C99_MATH=1
LOCAL_CFLAGS            += -DUNICODE=1
LOCAL_CFLAGS            += -D_UNICODE=1
LOCAL_CFLAGS            += -DGENERATE_BINARY=1
LOCAL_CFLAGS            += -DUSE_BINARY=1
LOCAL_CFLAGS            += -DPORTABLE=1
LOCAL_CFLAGS            += -fpermissive
LOCAL_CFLAGS            += $(CSPROMOBILE_INCLUDE)
LOCAL_STATIC_LIBRARIES  := Engine zTbdO zFormO zDictO zToolsO zUtilO zCommonO

Я заметил, что компилятор GCC не очень хорошо обрабатывает виртуальные функции, и я подозреваю, что это может быть проблемой, но я не уверен. Вот детали для моего окружения.

НДК: Crystax r75
Цель ABI: 4.6.3
ADT: v21.0.1-543035
Отладочное устройство: Nexus 7

Любая помощь будет оценена.

Если у вас есть дополнительная информация, пожалуйста, не стесняйтесь спрашивать.

Спасибо,
Будет

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]