解决lldb调试时可能出现的personality set failed: Function not implemented

42 篇文章 6 订阅
11 篇文章 2 订阅

最近在尝试使用Visual Studio 2022远程连接Linux进行C/C++的开发,由于CentOS风波不断,所以现在的开发基本上都是使用ubuntu了,但是目前VS2022有一些BUG,就是远程调试时,如果目标系统是ubuntu则会出现启动调试器很慢的问题,基本上要超过20秒,甚至更久,笔者试过几个ubuntu系统了,不管是实体机,虚拟机,还是容器,只要是ubuntu系统,都存在这样的问题,向MS提了BUG了,官方还在考虑中,不知道是否修复,啥时候修复。

CentOS系统则不存在很慢的问题,所以笔者在容器中安装了CentOS7,由于CentOS系统对软件的更新是比较慢的,所以想要使用C++的新特性,比如C++17,甚至C++20则需要自己安装新的编译器和调试器。

笔者在CentOS7安装了最新的GCC13.2、GDB13.2和llvm 16.0.6(包括clang、lld、lldb等)。使用下来GCC以及GDB都没发现问题,clang/clang++编译链接也没发现问题,只有lldb在调试时报了personality set failed: Function not implemented,查看lldb的源码发现是在文件source\Host\posix\ProcessLauncherPosixFork.cpp:69DisableASLR函数报的错误,源码:

static void DisableASLR(int error_fd) {
#if defined(__linux__)
  const unsigned long personality_get_current = 0xffffffff;
  int value = personality(personality_get_current);
  if (value == -1)
    ExitWithError(error_fd, "personality get");

  value = personality(ADDR_NO_RANDOMIZE | value);
  if (value == -1)
    ExitWithError(error_fd, "personality set");
#endif
}

即执行personality(ADDR_NO_RANDOMIZE | value)失败,关于personalityA tour of Linux syscall personality有一个简单的介绍。

lldb报personality set failed: Function not implemented即是personality函数没有实现。可以写一个简单的程序:

#include <stdlib.h>
#include <iostream>
#include <sys/personality.h>

static void ExitWithError(int error_fd,
	const char* operation) {
	int err = errno;
	std::cout << strerror(err) << std::endl;
	exit(1);
}

int main()
{
	int error_fd = 0;
	const unsigned long personality_get_current = 0xffffffff;
	int value = personality(personality_get_current);
	if (value == -1)
		ExitWithError(error_fd, "personality get");

	value = personality(ADDR_NO_RANDOMIZE | value);
	if (value == -1)
		ExitWithError(error_fd, "personality set");
	return 0;
}

来进行测试。

personality函数的实现是在glibc中,CentOS7的glibc是2.17版本的:
在这里插入图片描述

Ubuntu的glibc是2.35的,比较新(目前最新的glibc是2.38),经过测试,没这样的问题,所以CentOS7的版本是太老了。
在这里插入图片描述
可能有读者想到了升级glibc,可是可以,但是风险非常大,因为glibc是整个系统非常基础的库,一旦出问题,则会导致系统崩溃。笔者就在容器中尝试升级到2.38,发现编译不过报错../sysdeps/x86_64/multiarch/memchr-evex-base.S:229: Error: no such instruction: vpcmpneqb (64 * 4)(%rdi),%zmm17,%k1',2.36、2.37都是这样的错。2.35在添加了参数--disable-werror后编译通过了,但是安装后,常用的命令都不能使用了,不兼容,系统崩溃,不能再启动。所以一定要慎重升级glibc库,特别是物理机上。

在lldb源码source\Commands\CommandObjectProcess.cpp:188中有提到使用settings target.disable-aslr来进行开关,即在lldb中先执行settings set target.disable-aslr 0即可:

在这里插入图片描述

不能每次都手动输入,为了方便可以将命令写入到~/.lldbinit文件中,每次lldb启动时自动执行。

转载请标明出处。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值