Użyłem następującej arytmetyki it out:
slide
+ stack address
- load address
= symbol address
i
stack address
jest wartość hex otrzymuję od mojego stos zrzutu raportu katastrofy (a nie polecenie .crash plik, tylko zrzut stosu).
i
slide
jest vmaddr z cmd LC_SEGMENT gdy uruchomiony otool -arch armv7 -l APP_BINARY_PATH
. Mój zwykle kończy się jako 0x00001000.
i
load address
jest skomplikowany utwór. W rzeczywistości jest to różnica między najniższym adresem stosu głównego wątku i PIERWSZYM adresem części mojego pliku binarnego, która zawiera symbole podczas uruchamiania dwarfdump --arch armv7 --all DSYM_BINARY_PATH
. Jest to po prostu symboliczny adres funkcji main
. Więc jeśli twój najniższy adres awarii to 0x8000, a twój symboliczny adres głównej funkcji to 0x2000, twój load address
to 0x6000.
Teraz za pomocą WSZYSTKICH tych elementów mogę obliczyć adres symbolu i umieścić go w atos lub dwarfdump: dwarfdump --lookup SYM_ADDR --arch armv7 APP_BINARY_PATH
.
Przykład zrzutu (widać, że load address
był 0x00003af4):
----------------------------------------------------------------------
Plik: /Users/user/Desktop/MyApp.xcarchive/dSYMs/MyApp.app.dSYM/Zawartość/zasoby/KARŁOWATA/MojaApl (ARMv7)
----------------------------------------------------------------------
0x00000024 [0x00003af4 - 0x00003b4e) główne
0x00000098: [0x00003b50 - 0x00003d8c) - [MyAppDelegate aplikacji: didFinishLaunchingWithOptions:]
... reszta wysypisko
Najtrudniej było wiedząc, że jedna z 2 statycznych bibliotek I” d zawierał ich symbole rozebrane przed umieszczeniem linka do pliku binarnego mojej aplikacji! To pozostawiło OGROMNĄ szczelinę adresów symboli, więc skończyłem z dwiema trzecimi symboli, których potrzebowałem w moim dSYM.
Należy upewnić się, że następujące flagi ustawiono na NIE w projekcie xcode dla statycznych bibliotek, tak aby po połączeniu z nim można było wciągnąć symbole do pliku binarnego aplikacji (które można następnie usunąć): COPY_PHASE_STRIP
, DEAD_CODE_STRIPPING
, i STRIP_INSTALLED_PRODUCT
.
Teraz możesz zapytać: "co mam zrobić, jeśli zrzut stosu nie zawiera głównej funkcji, ponieważ nie znajduje się w głównym wątku, więc nie mogę uzyskać adresu stosu głównej funkcji?". Na to odpowiedziałbym: "Nie mam pojęcia"! Po prostu skrzyżuj palce i miej nadzieję, że możesz uzyskać ślad stosu zawierający adres symbolu lub skorzystać z systemu zgłaszania awarii, który naśladuje dzienniki awarii Apple, takie jak PLCrashReporter.
[EDIT 26 maja 2013] -
Została wniesiona do mojej uwagi, że load address
jest naprawdę adres binarny Mach-O. Chociaż to, co opisałem powyżej, może często zadziałać - nie jest właściwie poprawne. Można to uzyskać za pomocą RAPORTU CRASH, jednak celem tej odpowiedzi było dostarczenie symboli awarii, gdy nie masz raportu o awarii. Najlepszym sposobem, aby dowiedzieć się, kiedy load address
chciałbym oznaczyć symbol, jest upewnienie się, że loguję load address
z stack addresses
.
Osobiście stworzyłem system do rejestrowania awarii (bez raportów o awariach) i wysyłania ich do wiadra S3, w którym mogę je później pobrać w celu debugowania. Kiedy rozpoczynam swoją aplikację, buforuję slide
, load address
i main function address
do wykorzystania, jeśli moja aplikacja ulega awarii i wysyłam stack addresses
.
UWAGA: funkcje dyld używać #include <mach-o/dyld.h>
slide
= adres zwrócony przez _dyld_get_image_vmaddr_slide(0)
load address
= adres zwrócony przez _dyld_get_image_header(0)
main function address
= ostatni adres w [NSThread callStackReturnAddresses]
gdy nazwie na głównym wątek
W czasie zderzenia jestem sur e zalogować [NSThread callStackReturnAddresses]
i [NSThread callStackSymbols]
a także architektury, który można pobrać poprzez tę metodę:
- (NSString*) arch
{
NSString* arch =
#ifdef _ARM_ARCH_7
@"armv7";
#elif defined (_ARM_ARCH_6)
@"armv6";
#else
nil;
#endif
return arch;
}
ja nie wiem jeszcze jak odróżnić ARMv7 i armv7s chociaż.
Może to pomóc w przyszłości. Mam zamiar zabrać wszystko, czego się nauczyłem i zamienić to w proste narzędzie do zderzenia - lepsze niż narzędzie natos (prawdopodobnie natos v2).
zaktualizowałem Natos celu wspierania dostarczania load address
Ręczne: https://github.com/NSProgrammer/natos
Mam ten sam problem. Mam zgłoszoną awarię, która zapewnia śledzenie stosu, ale żaden z symboli z mojego projektu, który nie znajduje się w stosie, nie znajduje się w dSYM mojego archiwum. Identyfikatory UU są zgodne, ale symbole są wyłączone. Jak to możliwe i jak mogę to rozwiązać? Czy jabłko modyfikuje plik binarny w jakiś sposób przed wydaniem go do sklepu z aplikacjami, co zaburza wyrównanie z moim dSYM? – NSProgrammer
Musisz uwzględnić slajd binarny i adres początkowy aplikacji. Nie można po prostu użyć adresu pamięci ze śledzenia stosu. Wystarczy użyć skryptu symbolicatecrash z Xcode, który wykonuje wszystko, czego potrzebujesz. – Kerni
Ale jeśli wszystko, co mam, to symbole (powinienem był powiedzieć zrzut stosu, a nie ślad), który czysto daje mi wartości szesnastkowe, w jaki sposób wziąć pod uwagę "slajd"? – NSProgrammer