Mam na rynku aplikację NDK i otrzymałem natywny raport o awarii dotyczący sygnału SIGILL. (Używam google breakpad do generowania natywnych raportów o awariach.) Oto szczegóły:

  • Moja aplikacja jest skompilowana dla armeabi-v7a, z obsługą NEON.
  • Uszkodził się na procesorze NVIDIA Tegra 2, czyli ARM-7 (Cortex-A9).
  • Zdarza się za każdym razem. (skontaktował się z użytkownikiem)
  • Adres awarii był w 0x399cc, sygnał był SIGILL i jest w moim kodzie.

Rejestry i demontaż:

 r4 = 0x001d50f0    r5 = 0x001d50f0    r6 = 0x598e2a3c    r7 = 0x00000000
 r8 = 0x00000001    r9 = 0x001c22b0   r10 = 0x00000000    fp = 0x81216264
 sp = 0x598e2a18    lr = 0x816399cb    pc = 0x816399cc

0x000399c6 <_ZN8Analyzer15setExpAvgFactorEi+22>:    blx 0x30508
0x000399ca <_ZN8Analyzer15setExpAvgFactorEi+26>:    fconstd d16, #7
0x000399ce <_ZN8Analyzer15setExpAvgFactorEi+30>:    vldr    d17, [pc, #32]  ; 0x399f2 <_ZN8Analyzer15setExpAvgFactorEi+66>

Pełne źródło i asembler dostępne tutaj (jest krótki, w zasadzie 2 linijki C++).

Możesz zobaczyć, że 0x399cc znajduje się w środku instrukcji fconstd. Według arm.com ta instrukcja została dodana w VFP-v3, która powinna (chyba) być dostępna w każdym nowoczesnym procesorze.

Co się dzieje? Czy fakt, że adres znajduje się w środku instrukcji, wskazuje gdzieś na uszkodzony wskaźnik? (Zauważ, że śledzenie wsteczne ma sens, więc nie jest tak, że ta funkcja została w jakiś sposób wywołana przez przypadek.) A może jest to coś innego?

10
tmandry 18 sierpień 2011, 09:03
FWIW, oficjalną, pozornie wyglądającą odpowiedź firmy NVIDIA dotyczącą obsługi VFPv3 na Tegra 2, można znaleźć tutaj. (Spoiler: tak, więc osoby, które uważają to za problem, ponieważ VFPv3 jest oznaczony jako „opcjonalny” w serii Cortex-A9, powinny szukać dalej.) developer.nvidia.com/tegra/forum/does-tegra-2-support-vfpv3
 – 
Jay Freeman -saurik-
18 sierpień 2011, 11:56
Jeśli chodzi o Google Breakpad na Androida, jest otwarte pytanie na ten temat, jeśli chcesz kilka łatwych punktów :) stackoverflow.com/questions/9752759/…
 – 
olafure
17 marzec 2012, 23:15

2 odpowiedzi

Najlepsza odpowiedź

Ok, rozumiem: NVIDIA Tegra 2 ma tylko 16 64-bitowych rejestrów GPU, dlatego aby ją ustawić, musisz skompilować ją za pomocą -mfpu=vfpv3-d16. Instrukcja, o której mowa, używa rejestru d16, który jest "po prostu za dużo". :(

Oto odniesienie do forum firmy NVIDIA, na którym pracownik wspomina o tym ograniczeniu: http:// developer.nvidia.com/tegra/forum/optimal-performance-guidelines

16
Jay Freeman -saurik- 18 sierpień 2011, 12:00
Otóż ​​to. Nie obsługuje również instrukcji NEON. Teraz pytanie brzmi... czy można bezpiecznie założyć, że wszystkie armeabi-v7a procesory obsługują vfpv3-d16? I czy można skorzystać z FPU, nadal określając -mfloat-abi=softfp (wymagane dla Androida?)
 – 
tmandry
18 sierpień 2011, 21:08
5
Prawie już wcześniej zamieściłem odniesienie do strony projektu Debian ARMEL, ale twierdzili, że "vfpv3-d16" jest dobrym "wspólnym mianownikiem". Ponadto (to samo odniesienie), softfp pozwala kompilatorowi „dokonywać mądrych wyborów dotyczących tego, kiedy i czy generuje emulowane lub rzeczywiste instrukcje FPU w zależności od wybranego typu FPU”, więc wydaje się, że tak: będziesz mógł skorzystać z FPU z tę flagę. wiki.debian.org/ArmHardFloatPort/VfpComparison
 – 
Jay Freeman -saurik-
19 sierpień 2011, 02:10
1
Aby zapewnić dodatkowy kontekst odpowiedzi Jaya, obsługa NEON wymaga 32 rejestrów FPU (patrz uwagi w $NDK/platforms/android-14/arch-arm/usr/include/machine/cpu-features.h). Tegra 2 jest jednym z niewielu urządzeń ARM na wolności z zestawem instrukcji ARMv7a, ale bez obsługi NEON. I tak, ARMv7a nakazuje VFPv3-D16.
 – 
bleater
28 luty 2013, 05:54

Spróbuj umieścić *.so w folderze o nazwie 'externallibs' i użyj go do budowania przez ndk-build, po skopiowaniu i wklejeniu *.so w folderze armeabi-v7a. To pomaga mi. Innym rozwiązaniem jest usunięcie wspornika Neon, jeśli jest to możliwe

0
ZanoOnStack 18 lipiec 2013, 16:55