coredump: Exclude special areas

Fujitsu: POSTK_DEBUG_TEMP_FIX_38
Refs: #1005
Change-Id: I8934d2aecf06a09469afe131347e42b48b6f67f6
This commit is contained in:
Ken Sato
2018-08-09 16:02:46 +09:00
committed by Masamichi Takagi
parent 2910818f06
commit a269d96978
8 changed files with 327 additions and 9 deletions

View File

@ -18,6 +18,12 @@
#define DDEBUG_DEFAULT DDEBUG_PRINT
#endif
/* Exclude reserved (mckernel's internal use), device file,
* hole created by mprotect
*/
#define GENCORE_RANGE_IS_INACCESSIBLE(range) \
((range->flag & (VR_RESERVED | VR_MEMTYPE_UC | VR_DONTDUMP)))
/*
* Generate a core file image, which consists of many chunks.
* Returns an allocated table, an etnry of which is a pair of the address
@ -307,12 +313,10 @@ int gencore(struct thread *thread, void *regs,
dkprintf("start:%lx end:%lx flag:%lx objoff:%lx\n",
range->start, range->end, range->flag, range->objoff);
/* We omit reserved areas because they are only for
mckernel's internal use. */
if (range->flag & VR_RESERVED)
continue;
if (range->flag & VR_DONTDUMP)
if (GENCORE_RANGE_IS_INACCESSIBLE(range)) {
continue;
}
/* We need a chunk for each page for a demand paging area.
This can be optimized for spacial complexity but we would
lose simplicity instead. */
@ -401,8 +405,9 @@ int gencore(struct thread *thread, void *regs,
unsigned long flag = range->flag;
unsigned long size = range->end - range->start;
if (range->flag & VR_RESERVED)
if (GENCORE_RANGE_IS_INACCESSIBLE(range)) {
continue;
}
ph[i].p_type = PT_LOAD;
ph[i].p_flags = ((flag & VR_PROT_READ) ? PF_R : 0)
@ -444,8 +449,9 @@ int gencore(struct thread *thread, void *regs,
unsigned long phys;
if (range->flag & VR_RESERVED)
if (GENCORE_RANGE_IS_INACCESSIBLE(range)) {
continue;
}
if (range->flag & VR_DEMAND_PAGING) {
/* Just an ad hoc kluge. */
unsigned long p, start, phys;

View File

@ -2255,11 +2255,9 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) {
phys = ihk_device_map_memory(dev, rphys, size);
dprintk("physical %lx, ", phys);
pt = ihk_device_map_virtual(dev, phys, size, NULL, 0);
#ifdef POSTK_DEBUG_TEMP_FIX_38
if (pt == NULL) {
pt = phys_to_virt(phys);
}
#endif /*POSTK_DEBUG_TEMP_FIX_38*/
dprintk("virtual %p\n", pt);
if (pt != NULL) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)

112
test/issues/1005/C1005.sh Normal file
View File

@ -0,0 +1,112 @@
#!/bin/sh
USELTP=0
USEOSTEST=0
. ../../common.sh
sudo /bin/sh ${OSTESTDIR}/util/insmod_test_drv.sh
ulimit_c_bk=`ulimit -Sc`
# set ulimit -c unlimited to dump core
ulimit -Sc unlimited
$BINDIR/mcexec ./devmap_and_segv | tee ./maps.txt
# restore ulimit -c
ulimit -c ${ulimit_c_bk}
sudo /bin/sh ${OSTESTDIR}/util/rmmod_test_drv.sh
tid=001
echo "*** CT_$tid start *******************************"
echo "** check file type by readelf"
readelf -h ./core | grep -e "Type:.*CORE"
if [ $? == 0 ]; then
echo "*** CT_$tid PASSED ******************************"
else
echo "*** CT_$tid FAILED ******************************"
fi
echo ""
# check by gdb
VDSO_ADDR=`grep "\[vdso\]" ./maps.txt | cut -f 1 -d "-"`
DEVMAP_ADDR=`grep "mmap_dev2$" ./maps.txt | cut -f 1 -d "-"`
GDB_OUT="./gdb_out.txt"
expect -c "
set timeout 3
log_file -noappend ${GDB_OUT}
spawn gdb --quiet -c ./core ./devmap_and_segv
# check vdso addr
expect \"(gdb)\"
send \"x 0x${VDSO_ADDR}\n\"
#check devmap addr
expect \"(gdb)\"
send \"x 0x${DEVMAP_ADDR}\n\"
#check backtrace
expect \"(gdb)\"
send \"bt\n\"
#check info registers
expect \"(gdb)\"
send \"info registers\n\"
# quit gdb_test
expect \"(gdb)\"
send \"quit\n\"
log_file
interact
" > /dev/null
tid=002
echo "*** CT_$tid start *******************************"
echo "** check that core contains vdso data"
grep -A 1 "(gdb) x 0x${VDSO_ADDR}" ${GDB_OUT}
grep -A 1 "(gdb) x 0x${VDSO_ADDR}" ${GDB_OUT} | tail -1 | grep -q "0x${VDSO_ADDR}:\s*0x[0-9a-f]\+"
if [ $? == 0 ]; then
echo "*** CT_$tid PASSED ******************************"
else
echo "*** CT_$tid FAILED ******************************"
fi
echo ""
tid=003
echo "*** CT_$tid start *******************************"
echo "** check that core dose NOT contain devmap data"
grep -A 1 "(gdb) x 0x${DEVMAP_ADDR}" ${GDB_OUT}
grep -A 1 "(gdb) x 0x${DEVMAP_ADDR}" ${GDB_OUT} | tail -1 | grep -q "0x${VDSO_ADDR}:\s*0x[0-9a-f]\+"
if [ $? == 1 ]; then
echo "*** CT_$tid PASSED ******************************"
else
echo "*** CT_$tid FAILED ******************************"
fi
echo ""
tid=004
echo "*** CT_$tid start *******************************"
echo "** check that core can be backtraced"
grep -A 1 "(gdb) bt" ${GDB_OUT}
grep -A 1 "(gdb) bt" ${GDB_OUT} | tail -1 | grep -q "^#0.*in main"
if [ $? == 0 ]; then
echo "*** CT_$tid PASSED ******************************"
else
echo "*** CT_$tid FAILED ******************************"
fi
echo ""
tid=005
echo "*** CT_$tid start *******************************"
echo "** check that core can be got info registers"
grep -A 30 "(gdb) info registers" ${GDB_OUT}
grep -A 30 "(gdb) info registers" ${GDB_OUT} | grep -q "^rip\s*0x.*main"
if [ $? == 0 ]; then
echo "*** CT_$tid PASSED ******************************"
else
echo "*** CT_$tid FAILED ******************************"
fi
echo ""

17
test/issues/1005/Makefile Normal file
View File

@ -0,0 +1,17 @@
CC = gcc
TARGET=devmap_and_segv
CPPFLAGS =
LDFLAGS =
all: $(TARGET)
devmap_and_segv: devmap_and_segv.c
$(CC) -g -o $@ $^ $(LDFLAGS)
test: all
@sh ./C1005.sh
clean:
rm -f $(TARGET) *.o ./core ./core.* ./maps.txt ./gdb_out.txt

31
test/issues/1005/README Normal file
View File

@ -0,0 +1,31 @@
【Issue#1005 動作確認】
□ テスト内容
1. Issueで報告された症状が修正されたことの確認
CT_001: McKernelのcoreファイルの形式を確認
readelf -h で、TypeがCOREであることを確認する
CT_002: vdso領域の内容がcoreファイルに含まれていることの確認
gdbのxコマンドでvdso領域のアドレスを指定し、
内容が表示されることを確認する
CT_003: device-fileの内容がcoreファイルに含まれていないことの確認
gdbのxコマンドでdevice-fileをマップした領域のアドレスを指定し、
内容を取得できないことを確認する
CT_004: backtraceの情報がcoreファイルに含まれていることを確認
gdbのbtコマンドでbacktraceの情報が表示されることを確認する
CT_005: registersの情報がcoreファイルに含まれていることを確認
gdbのinfo registersコマンドでregistersの情報が表示されることを確認する
□ 実行手順
$ make test
McKernelのインストール先や、OSTEST, LTPの配置場所は、
$HOME/.mck_test_config を参照している
.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを
$HOMEにコピーし、適宜編集する
□ 実行結果
result.log 参照
すべての項目をPASSしていることを確認

View File

@ -0,0 +1,54 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "./test_chk.h"
#define TEST_NAME "devmap_and_segv"
#define PROCFILE_LEN 128
#define MAP_LEN 4096
#define DEV_NAME "/dev/test_mck/mmap_dev2"
int main(int argc, char *argv[])
{
int dev_fd = 0;
pid_t pid = getpid();
void *dev_map = NULL;
char *segv_addr = NULL;
char cmd[128];
printf("*** %s start *******************************\n", TEST_NAME);
/* open device file */
dev_fd = open(DEV_NAME, O_RDONLY);
OKNG(dev_fd < 0, "open test_device_file:%s", DEV_NAME);
/* mmap device file */
dev_map = mmap(NULL, MAP_LEN, PROT_READ, MAP_SHARED, dev_fd, 0);
OKNG(dev_map == MAP_FAILED, "mmap device file");
printf(" map dev_file to %p\n", dev_map);
/* print maps */
sprintf(cmd, "cat /proc/%d/maps", pid);
system(cmd);
/* occur segv */
*segv_addr = '0';
printf("*** Why reached here? ***\n");
return 0;
fn_fail:
if (dev_fd > 0) {
close(dev_fd);
}
return -1;
}

View File

@ -0,0 +1,77 @@
insmod /home/satoken/ostest/util/../bin/test_mck.ko
create charcter device /dev/test_mck/mmap_dev(244:0)
create charcter device /dev/test_mck/mmap_dev2(244:1)
000000400000-000000401000 r-xs 0 0:0 0
000000600000-000000601000 r--s 0 0:0 0
000000601000-000000602000 rw-s 0 0:0 0
2aaaaa9f8000-2aaaaaa00000 rw-s 0 0:0 0
2aaaaaa00000-2aaaaaa21000 r-xs 0 0:0 0
2aaaaac21000-2aaaaac22000 r--s 0 0:0 0
2aaaaac22000-2aaaaac24000 rw-s 0 0:0 0
2aaaaac24000-2aaaaac26000 r-xs 0 0:0 0 [vdso]
2aaaaac26000-2aaaaac27000 rw-p 0 0:0 0
2aaaaac4d000-2aaaaac4e000 rw-p 0 0:0 0
2aaaaac4e000-2aaaaae06000 r-xp 0 0:0 0 /usr/lib64/libc-2.17.so
2aaaaae06000-2aaaab006000 ---p 0 0:0 0 /usr/lib64/libc-2.17.so
2aaaab006000-2aaaab00a000 r--p 0 0:0 0 /usr/lib64/libc-2.17.so
2aaaab00a000-2aaaab00c000 rw-p 0 0:0 0 /usr/lib64/libc-2.17.so
2aaaab00c000-2aaaab011000 rw-p 0 0:0 0
2aaaab011000-2aaaab013000 rw-p 0 0:0 0
2aaaab013000-2aaaab014000 rw-p 0 0:0 0
2aaaab014000-2aaaab015000 r--s 0 0:0 0 /dev/test_mck/mmap_dev2
547fff800000-548000000000 rw-s 0 0:0 0 [stack]
Terminate by signal 11
remove /dev/test_mck
rmmod /home/satoken/ostest/util/../bin/test_mck.ko
*** CT_001 start *******************************
** check file type by readelf
Type: CORE (Core file)
*** CT_001 PASSED ******************************
*** CT_002 start *******************************
** check that core contains vdso data
(gdb) x 0x2aaaaac24000
0x2aaaaac24000: 0x464c457f
*** CT_002 PASSED ******************************
*** CT_003 start *******************************
** check that core dose NOT contain devmap data
(gdb) x 0x2aaaab014000
0x2aaaab014000: Cannot access memory at address 0x2aaaab014000
*** CT_003 PASSED ******************************
*** CT_004 start *******************************
** check that core can be backtraced
(gdb) bt
#0 0x0000000000400ad0 in main (argc=1, argv=0x547ffffffd08) at devmap_and_segv.c:42
*** CT_004 PASSED ******************************
*** CT_005 start *******************************
** check that core can be got info registers
(gdb) info registers
rax 0x0 0
rbx 0x0 0
rcx 0x2aaaaac834a0 46912498054304
rdx 0x0 0
rsi 0x547ffffffa30 92908732545584
rdi 0x2 2
rbp 0x547ffffffc20 0x547ffffffc20
rsp 0x547ffffffb70 0x547ffffffb70
r8 0x0 0
r9 0x547ffffff930 92908732545328
r10 0x8 8
r11 0x246 582
r12 0xffff8001007d0dc0 -140733185192512
r13 0xffff800100770000 -140733185589248
r14 0xb98 2968
r15 0xffff80010078fa9c -140733185459556
rip 0x400ad0 0x400ad0 <main+592>
eflags 0x10206 [ PF IF RF ]
cs 0x33 51
ss 0x3b 59
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)
*** CT_005 PASSED ******************************

View File

@ -0,0 +1,23 @@
#ifndef HEADER_TEST_CHK_H
#define HEADER_TEST_CHK_H
#define CHKANDJUMP(cond, ...) do {\
if (cond) {\
fprintf(stderr, " [NG] ");\
fprintf(stderr, __VA_ARGS__);\
fprintf(stderr, " failed\n");\
goto fn_fail;\
} \
} while (0)
#define OKNG(cond, ...) do {\
if (cond) {\
CHKANDJUMP(cond, __VA_ARGS__);\
} else {\
fprintf(stdout, " [OK] ");\
fprintf(stdout, __VA_ARGS__);\
fprintf(stdout, "\n");\
} \
} while (0)
#endif