动机
我正在努力提高对SIGBUS error in Xwayland的理解。自2018年2月20日左右以来,Fedora Linux的一些用户已经看到了这一点,这些用户使用Xwayland 1.19.6-5.fc27.x86_64和Linux内核4.15.3-300.fc27.x86-64。
可悲的是我没有kernel "segfault" log message(或SIGBUS的等效项)。 Xwayland有一些毫无意义的代码,可以捕获致命信号。但是我可以通过调试coredump看到 siginfo ,这似乎差不多。
定义
我了解当虚拟内存的页面在RAM中不可用并且必须从磁盘读取时会发生“主要页面错误”。我想我对ext4文件系统支持的页面特别感兴趣(例如,无法直接访问块设备)。
因此,当不需要磁盘访问时就是“较小的页面错误”。我认为差异是相当明确的,因为Linux公开了主要和次要页面错误的计数器。
我的问题
如果内核发送了一个SIGBUS程序,我想知道我是否通常应该认为这将是主要的页面错误。
根据核心转储和反汇编,程序在接收到SIGBUS时正在读取内存,而不是对其进行写入。 siginfo->si_addr中的错误地址在映射的系统可执行文件内,该文件不能由用户写入,并且该地址似乎在当前文件长度的范围内。实际上,在调试coredump时,我已经从内存地址中读取了非常令人信服的值。似乎coredump生成过程在读取此地址时没有困难:-(。
我也有信心排除“无效的地址对齐”情况(BUS_ADRALN),因为siginfo->si_code为2,即BUS_ADRERR,“不存在的物理地址”。同样是因为我使用的是x86,在大多数情况下它允许未对齐的访问,并且陷阱不在任何SSE扩展指令中。
我考虑了内核在处理确定为“次要”的页面错误时通常负责的工作。我想小故障可能无法分配内存,从而引发SIGBUS。但是,我相信我会注意到这样的分配失败:
我有很多免费的交换操作可以将用户页面逐出,并且我没有注意到系统开始交换时通常发生的明显减速。崩溃发生在笔记本电脑从挂起状态变为ram状态后的几秒钟内,即使以大约100MB/s的速度,它也不足以填满8GB的交换空间。
我也没有看到可怕的内存不足(OOM)杀手出现在内核日志中,就像我期望的那样,如果内核未能成功分配页面框架或页面表。
还有其他可能性,一个轻微的页面错误可能会失败并导致SIGBUS? IE。在内核日志中查找错误时,有什么我不会注意到的原因吗?哪个会很快发作?
同样,多个核心转储将其显示为页面错误,这是通过从文件系统上的映射文件读取而触发的。
别有用心
我真的很想念一个小页面错误的情况。因为这令人恐惧的反面是,我不明白这种SIGBUS可能是由硬页面错误的一面引起的。从几个月前开始,我们中的一些用户有非常相似的错误。我的内核日志中没有IO错误。在正常操作期间,读取指示的文件时没有IO错误。在rpm --verify --all上运行或在HDD上运行扩展的SMART测试时,我没有任何错误。不幸的是,我似乎很少有犯罪嫌疑人。我最怀疑的是内核升级,显然我不希望排除该升级。日期并不能完全证明这一点,但是还不能完全排除它。日期最近的是今年的微代码更新。这似乎更难确定。
轻微页面错误的已知原因
MAP_NONBLOCK (since Linux 2.5.46)
This flag is meaningful only in conjunction with MAP_POPULATE. Don't perform read-ahead: create page tables entries only for pages that are already present in RAM. Since Linux 2.6.23, this flag causes MAP_POPULATE to do nothing. One day, the combina‐ tion of MAP_POPULATE and MAP_NONBLOCK may be reimplemented.
$ gdb 2018-03-21.core
...
Core was generated by `/usr/bin/Xwayland :0 -rootless -terminate -core -listen 4 -listen 5 -displayfd'.
Program terminated with signal SIGBUS, Bus error.
#0 _dl_fixup (l=0x7fc0be2e0130, reloc_arg=203) at ../elf/dl-runtime.c:73
73 const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
[Current thread is 1 (Thread 0x7fc0be29fa80 (LWP 1918))]
(gdb) p $_siginfo.si_signum
$1 = 7
(gdb) p $_siginfo.si_code
$2 = 2
(gdb) p $_siginfo._sifields._sigfault.si_addr
$3 = (void *) 0x41bd80
(gdb) disassemble
Dump of assembler code for function _dl_fixup:
0x00007fc0be0c8bd0 <+0>: push %rbx
0x00007fc0be0c8bd1 <+1>: mov %rdi,%r10
0x00007fc0be0c8bd4 <+4>: mov %esi,%esi
0x00007fc0be0c8bd6 <+6>: lea (%rsi,%rsi,2),%rdx
0x00007fc0be0c8bda <+10>: sub $0x10,%rsp
0x00007fc0be0c8bde <+14>: mov 0x68(%rdi),%rax
0x00007fc0be0c8be2 <+18>: mov 0x8(%rax),%rdi
0x00007fc0be0c8be6 <+22>: mov 0xf8(%r10),%rax
0x00007fc0be0c8bed <+29>: mov 0x8(%rax),%rax
0x00007fc0be0c8bf1 <+33>: lea (%rax,%rdx,8),%r8
0x00007fc0be0c8bf5 <+37>: mov 0x70(%r10),%rax
=> 0x00007fc0be0c8bf9 <+41>: mov 0x8(%r8),%rcx
(gdb) p/x $r8
$4 = 0x41bd78
(gdb) p/x $r8 + 8
$5 = 0x41bd80
reloc->r_info。(gdb) p reloc
$6 = (const Elf64_Rela * const) 0x41bd78
(gdb) p &reloc->r_info
$7 = (Elf64_Xword *) 0x41bd80
(gdb) p *reloc
$8 = {r_offset = 8443504, r_info = 936302870535, r_addend = 0}
maps捕获的abrtd文件):00400000-0060b000 r-xp 00000000 fd:00 1708508 /usr/bin/Xwayland
0080a000-0080d000 r--p 0020a000 fd:00 1708508 /usr/bin/Xwayland
0080d000-00817000 rw-p 0020d000 fd:00 1708508 /usr/bin/Xwayland
$ size -x /usr/bin/Xwayland
text data bss dec hex filename
0x209ffb 0xbe9d 0x1f3e0 2314872 235278 /usr/bin/Xwayland
最佳答案
我当然在内核中有一些错误,除非它是内核自检中的错误。
编辑:嗯,实际上似乎其他人最近也注意到了GS自检失败,但是它已经存在于较早的内核中,并且也出现在AMD cpus上。目前似乎还没有关于如何修复它的结论。 https://lkml.org/lkml/2018/1/26/436
因此,尽管我不能排除在启用PTI之类的情况下此GS错误会导致更明显的损坏,但这并不是它本身。
$ uname -r
4.15.10-300.fc27.x86_64
$ git describe --all
heads/4.15.10
$ cat ./Documentation/x86/pti.txt
...
2. Run several copies of all of the tools/testing/selftests/x86/ tests
(excluding MPX and protection_keys) in a loop on multiple CPUs for
several minutes. These tests frequently uncover corner cases in the
kernel entry code. In general, old kernels might cause these tests
themselves to crash, but they should never crash the kernel.
$ cd tools/testing/selftests/x86
$ make
...
sh -c ' while true; do for i in *; do if test -x $i; then ./$i || exit; fi ; done; done '
[RUN] ARCH_SET_GS(0x200000000), then schedule to 0x200000000
Before schedule, set selector to 0x3
other thread: ARCH_SET_GS(0x200000000) -- sel is 0x0
[FAIL] GS/BASE changed from 0x3/0x0 to 0x0/0x0
[RUN] Executing 6-argument 32-bit syscall via VDSO
[WARN] Flags before=0000000000200ed7 id 0 00 o d i s z 0 a 0 p 1 c
[WARN] Flags after=0000000000200682 id 0 00 d i s 0 0 1
[WARN] Flags change=0000000000000855 0 00 o z 0 a 0 p 0 c
[OK] Arguments are preserved across syscall
[NOTE] R11 has changed:0000000000200682 - assuming clobbered by SYSRET insn
[OK] R8..R15 did not leak kernel data
[RUN] Executing 6-argument 32-bit syscall via INT 80
[OK] Arguments are preserved across syscall
[OK] R8..R15 did not leak kernel data
[RUN] Running tests under ptrace
[RUN] Executing 6-argument 32-bit syscall via VDSO
[WARN] Flags before=0000000000200ed7 id 0 00 o d i s z 0 a 0 p 1 c
[WARN] Flags after=0000000000200686 id 0 00 d i s 0 0 p 1
[WARN] Flags change=0000000000000851 0 00 o z 0 a 0 0 c
[OK] Arguments are preserved across syscall
[NOTE] R11 has changed:0000000000200686 - assuming clobbered by SYSRET insn
[OK] R8..R15 did not leak kernel data
[RUN] Executing 6-argument 32-bit syscall via INT 80
[OK] Arguments are preserved across syscall
[OK] R8..R15 did not leak kernel data
Warning: failed to find getcpu in vDSO
[RUN] Testing getcpu...
[OK] CPU 0: syscall: cpu 0, node 0
[OK] CPU 1: syscall: cpu 1, node 0
[OK] CPU 2: syscall: cpu 2, node 0
[OK] CPU 3: syscall: cpu 3, node 0
[RUN] Testing getcpu...
[OK] CPU 0: syscall: cpu 0, node 0 vdso: cpu 0, node 0 vsyscall: cpu 0, node 0
[OK] CPU 1: syscall: cpu 1, node 0 vdso: cpu 1, node 0 vsyscall: cpu 1, node 0
[OK] CPU 2: syscall: cpu 2, node 0 vdso: cpu 2, node 0 vsyscall: cpu 2, node 0
[OK] CPU 3: syscall: cpu 3, node 0 vdso: cpu 3, node 0 vsyscall: cpu 3, node 0
[NOTE] failed to find getcpu in vDSO
[RUN] test gettimeofday()
vDSO time offsets: 0.000006 0.000000
[OK] vDSO gettimeofday()'s timeval was okay
[RUN] test time()
[FAIL] vDSO returned the wrong time (1522063297 1522063296 1522063297)
关于我可以排除SIGBUS由 "minor page fault"引发吗? (内核日志没有分配失败),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49477340/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
通过rubykoans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que