Test "/proc/PID/maps support add" on arm64.

Change-Id: I0585ae6257b5c0269760dd7f23ba75b83dd7ac2c
This commit is contained in:
Shiratori, Takehiro
2018-11-21 17:24:29 +09:00
committed by Masamichi Takagi
parent 9e57db5427
commit cf113d392a
5 changed files with 364 additions and 0 deletions

View File

@ -0,0 +1,15 @@
# Makefile COPYRIGHT FUJITSU LIMITED 2018
CC = gcc
TARGET = proc_maps
LDFLAGS =
all: $(TARGET)
proc_maps: proc_maps.c
$(CC) -o $@ $^ $(LDFLAGS)
test: all
./run.sh
clean:
rm -f $(TARGET)

View File

@ -0,0 +1,58 @@
/* README COPYRIGHT FUJITSU LIMITED 2018 */
/proc/[pid]/maps 追加機能テストセットREADME
(1) テストの実行方法
以下の手順でテストを実行する
1. $HOME/.mck_test_configを用意する
当該ファイルは、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを
$HOMEにコピーし、適宜編集する
2. make testを実行する
(2) テスト項目詳細
TEST001 ---p の属性でmmap登録した情報が出力されること。
TEST002 ---s の属性でmmap登録した情報が出力されること。
TEST003 r--p の属性でmmap登録した情報が出力されること。
TEST004 r--s の属性でmmap登録した情報が出力されること。
TEST005 -w-p の属性でmmap登録した情報が出力されること。
TEST006 -w-s の属性でmmap登録した情報が出力されること。
TEST007 --xp の属性でmmap登録した情報が出力されること。
TEST008 --xs の属性でmmap登録した情報が出力されること。
TEST009 rw-p の属性でmmap登録した情報が出力されること。
TEST010 rw-s の属性でmmap登録した情報が出力されること。
TEST011 r-xp の属性でmmap登録した情報が出力されること。
TEST012 r-xs の属性でmmap登録した情報が出力されること。
TEST013 -wxp の属性でmmap登録した情報が出力されること。
TEST014 -wxs の属性でmmap登録した情報が出力されること。
TEST015 rwxp の属性でmmap登録した情報が出力されること。
TEST016 rwxs の属性でmmap登録した情報が出力されること。
TEST017 offsetフィールドが全て0であること。
TEST018 devフィールドがすべて0:0であること。
TEST019 inodeフィールドが全て0であること。
TEST020 "[vdso]"のpathnameを持つエントリが存在すること。
TEST021 "[vsyscall]"のpathnameを持つエントリが存在すること。
TEST022 "[stack]"のpathnameを持つエントリのstart-endの間にスタックアドレスがあること。
TEST023 "[heap]"のpathnameを持つエントリのstart-endの間にsbrk()の結果アドレスがあること。
TEST024 pathnameが空文字列であるエントリがあること。
(3) 実行結果ログ
result.logファイル内に実行時のログを記載する。
実行に利用したIHK/McKernelは、IA版における下記の版数相当の
arm64版移植IHK/McKernelである。
IHK
commit d6fcbee8cb91f9ec4b49f97c918e696ac0335aaf
Author: Shiratori, Takehiro <fj0300es@aa.jp.fujitsu.com>
Date: Tue Oct 16 16:25:33 2018 +0900
McKernel
commit 6f9fef2b13447c74c36d15cf5ebd186f8395ccca
Author: Ken Sato <ken.sato.ty@hitachi-solutions.com>
Date: Tue Sep 25 10:05:41 2018 +0900
(4) 備考
本テストセットは一部IHK/McKernelの実装挙動を期待としてテスト項目を作成しているため、
全ての項目がHOST-Linux上でもOKになるとは限らない。
以上。

View File

