lldb给出“连接失败"消息.尝试“运行"时macOS 11.1上的arm64二进制文件 [英] lldb gives "attach failed" when trying to "run" an arm64 binary on macOS 11.1

查看:122
本文介绍了lldb给出“连接失败"消息.尝试“运行"时macOS 11.1上的arm64二进制文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是在运行11.1且更新了Xcode的M1 mini上.(已应用所有待处理的更新.)SIP尚未被禁用(如果可能的话,在M1上也是如此).

This is on an M1 mini, running 11.1 with an updated Xcode. (All pending updates have been applied.) SIP has not been disabled (if it can even be, on the M1).

我们有一个程序用于测试移植应用程序中的 mmap() 故障.我们按照以下方式构建测试程序:

We have a program we're using to test an mmap() failure in our application being ported. We build the test program like this:

cc -v -arch arm64 -m64 -Wl,-no_adhoc_codesign -o mapfail mapfail.c

然后,我们对其进行签名.它似乎已正确签名:

Then, we sign it. It appears to be correctly signed:

@macarm[git:master]$ codesign -vvv mapfail
mapfail: valid on disk
mapfail: satisfies its Designated Requirement
@macarm[git:master]$ 

我们已在系统上启用开发人员模式.我们还将用户添加到了 _developer 组中.我的用户不是管理员,但是我尝试使用它作为管理员,并得到了同样的东西.

We have enabled developer mode on the system. We also added my user to the _developer group. My user is not an administrator, but I tried it as one and got the same thing.

当我们运行程序时,它会遇到分段错误(SIGSEGV),因此我们想使用 lldb 对其进行调试,但这会发生:

When we run the program it gets a segmentation fault (SIGSEGV), so we want to debug it with lldb, but this happens:

@macarm[git:master]$ lldb mapfail
(lldb) target create "mapfail"
Current executable set to '/Users/layer/mapfail' (arm64).
(lldb) run
error: process exited with status -1 (attach failed ((os/kern) invalid argument))
(lldb) 

即使在Apple开发人员论坛上,对此的搜索也没有得到任何信息.

Searches for this have yielded no information, even on the Apple developer forums.

mapfail.c 的代码:

Code for mapfail.c:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <mach/mach.h>
#include <mach/machine/vm_param.h>

#define nat long

#define UseMAP_ANON
/* define UseDevZero */

#define FIROUNDUP(a, n) (((a) + ((n) - 1)) & ~((n) - 1))
#define FIROUNDDOWN(a, n) ((a) & ~((n) - 1))

int bucket_o_zeros = -1;
int ChunkSize;

# ifdef UseMAP_ANON
#   define FIMAP_ANON MAP_ANON
# else
#   define FIMAP_ANON 0
# endif

typedef struct {
    char *base;     /* lowest address -- 64k aligned */
    char *pos;      /* 1+ highest address allocated */
    char *commit;   /* 1+ highest address committed */
} heap_descriptor;

heap_descriptor test1, test2;
unsigned nat test1_base, test1_size;

int
ok_to_map(unsigned nat base, unsigned nat top)
{
    /* check if the specified memory is free */
    unsigned nat address = base;
    vm_size_t size;
    mach_port_t object_name;
    task_t task = mach_task_self();
    struct vm_region_basic_info_64 info;
    mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
    kern_return_t retval;
    int res = 0;

    retval = vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO_64,
              (vm_region_info_64_t)&info, &info_count, &object_name);
    if (retval == KERN_NO_SPACE) {
    res = 1;
    } else if ((retval == KERN_SUCCESS) && (address > top)) {
    res = 1;
    }
    if (object_name != MACH_PORT_NULL)
    mach_port_deallocate(mach_task_self(), object_name);

    printf("maping from 0x%lx to 0x%lx is %s\n", base, top, res ? "OK" : "BAD");
    return res;
}

char *
setup_heap( heap_descriptor *hd, unsigned nat base, unsigned nat size)
{
    /* allocate memory at the given address, and return the address
     * which was allocated
     */
       
    char *res = (char *)MAP_FAILED;

    /* initial setup of heap when there is nothing to map in or commit */
    base = FIROUNDDOWN(base, ChunkSize);
    size = FIROUNDUP(size, ChunkSize);

    /* we demand that OS puts memory at our base, so we can grow later */
    if (base == 0 || ok_to_map(base, base+size)) {
    res = (char *) mmap((void *) base, size, PROT_READ | PROT_WRITE | PROT_EXEC,
                MAP_PRIVATE | FIMAP_ANON | (base ? MAP_FIXED : 0),
                bucket_o_zeros, 0);
    }
    if (res != (char *) MAP_FAILED) {
    /* success - check alignment */
    if (base == 0) {
        nat diff;
        base = (unsigned nat) res;
        res = (char *) FIROUNDUP((nat) res, ChunkSize);
        diff = ((unsigned nat)res - base);
        if (diff > 0) {
        /* this had been over-requested already */
        size -= ChunkSize;
        /* must munmap the two ends */
        munmap((caddr_t) base, diff);
        munmap((caddr_t) (res + size), diff);
        }
    }
    /* initialize the heap descriptor */
    hd->pos = hd->base = res;
    hd->commit = (char *) (hd->base + size);
    return hd->base;
    } else {
    return 0;   /* failure */
    }
}

int
try_setup_heap(char *kind, heap_descriptor *hd, unsigned nat base, unsigned nat size)
{
    /* try to allocate where first requested, and then let the system decide.
     * return true or false depending on whether it worked.
     */
     
    char *result_base;

    base = FIROUNDUP(base,ChunkSize);
    size = FIROUNDUP(size,ChunkSize);

    /* ask for a specific area */
    if (setup_heap(hd, base, size)) return 1;   /* success */

    /* now ask for any location */
    if ((result_base = setup_heap(hd, 0, size + ChunkSize)) == 0) {
    fprintf(stderr,
        "Unable to reserve at %ld (0x%lx) bytes of memory for the %s heap\n",
        size, size, kind);
    return 0;
    } else {
    fprintf(stderr,
        "Unable to reserve 0x%lx for the %s heap,\n using 0x%lx instead\n",
        base, kind, (unsigned nat) result_base);
    return 1;
    }
}

int main(int argc, char **argv, char**envp)
{
    ChunkSize = getpagesize();
#if defined(UseDevZero)
    if(bucket_o_zeros == -1){
    bucket_o_zeros = open("/dev/zero", O_RDWR);
    }
#endif
    if (argc > 2) {
    sscanf(argv[1], "%lx", &test1_base);
    sscanf(argv[2], "%lx", &test1_size);
    if (try_setup_heap("test1", &test1, test1_base, test1_size)) {
        printf("test1 heap mapped from 0x%lx to 0x%lx\n",
           (unsigned nat) test1.base, (unsigned nat)test1.commit);
    } else {
        printf("test1 not mapped\n");
    }
    } else {
    unsigned nat addr = 0x100000000;
    unsigned nat size = 0x100000;
    int i, n, didit=0;;
    sscanf(argv[1], "%d", &n);
    for (i=0; i < n; i++) {
        if (try_setup_heap("test2", &test2, addr, size)) {
        printf("test1 heap mapped from 0x%lx to 0x%lx\n",
               (unsigned nat) test2.base, (unsigned nat)test2.commit);
        didit++;
        }
        addr += 0x100000000;
    }
    printf("Total mappings: %d\n", didit);
    }
}

/*
 * To compile on M1 with debugging:
 * cc -v -arch arm64 -m64 -Wl,-no_adhoc_codesign -o mapfail mapfail.c
 */

推荐答案

此问题是众所周知的,并且尚未为Apple Silicon构建C/C ++扩展二进制文件,到目前为止,它尚不起作用.

This issue is known and as C/C++ extension binaries are yet to be built for Apple Silicon, it does not work as of now.

请参阅下面的链接进行跟踪:

Refer to below link to keep a track:

https://github.com/microsoft/vscode-cpptools/issues/6595

这篇关于lldb给出“连接失败"消息.尝试“运行"时macOS 11.1上的arm64二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