Subject: bug#33174: 27.0.50; Dump fails on GNU/Linux ppc64le

From: Thomas Fitzsimmons <[email-masked]>
Date: Mon, 29 Oct 2018 22:44:16 -0400

Paul Eggert <[email-masked]> writes:

> Thomas Fitzsimmons wrote:
>> Paul Eggert <[email-masked]> writes:
>>
>>> Wonderful. Yet another reason we need to get the pdumper branch working. Anyway:
>>>
>>> 1. Can you use strace and/or GDB to investigate how ./temacs is
>>> disabling address randomization? In the emacs-26 branch, if you run
>>> this command in src:
>>>
>>> strace -f -o /tmp/tr ./temacs --batch  --load loadup bootstrap
>>>
>>> the output file /tmp/tr should contain something like this:
>>>
>>> 18406 personality(0xffffffff)           = 0 (PER_LINUX)
>>> 18406 personality(PER_LINUX|ADDR_NO_RANDOMIZE) = 0 (PER_LINUX)
>>> 18406 personality(0xffffffff)           = 0x40000 (PER_LINUX|ADDR_NO_RANDOMIZE)
>>
>> I see the above personality calls exactly as you've shown them.
>>
>> strace never gets to the next execve; the crash happens before the next
>> execve is run, see below.
>>
>>> 18406 execve("./temacs", ["./temacs", "--batch", "--load", "loadup",
>>> "bootstrap"], 0xc521b0 /* 80 vars */) = 0
>
> So there are no more system calls after personality(0xffffffff)? That
> is, the crash happens immediately before any other system calls?

There are many more syscalls before the crash.

