Skip to content

LA glibc下libcbench测例b_pthread_create_serial1测试项设置了非法线程栈大小 #47

@yuanmu2004

Description

@yuanmu2004

在测试LoongArch glibc的libcbench测例时发现爆内存,经检查是mmap映射了过多的虚拟地址空间所致,内核打印的调试信息中包含数条以下调试信息:

[sys_mmap] addr:0x0, length:0x801000, prot:MmapProt(0x0), flags:MmapFlags(MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK), fd:18446744073709551615, offset:0x0

阅读位于 libc-bench/pthread.c:35的源码可知,该测试项创建了2500个线程,并意图为每个线程分配16384字节大小的栈空间。pthread_create使用mmap系统调用分配线程栈,在用户为attr设置了栈大小stacksize的情况下,mmap系统调用的length参数理应为stacksize+guardsize,这与实际情况不符。

阅读glibc代码发现,在测例调用pthread_attr_setstacksize时,glibc设置attr中的stacksize字段前,会检查传入的stacksize是否大于等于PTHREAD_STACK_MIN(参见nptl/pthread_attr_setstacksize.c),这个值在LA架构下等于131072。不满足时不修改attr->stacksize字段并返回错误码。在线程创建时,attr->stacksize仍为缺省值,故glibc使用默认的__default_pthread_attr.internal.stacksize,这个值在__pthread_early_init中被初始化为rlimit_stack,这个值在我们内核的设计中是8MB。我们尝试修改了prlimit64系统调用的返回值,观察到mmap分配的内核栈大小也改变了,验证了这一猜想。

对libc-bench进行反汇编,也能验证这个猜想。以下是pthread_attr_setstacksize的汇编代码:

000000012001a954 <__pthread_attr_setstacksize>:
check_stacksize_attr():
/home/airxs/user/gnu/build-cross-tools-hf/glibc-2.38/nptl/../sysdeps/nptl/pthreadP.h:707
   12001a954:	1400040c 	lu12i.w     	$t0, 32
   12001a958:	6c000cac 	bgeu        	$a1, $t0, 12	# 12001a964 <__pthread_attr_setstacksize+0x10>
__pthread_attr_setstacksize():
/home/airxs/user/gnu/build-cross-tools-hf/glibc-2.38/nptl/pthread_attr_setstacksize.c:38
   12001a95c:	02805804 	li.w        	$a0, 22
/home/airxs/user/gnu/build-cross-tools-hf/glibc-2.38/nptl/pthread_attr_setstacksize.c:43
   12001a960:	4c000020 	ret
/home/airxs/user/gnu/build-cross-tools-hf/glibc-2.38/nptl/pthread_attr_setstacksize.c:40
   12001a964:	29c08085 	st.d        	$a1, $a0, 32
/home/airxs/user/gnu/build-cross-tools-hf/glibc-2.38/nptl/pthread_attr_setstacksize.c:42
   12001a968:	00150004 	move        	$a0, $zero
   12001a96c:	4c000020 	ret

第一行lu12i.w $t0, 32,便是glibc中LA架构的PTHREAD_STACK_MIN值131072。

这个问题可能导致大多数队伍使用正常手段无法通过LA架构glibc的libc-bench测例,希望老师能修复这个问题。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions