iOS工程14调试及崩溃日志

一、xctest

1.xctest 的作用

XCTest是Xcode自带的单元测试框架,我们可以使用该框架做功能性代码的白盒单元测试,以自测并增强代码健壮性。

创建时勾选:

我们通过一个工程来了解xctest:

编译运行,查看生成目录:

查看符号(命令):

css 复制代码
objdump --macho --private-headers path/path

现在我们来找到xctest.framwork在什么位置

通过创建LGXCTestCenter 来进行单元测试:

objectivec 复制代码
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>

NS_ASSUME_NONNULL_BEGIN
@interface LGXCTestCenter : XCTestSuite

+ (instancetype)testSuiteForTestCaseClassString:(NSString *)cls;

@end
NS_ASSUME_NONNULL_END


#import "LGXCTestCenter.h"
@implementation LGXCTestCenter

+ (instancetype)testSuiteForTestCaseClassString:(NSString *)cls {
    Class cl = NSClassFromString(cls);
    if (cl) {
        return [self testSuiteForTestCaseClass:cl];
    }
    return nil;
}

@end

需要配置xcconfig:

保证能够加载到xctest.framework :

ini 复制代码
#include "Pods/Target Support Files/Pods-LoginApp/Pods-LoginApp.debug.xcconfig"

// framework
XCODE_XCTEST_PATH =  /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks

FRAMEWORK_SEARCH_PATHS = ${XCODE_XCTEST_PATH}

// ld framework
//OTHER_LDFLAGS = -framework XCTest

二、dSYM

dSYM文件就是保存按DWARF格式保存调试信息的文件;

DWARF是一种被众多编译器和调试器使用的用于支持源代码级别调试的调试文件格式。

  • 读取debug map
  • 从.o文件中加载__DWARF
  • 重新定位所有地址
  • 最后将全部的DWARF打包成dSYM Bundle

使用命令查看.o的__DWARF

css 复制代码
objdump --macho --private-headers test.o

我们在运行时调试到的地址实际上是 调试地址 = 虚拟地址 + ASLR

dSYM文件内保存的是没有偏移的虚拟地址还是偏移后的地址?

通过命令查看:

通过研究 LLVM源码来探索。

三、崩溃日志

通过命令查看地址在 .dSYM内的DWARF信息:

css 复制代码
dwarfdump --lookup 0x100000f20 --arch=x86_64 test.dSYM

如何导出 .dSYM:

在设置 shell 脚本 编译生成项目导出 dSYM:

运行项目 崩溃的日志信息: 通过命令查看 macho 汇编代码:

bash 复制代码
objdump --macho -d /path

四、二进制

ASLR 内存偏移算法:

ini 复制代码
@implementation ViewController

// 偏移
// dsym --> 没

uintptr_t get_slide_address(void) {
    uintptr_t vmaddr_slide = 0;
    // dyld 加载了多少image
    for (uint32_t i = 0; i < _dyld_image_count(); i++) {
        // index dyld加载的imgae name
        const char *image_name = (char *)_dyld_get_image_name(i);
        const struct mach_header *header = _dyld_get_image_header(i);
        // macho EXEC MH_EXECUTE
        if (header->filetype == MH_EXECUTE) {
            // ASLR
            vmaddr_slide = _dyld_get_image_vmaddr_slide(i);
        }
        NSString *str = [NSString stringWithUTF8String:image_name];

        if ([str containsString:@"TestInject"]) {

              NSLog(@"Image name %s at address 0x%llx and ASLR slide 0x%lx.\n", image_name, (mach_vm_address_t)header, vmaddr_slide);
                   break;
          }
    }
    return (uintptr_t)vmaddr_slide;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self getMethodVMA];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self test_dwarf];
    });
    NSLog(@"123");

}


- (void)test_dwarf {
    NSArray *array = @[];
    array[1];
}

- (void)getMethodVMA {
    // imp 调用
    IMP imp = (IMP)class_getMethodImplementation(self.class, @selector(test_dwarf));
    unsigned long imppos = (unsigned long)imp;
    // 偏移量
    unsigned long slide =  get_slide_address();
    // imp - 偏移量
    unsigned long addr = imppos - slide;
    NSLog(@"%lx-- %lx", addr, imp);
}

/**
 ASLR 0x8c03000
 没: 100001d00
 偏移:108c04d00
 */
@end

/**
 0x000000000f0aa000
 0x0000000100001d20
 */

拿到没有偏移的地址,进行读取dSYM查看测试单元信息。

css 复制代码
dwarfdump --lookup 0x100001d00  test.dSYM

如果是.a 库,是.dylib库 出错了,怎么查看dSYM文件的错误信息。

在lldb 中设置断点。

只需要在dSYM信息中的地址中,添加对应的源码文件。就能app工程中断点到framework库中的代码。

通过命令生成 SDWebImage.a库

css 复制代码
xcframework gen --use-libraries --configuration=Debug --output-dir="../App"

产物目录/include -->xcode 会copy一份你使用的框架到 产物目录/同时copy

相关推荐
菲力蒲LY几秒前
输入搜索、分组展示选项、下拉选取,全局跳转页,el-select 实现 —— 后端数据处理代码,抛砖引玉展思路
java·前端·mybatis
MickeyCV1 小时前
Nginx学习笔记:常用命令&端口占用报错解决&Nginx核心配置文件解读
前端·nginx
祈澈菇凉2 小时前
webpack和grunt以及gulp有什么不同?
前端·webpack·gulp
zy0101012 小时前
HTML列表,表格和表单
前端·html
初辰ge2 小时前
【p-camera-h5】 一款开箱即用的H5相机插件,支持拍照、录像、动态水印与样式高度定制化。
前端·相机
HugeYLH2 小时前
解决npm问题:错误的代理设置
前端·npm·node.js
六个点3 小时前
DNS与获取页面白屏时间
前端·面试·dns
道不尽世间的沧桑3 小时前
第9篇:插槽(Slots)的使用
前端·javascript·vue.js
bin91533 小时前
DeepSeek 助力 Vue 开发:打造丝滑的滑块(Slider)
前端·javascript·vue.js·前端框架·ecmascript·deepseek
uhakadotcom3 小时前
最新发布的Tailwind CSS v4.0提供了什么新能力?
前端