58215 personality(0xffffffff)           = 0 (PER_LINUX)
58215 personality(PER_LINUX|ADDR_NO_RANDOMIZE) = 0 (PER_LINUX)
58215 personality(0xffffffff)           = 0x40000 (PER_LINUX|ADDR_NO_RANDOMIZE)
58215 brk(NULL)                         = 0x27070000
58215 dup2(0, 0)                        = 0
58215 dup2(1, 1)                        = 1
58215 dup2(2, 2)                        = 2
58215 ugetrlimit(RLIMIT_STACK, {rlim_cur=9792*1024, rlim_max=RLIM64_INFINITY}) = 0
58215 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
58215 fstat(3, {st_mode=S_IFREG|0644, st_size=1679776, ...}) = 0
58215 mmap(NULL, 1679776, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fffb6ed0000
58215 close(3)                          = 0
58215 open("/usr/lib/powerpc64le-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
58215 fstat(3, {st_mode=S_IFREG|0644, st_size=26264, ...}) = 0
58215 mmap(NULL, 26264, PROT_READ, MAP_SHARED, 3, 0) = 0x7fffbbd00000
58215 close(3)                          = 0
58215 futex(0x7fffba001ab8, FUTEX_WAKE_PRIVATE, 2147483647) = 0
58215 timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC|TFD_NONBLOCK) = 3
58215 rt_sigaction(SIGALRM, {sa_handler=0x10209280, sa_mask=[ALRM CHLD PROF WINCH], sa_flags=SA_RESTART}, NULL, 8) = 0
58215 open("/dev/urandom", O_RDONLY|O_CLOEXEC) = 4
58215 read(4, "\315\276O\225", 4)       = 4
58215 close(4)                          = 0
[...]

> What does 'strace' say about the crash?

[...]
58215 write(2, "Dumping under the name emacs", 28) = 28
58215 write(2, "\n", 1)                 = 1
58215 stat("/a/b/c/emacs/src/emacs", {st_mode=S_IFREG|0755, st_size=57908416, ...}) = 0
58215 unlink("/a/b/c/emacs/src/emacs") = 0
58215 write(2, "********************************"..., 51) = 51
58215 write(2, "Warning: Your system has a gap b"..., 51) = 51
58215 write(2, "heap (346093672 bytes).  This us"..., 61) = 61
58215 write(2, "or something similar is in effec"..., 49) = 49
58215 write(2, "fail because of this.  See the s"..., 45) = 45
58215 write(2, "exec-shield in etc/PROBLEMS for "..., 50) = 50
58215 write(2, "********************************"..., 51) = 51
58215 write(2, "22440720 of 33554432 static heap"..., 43) = 43
58215 write(2, "\n", 1)                 = 1
58215 open("/a/b/c/emacs/src/temacs", O_RDONLY|O_CLOEXEC) = 5
58215 fstat(5, {st_mode=S_IFREG|0755, st_size=23687896, ...}) = 0
58215 mmap(NULL, 23687896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fffb3980000
58215 read(5, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\2\0\25\0\1\0\0\0,\207\1\20\0\0\0\0"..., 23687896) = 23687896
58215 open("/a/b/c/emacs/src/emacs", O_RDWR|O_CREAT|O_CLOEXEC, 0777) = 6
58215 ftruncate(6, 403938496)           = 0
58215 mmap(NULL, 403938496, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fff9b840000
58215 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x12670000} ---
58215 +++ killed by SIGSEGV +++

I could attach the whole strace output but it's pretty big.

> For me, the execve is the first syscall after the
> 'personality(0xffffffff) = 0x40000'. If you're seeing some other
> syscall there (or are seeing a crash), please investigate why,
> presumably with GDB.

It seems like it's crashing when trying to memcpy over the BSS area, on
this line in unexelf.c (see below):

  /* Copy over what we have in memory now for the bss area. */
  memcpy (new_base + new_data2_offset, (caddr_t) old_bss_addr,
	  bss_size_growth);

>> When I run the command under gdb, it succeeds, so I had to enable core
>> dumps to get the backtrace:
>
> Core dumps won't help us much I'm afraid. Instead, when debugging
> ./temacs, please use the GDB command "set disable-randomization off"
> before issuing the GDB command "run --batch  --load loadup bootstrap".

(memcpy.S below might not be quite the right version; the Debian
libc6-dbg 2.24 package doesn't seem to have that file, so I pointed gdb
to a copy within a glibc 2.24 git checkout instead.)

[...]
Dumping under the name emacs
**************************************************
Warning: Your system has a gap between BSS and the
heap (652277864 bytes).  This usually means that exec-shield
or something similar is in effect.  The dump may
fail because of this.  See the section about
exec-shield in etc/PROBLEMS for more information.
**************************************************
22440720 of 33554432 static heap bytes used

Program received signal SIGSEGV, Segmentation fault.
__memcpy_power7 () at ../sysdeps/powerpc/powerpc64/power7/memcpy.S:111
warning: Source file is more recent than executable.
111		lxvd2x	8,src,7
(gdb) thread apply all bt

Thread 1 (Thread 0x7fffb0f47be0 (LWP 23958)):
#0  __memcpy_power7 () at ../sysdeps/powerpc/powerpc64/power7/memcpy.S:111
#1  0x00000000101ec178 in memcpy (__len=686434792, __src=<optimized out>, __dest=<optimized out>) at /usr/include/powerpc64le-linux-gnu/bits/string3.h:53
#2  unexec (new_name=0x11b934f8 <bss_sbrk_buffer+22229000> "/a/b/c/emacs/src/emacs", 
    old_name=0x11b93528 <bss_sbrk_buffer+22229048> "/a/b/c/emacs/src/temacs") at unexelf.c:410
#3  0x0000000010110bec in Fdump_emacs (filename=XIL(0x11b945a4), symfile=XIL(0x11b94584)) at emacs.c:2224
#4  0x00000000101a7cb8 in eval_sub (form=...) at eval.c:2244
#5  0x00000000101a8194 in Fprogn (body=XIL(0x107656d3)) at eval.c:459
#6  0x00000000101a7d6c in eval_sub (form=...) at eval.c:2193
#7  0x00000000101ab8bc in Fif (args=...) at eval.c:414
#8  0x00000000101a7d6c in eval_sub (form=...) at eval.c:2193
#9  0x00000000101d8a98 in readevalloop (readcharfun=XIL(0x68d0), infile0=0x7fffffa503a0, sourcename=XIL(0x10721684), printflag=false, unibyte=..., 
    readfun=XIL(0), start=XIL(0), end=XIL(0)) at lread.c:2048
#10 0x00000000101d90bc in Fload (file=XIL(0x10721584), noerror=..., nomessage=XIL(0), nosuffix=..., must_suffix=...) at lread.c:1435
#11 0x00000000101a7c34 in eval_sub (form=...) at eval.c:2255
#12 0x00000000101acd18 in Feval (form=XIL(0x10727f03), lexical=...) at eval.c:2061
#13 0x00000000101188f8 in top_level_2 () at keyboard.c:1119
#14 0x00000000101a6410 in internal_condition_case (bfun=0x101188d0 <top_level_2>, handlers=..., hfun=0x1011f030 <cmd_error>) at eval.c:1336
#15 0x00000000101188a8 in top_level_1 (ignore=...) at keyboard.c:1127
#16 0x00000000101a6364 in internal_catch (tag=..., func=0x10118800 <top_level_1>, arg=XIL(0)) at eval.c:1101
#17 0x000000001011873c in command_loop () at keyboard.c:1088
#18 0x000000001011e89c in recursive_edit_1 () at keyboard.c:695
#19 0x000000001011eeb4 in Frecursive_edit () at keyboard.c:766
#20 0x0000000010017804 in main (argc=<optimized out>, argv=0x7fffffa50d58) at emacs.c:1717

Lisp Backtrace:
"dump-emacs" (0xffa4fee0)
"progn" (0xffa50060)
"if" (0xffa501a0)
"load" (0xffa505a0)

BTW, let me know if you don't think it's useful to debug this further.
I'm OK just disabling randomization when I build Emacs for the time
being and waiting until the portable dumper work lands, but I'm happy to
continue if you think it will lead to a general fix.

Thanks,
Thomas