崩潰日誌包含「二進制映像」部分,其中包含有關所有已加載模塊的體系結構(armv6/armv7)和標識符的信息。如何在運行時確定這些信息? (至少,僅適用於應用程序可執行文件)
NSBundle具有方法executableArchitectures,但如何確定哪個體系結構正在運行?如何在運行時確定二進制圖像體系結構?
5
A
回答
14
好的時間爲長的答案。應用程序中的dyld圖像的mach標題包含您正在查找的信息。我已經添加了一個例子,我只測試了其他功能,所以我不建議將它直接粘貼到生產代碼中。它的功能是獲取當前加載的所有dyld映像的所有mach標題,並打印與崩潰日誌的Binary Images部分非常相似的輸出。我所調用的方法不是線程安全的。我缺少的一件事是二進制映像的結束地址,因爲我沒有打擾如何查找。
的main.m
#import <UIKit/UIKit.h>
#include <string.h>
#import <mach-o/loader.h>
#import <mach-o/dyld.h>
#import <mach-o/arch.h>
void printImage(const struct mach_header *header)
{
uint8_t *header_ptr = (uint8_t*)header;
typedef struct load_command load_command;
const NXArchInfo *info = NXGetArchInfoFromCpuType(header->cputype, header->cpusubtype);
//Print the architecture ex. armv7
printf("%s ", info->name);
header_ptr += sizeof(struct mach_header);
load_command *command = (load_command*)header_ptr;
for(int i = 0; i < header->ncmds > 0; ++i)
{
if(command->cmd == LC_UUID)
{
struct uuid_command ucmd = *(struct uuid_command*)header_ptr;
CFUUIDRef cuuid = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, *((CFUUIDBytes*)ucmd.uuid));
CFStringRef suuid = CFUUIDCreateString(kCFAllocatorDefault, cuuid);
CFStringEncoding encoding = CFStringGetFastestEncoding(suuid);
//Print UUID
printf("<%s> ", CFStringGetCStringPtr(suuid, encoding));
CFRelease(cuuid);
CFRelease(suuid);
break;
}
header_ptr += command->cmdsize;
command = (load_command*)header_ptr;
}
}
void printBinaryImages()
{
printf("Binary Images:\n");
//Get count of all currently loaded DYLD
uint32_t count = _dyld_image_count();
for(uint32_t i = 0; i < count; i++)
{
//Name of image (includes full path)
const char *dyld = _dyld_get_image_name(i);
//Get name of file
int slength = strlen(dyld);
int j;
for(j = slength - 1; j>= 0; --j)
if(dyld[j] == '/') break;
//strndup only available in iOS 4.3
char *name = strndup(dyld + ++j, slength - j);
printf("%s ", name);
free(name);
const struct mach_header *header = _dyld_get_image_header(i);
//print address range
printf("0x%X - ??? ", (uint32_t)header);
printImage(header);
//print file path
printf("%s\n", dyld);
}
printf("\n");
}
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
printBinaryImages();
[pool release];
return retVal;
}
輸出示例:
Binary Images:
TestBed 0x1000 - ??? i386 <E96D079C-E035-389D-AA12-71E968C76BFE> /Users/username/Library/Application Support/iPhone Simulator/4.3/Applications/6F64D9F8-9179-4E21-AE32-4D4604BE77E5/TestBed.app/TestBed
UIKit 0x8000 - ??? i386 <72030911-362F-3E47-BAF3-ACD2CB6F88C0> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit
Foundation 0x772000 - ??? i386 <EB718CBD-1D57-3D31-898D-7CFA9C172A46> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation
CoreGraphics 0xA10000 - ??? i386 <D168A716-71F2-337A-AE0B-9DCF51AE9181> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics
libSystem.dylib 0xCAA000 - ??? i386 <8DF0AFCD-FFA5-3049-88E2-7410F8398749> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/usr/lib/libSystem.dylib
...
2
由於您正在構建您的應用程序,因此只需簡單回答一下體系結構,就可以檢查一些預處理器定義以確定您的應用程序的當前體系結構。確保先檢查可用的最高版本的arm,因爲每個較新的版本都定義了所有舊版本。
#if __arm__
#import <arm/arch.h>
#ifdef __ARM_ARCH_6K__
//This is armv6
#endif //__ARM_ARCH_6K__
#endif //__arm__
0
我們可以使用sysctl,sysctlbyname系統調用來獲取或設置系統信息。
示例代碼:
#import <sys/sysctl.h>
#import <mach/machine.h>
int32_t value = 0;
size_t length = sizeof(value);
sysctlbyname("hw.cputype", &value, &length, NULL, 0);
if (value == CPU_TYPE_ARM64) {
// arm64
}
else if (value == CPU_TYPE_ARM) {
// armv7/armv7s
}
else if (value == CPU_TYPE_X86) {
// simulator
}
我只列出最常見的拱形在2016年尋找「hw.cpusubtype」,以獲得更多的產品詳情,像CPU_SUBTYPE_ARM_V6
CPU_SUBTYPE_ARM_V7
CPU_SUBTYPE_ARM_V7S
+0
當問題是關於編譯二進制模塊的體系結構時,這將返回設備的CPU類型。所以,@ Joe的回答是正確的。 – michelnok 2017-07-25 14:44:34
相關問題
- 1. 確定進程的體系結構
- 2. GDB如何確定ARM體系結構
- 3. 定義一個在運行時確定屬性的結構體
- 4. 如何在android運行時得到芯片的體系結構
- 5. 結構圖:在運行時
- 6. 如何爲幾種體系結構創建二進制Debian軟件包?
- 7. 如何確定我在GCC中編譯的體系結構?
- 8. SegNet - 體系結構和圖像大小
- 9. 準確的二進制圖像分類
- 10. 二進制plist結構
- 11. 在Qt中獲取運行時體系結構信息
- 12. 插件在運行時加載的體系結構
- 13. jQuery像體系結構
- 14. 二進制圖像
- 15. 不確定如何建模和體系結構這一個
- 16. 如何運行Go二進制文件?
- 17. 如何從二進制圖像
- 18. 如何從二進制圖像
- 19. 如何顯示二進制圖像?
- 20. 如何從二進制圖像中刪除細長結構(輪廓)
- 21. 如何使用java讀取給定的二進制結構?
- 22. 如何使具有特定結構的二進制varibale - php
- 23. 確定直方圖二進制大小
- 24. 如何在運行二進制文件時加載android庫?
- 25. 在R讀取二進制結構
- 26. 以編程方式確定Ubuntu發行版和體系結構?
- 27. 如何在MATLAB中乘以二進制圖像和RGB圖像?
- 28. 視圖體系結構 - iPhone
- 29. 二進制搜索運行時間上限:復發關係
- 30. 長時間運行的webservice體系結構
謝謝你的回答!由於我只需要CPU架構來執行應用程序,因此我使用dladdr(this_function),然後使用Dl_info.dli_fbase作爲指向mach_header的指針。 – michelnok 2011-04-15 15:06:38
@Joe,你碰巧知道從_mh_execute_header獲取bundle uuid(幾乎相同的方式)是否可以在Appstore二進制文件中工作?它既適用於開發人員,也適用於臨時構建,但我想確定。 – Tertium 2012-10-08 17:44:23
@Tertium我不確定該函數的位置,但如果它是私有框架的一部分,那麼它將不被允許。 – Joe 2012-10-08 18:05:13