线上有一台t4的机器,这些机器的cpu topo是经过伪造的,通过top命令可以看到4个核心:
top
Cpu0 : 0.3%us, 0.0%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.7%st
Cpu1 : 0.7%us, 0.3%sy, 0.0%ni, 98.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.3%st
Cpu2 : 0.3%us, 0.7%sy, 0.0%ni, 78.1%id, 0.0%wa, 0.0%hi, 0.0%si, 20.9%st
Cpu3 : 0.0%us, 0.3%sy, 0.0%ni, 79.2%id, 0.0%wa, 0.0%hi, 0.0%si, 20.5%st
/proc/cpu_info下也是4个核心:
cat /proc/cpuinfo
processor : 0
physical id : 0
core id : 0
cpu cores : 4
processor : 1
physical id : 0
core id : 1
cpu cores : 4
processor : 2
physical id : 0
core id : 2
cpu cores : 4
processor : 3
physical id : 0
core id : 3
cpu cores : 4
但实际机器有24个核心:
cat /sys/devices/system/cpu/online
0-23
在这台机器上编译erlang虚拟机或安装已经打包的虚拟机,全部会报出segment falut的错误,对于这个问题,进行了跟踪。
首先可以确认,erlang虚拟机本身是可以正确编译好的,这给我们提供了gdb跟踪的条件,跟踪发现:
main
|-erts_cpu_info_create
|-erts_cpu_info_update
|-configured = (int) sysconf(_SC_NPROCESSORS_CONF);
| 使用sysconf得到cpu个数,此处得到的是伪造的4
|-cpuinfo->configured = configured;
|-read_topology
|-cpuinfo->topology = malloc(sizeof(erts_cpu_topology_t) * cpuinfo->configured);
| 此处为拓扑信息分配空间,数量为从sysconf处获得的cpu个数
|-cdir = opendir("/sys/devices/system/cpu");
|-do {
struct dirent *cde = readdir(cdir);
if (sscanf(cde->d_name, "cpu%d", &cpu_id) == 1) {
sprintf(fpath, "%s/cpu%d/topology/physical_package_id", cpath, cpu_id);
if (read_file(fpath, buf, sizeof(buf)) <= 0) continue;
读取/sys/devices/system/cpu/cpu#/topology/physical_package_id,注意这将取出配置的4个cpu之外的cpu的物理封包id
sprintf(fpath, "%s/cpu%d/topology/physical_package_id", cpath, cpu_id);
if (read_file(fpath, buf, sizeof(buf)) <= 0) continue;
读取/sys/devices/system/cpu/cpu#/topology/core_id,注意这将取出配置的4个cpu之外的cpu的核心id
ix++;
cpuinfo->topology[ix].node= node_id;
在ix超过4时,该处动作将越界访问cpuinfo->topology分配的内存,引发segment fault
}
} while (got_nodes);
自此,已经得到了问题的原因,t4机器伪造的cpu拓扑信息并不完全,erlang虚拟机在启动的时候会额外检查/sys/devices/system/cpu下
具体的cpu信息,这些信息与通过sysconf得到的信息不符,进而引发了越界的访存。
这个问题的fix方案有几种,举例如下:
1.修改erlang代码,将configured赋予一个足够大的值,避免访存越界,然后通过启动时加入参数或设置环境变量sct强制控制cpu拓扑,
如:export ERL_FLAGS="+sct L0-3c0-3";
2.修改erlang代码,在循环读取真实拓扑信息时,忽略超过configured数量的cpu的信息,同样,启动时加入参数或设置环境变量sct;
3.令额外的cpu信息对erlang虚拟机不可见。
这个坑比较容易误导,今后应避免。
相关推荐
Erlang核心开发者Lukas Larsson在2014年3月份Erlang Factory上的一个演讲详细介绍了Erlang内存体系的原理以及调优案例 根据siyao zheng博客上听写的资源进行的翻译,大致只翻译了80%但核心部分已经完整,希望对大家...
hex, Erlang虚拟机的软件包管理器 十六进制 Hex是Erlang虚拟机的软件包管理器。这个项目目前提供了与混合。tcm 工具构建的任务。有关安装说明和其他文档,请参阅 hex.pm 。在本地安装十六进制以进行开发: mix ...
Erlang虚拟机(Erlang VM,也称为BEAM虚拟机)是Erlang编程语言的核心组成部分,它为Erlang提供了强大的并发特性和故障容错能力。基于Erlang VM的语言充分利用了这些优势,同时也引入了不同语法和编程范式的创新。 ...
Erlang是运行于虚拟机的解释性语言,但是现在也包含有乌普萨拉大学高性能Erlang计划(HiPE)开发的本地代码编译器,自R11B-4版本开始,Erlang也开始支持脚本式解释器。在编程范型上,Erlang属于多重范型编程语言,...
- **BEAM虚拟机**:Erlang的运行时系统,全称是BIFs (Built-In Functions)、Erlang、Assembler and Memory管理器。 - **OTP行为**:如Supervisor(监督者)、GenServer(通用服务器)、GenEvent(事件处理器)等,...
3. 安装完成后,确保Erlang的路径被添加到系统的PATH环境变量中,以便在命令行中直接运行erl命令。 4. 验证安装是否成功,可以打开命令行输入`erl`,如果出现Erlang shell界面,说明安装成功。 Erlang语言的特点...
Erlang采用“let it crash”哲学,鼓励程序在遇到错误时立即崩溃,而不是尝试恢复。这样可以快速暴露问题,便于系统自我修复。Supervision树(Supervisor Trees)是处理故障的一种机制,它能自动重启失败的进程。 #...
调试是软件开发中不可或缺的环节,Erlang提供了许多强大的调试工具,例如Erlang的crash dump分析工具、snooper消息监听器等,它们帮助开发者在开发和测试阶段快速定位和解决问题。 #### 4. 并发与网络 ##### 4.1 ...
在Erlang中,程序结构由函数、模块和Beam文件组成,运行在Erlang虚拟机(VM)上。Erlang 的进程模型支持抢占式调度,通信机制基于消息传递,且有专门的监控和调试工具,如etop。 **Erlang 的系统组成** - 编译器:...
为了确保Erlang OTP能够正常工作,安装后可以验证其安装是否成功,例如通过命令行输入`erl`启动Erlang shell,如果能够进入交互式模式,就表明Erlang已正确安装。接下来,如果计划安装RabbitMQ,需要从RabbitMQ官方...
7. **BEAM虚拟机**:Erlang运行在BEAM(Erlang虚拟机)上,BEAM为Erlang提供了高效的内存管理和垃圾回收。 8. **标准库**:OTP包含了大量的库和组件,如Mnesia(分布式数据库)、Riak(分布式键值存储)等,为...
7. **Erlang虚拟机(BEAM)**:BEAM是Erlang的运行时环境,它优化了并发执行和内存管理。书中会简要介绍BEAM的工作原理,以及它如何支持Erlang的独特特性和性能。 8. **实际应用案例**:除了理论知识,本书还包含了...
Erlang NIF(Native Implemented Functions)是Erlang虚拟机提供的一种机制,允许开发者用C语言或者其他低级语言编写性能关键部分的代码,并在Erlang系统中无缝调用。这种方式可以充分利用C语言的高效性,同时保持...
OTP_src_21.0是Erlang/OTP 21.0版本的源代码包,其中包含了Erlang虚拟机(BEAM)、标准库、开发工具和其他相关组件。这个版本可能引入了新的特性、性能优化或错误修复,对于开发者来说,研究源码有助于了解这些变化...
它包括Erlang虚拟机(BEAM)、进程间通信机制、错误处理工具以及一系列预先设计好的行为模式(Behaviours),如GenServer、GenEvent和Supervisor,这些模式提供了强大的容错和恢复能力。 **2. ERTS - Erlang Run-...
4. **验证**:安装完成后,打开命令行窗口并输入`erl`,如果Erlang成功安装,你应该能看到Erlang的shell(REPL)启动。 Erlang 25.0版本可能包含以下改进和新特性: 1. **性能优化**:新版本通常会对语言性能进行...
erts包含了Erlang虚拟机和其他核心组件,而库则包含了大量的模块和功能,如分布式通信、数据库接口、加密等。 在压缩包中,"COPYRIGHT"文件通常包含了软件的版权信息和许可协议。阅读此文件是了解Erlang的使用权限...
OTP 21.3是Erlang的一个特定版本,它包含了Erlang虚拟机(BEAM)、标准库和其他相关工具。在这个版本中,开发者可以享受到更稳定、性能更优的Erlang运行环境。 Erlang是一种函数式编程语言,特别适合用于并发处理和...