@ -0,0 +1,254 @@
/* proc_maps.c COPYRIGHT FUJITSU LIMITED 2018 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#define BUF_SIZE 4096
#define EXP_STR_SIZE 64
int main(int argc, char *argv[])
{
FILE *fp = NULL;
const char pfname[] = "/proc/self/maps";
int result = 0;
int i = 0;
int offset_ng = 0;
int dev_ng = 0;
int inode_ng = 0;
int vdso_ok = 0;
int vsyscall_ok = 0;
int stack_ok = 0;
int heap_ok = 0;
int pathempty_ok = 0;
const unsigned int page_size = sysconf(_SC_PAGESIZE);
char buf[BUF_SIZE];
struct {
int okng;
int prot;
int flags;
void *addr;
char exp[EXP_STR_SIZE];
} mapconf[] = {
{ -1, PROT_NONE, MAP_PRIVATE },
{ -1, PROT_NONE, MAP_SHARED },
{ -1, PROT_READ, MAP_PRIVATE },
{ -1, PROT_READ, MAP_SHARED },
{ -1, PROT_WRITE, MAP_PRIVATE },
{ -1, PROT_WRITE, MAP_SHARED },
{ -1, PROT_EXEC, MAP_PRIVATE },
{ -1, PROT_EXEC, MAP_SHARED },
{ -1, PROT_READ | PROT_WRITE, MAP_PRIVATE },
{ -1, PROT_READ | PROT_WRITE, MAP_SHARED },
{ -1, PROT_READ | PROT_EXEC, MAP_PRIVATE },
{ -1, PROT_READ | PROT_EXEC, MAP_SHARED },
{ -1, PROT_WRITE | PROT_EXEC, MAP_PRIVATE },
{ -1, PROT_WRITE | PROT_EXEC, MAP_SHARED },
{ -1, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE },
{ -1, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED },
};
/* fopen */
if ((fp = fopen(pfname, "r")) == NULL) {
printf("fopen() failed. %d\n", errno);
result = -1;
goto fast_err;
}
/* mapping */
for (i = 0; i < sizeof(mapconf) / sizeof(mapconf[0]); i++) {
mapconf[i].addr = mmap(NULL, page_size, mapconf[i].prot,
mapconf[i].flags | MAP_ANONYMOUS, -1, 0);
if (mapconf[i].addr == NULL) {
printf("mmap(prot=%d, flags=%d) failed. %d\n",
mapconf[i].prot, mapconf[i].flags, errno);
result = -1;
goto err;
}
snprintf(mapconf[i].exp, sizeof(mapconf[i].exp),
"%lx-%lx %s%s%s%s", mapconf[i].addr, mapconf[i].addr + page_size,
mapconf[i].prot & PROT_READ ? "r" : "-",
mapconf[i].prot & PROT_WRITE ? "w" : "-",
mapconf[i].prot & PROT_EXEC ? "x" : "-",
mapconf[i].flags & MAP_PRIVATE ? "p" : "s");
}
/* print-procfs */
while (fgets(buf, sizeof(buf), fp) != NULL) {
unsigned long start;
unsigned long end;
char prot[8];
unsigned long offset = 1;
unsigned long dev1 = 1;
unsigned long dev2 = 1;
unsigned long inode = 1;
char pathname[BUF_SIZE] = "\0";
sscanf(buf, "%lx-%lx %s %lx %lx:%lx %lx\t\t\t%s",
&start, &end, prot, &offset, &dev1, &dev2, &inode, pathname);
if (offset != 0) {
offset_ng = 1;
}
if (dev1 != 0 || dev2 != 0) {
dev_ng = 1;
}
if (inode != 0) {
inode_ng = 1;
}
if (strlen(pathname) != 0) {
if (vdso_ok != 1) {
if (!strcmp("[vdso]", pathname)) {
vdso_ok = 1;
}
}
if (vsyscall_ok != 1) {
if (!strcmp("[vsyscall]", pathname)) {
vsyscall_ok = 1;
}
}
if (stack_ok != 1) {
if (!strcmp("[stack]", pathname)) {
unsigned long stack_addr = (unsigned long)pathname;
stack_addr--;
if ((start <= stack_addr) &&
(stack_addr < end)) {
stack_ok = 1;
} else {
stack_ok = -1;
}
}
}
if (heap_ok != 1) {
if (!strcmp("[heap]", pathname)) {
unsigned long heap_addr = (unsigned long)sbrk(0);
heap_addr--;
if ((start <= heap_addr) &&
(heap_addr < end)) {
heap_ok = 1;
} else {
heap_ok = -1;
}
}
}
} else if (pathempty_ok != 1) {
pathempty_ok = 1;
}
for (i = 0; i < sizeof(mapconf) / sizeof(mapconf[0]); i++) {
if (mapconf[i].okng == -1) {
if (strstr(buf, mapconf[i].exp)) {
mapconf[i].okng = 0;
break;
}
}
}
}
/* unmapping */
for (i = 0; i < sizeof(mapconf) / sizeof(mapconf[0]); i++) {
munmap(mapconf[i].addr, page_size);
}
/* ok/ng check */
/* addr, prot and flags */
for (i = 0; i < sizeof(mapconf) / sizeof(mapconf[0]); i++) {
if (mapconf[i].okng == -1) {
printf("TEST%03d: NG, %s not found.\n", i + 1, mapconf[i].exp);
result = -1;
} else {
printf("TEST%03d: OK\n", i + 1);
}
}
/* offset */
if (offset_ng == 1) {
printf("TEST%03d: NG, offset field is not 0.\n", ++i);
result = -1;
} else {
printf("TEST%03d: OK\n", ++i);
}
/* dev */
if (dev_ng == 1) {
printf("TEST%03d: NG, dev field is not 0.\n", ++i);
result = -1;
} else {
printf("TEST%03d: OK\n", ++i);
}
/* inode */
if (inode_ng == 1) {
printf("TEST%03d: NG, inode field is not 0.\n", ++i);
result = -1;
} else {
printf("TEST%03d: OK\n", ++i);
}
/* pathname */
/* [vsdo] */
if (vdso_ok == 1) {
printf("TEST%03d: OK\n", ++i);
} else {
printf("TEST%03d: NG, [vdso] pathname not found.\n", ++i);
result = -1;
}
/* [vsyscall] */
if (vsyscall_ok == 1) {
printf("TEST%03d: OK\n", ++i);
} else {
printf("TEST%03d: NG, [vsyscall] pathname not found.\n", ++i);
result = -1;
}
/* [stack] */
if (stack_ok == 0) {
printf("TEST%03d: NG, [stack] pathname not found.\n", ++i);
result = -1;
} else if (stack_ok == -1) {
printf("TEST%03d: NG, [stack] pathname found, but addr is not expected.\n", ++i);
result = -1;
} else {
printf("TEST%03d: OK\n", ++i);
}
/* [heap] */
if (heap_ok == 0) {
printf("TEST%03d: NG, [heap] pathname not found.\n", ++i);
result = -1;
} else if (heap_ok == -1) {
printf("TEST%03d: NG, [heap] pathname found, but addr is not expected.\n", ++i);
result = -1;
} else {
printf("TEST%03d: OK\n", ++i);
}
/* empty */
if (pathempty_ok == 0) {
printf("TEST%03d: NG, empty pathname not found.\n", ++i);
result = -1;
} else {
printf("TEST%03d: OK\n", ++i);
}
err:
if (fclose(fp)) {
printf("fclose() failed. %d\n", errno);
result = -1;
}
fast_err:
return result;
}

View File

@ -0,0 +1,28 @@
gcc -o proc_maps proc_maps.c
./run.sh
mcstop+release.sh ... done
mcreboot.sh -c 4-7 -m 2G ... done
TEST001: OK
TEST002: OK
TEST003: OK
TEST004: OK
TEST005: OK
TEST006: OK
TEST007: OK
TEST008: OK
TEST009: OK
TEST010: OK
TEST011: OK
TEST012: OK
TEST013: OK
TEST014: OK
TEST015: OK
TEST016: OK
TEST017: OK
TEST018: OK
TEST019: OK
TEST020: OK
TEST021: OK
TEST022: OK
TEST023: OK
TEST024: OK

9
test/proc_maps/arm64/run.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
## run.sh COPYRIGHT FUJITSU LIMITED 2018 ##
USELTP=0
USEOSTEST=0
. ../../common.sh
${MCEXEC} ./proc_maps