gpt4 book ai didi

c - 使用 ulimit -s unlimited 的段错误

转载 作者:太空狗 更新时间:2023-10-29 11:49:03 26 4
gpt4 key购买 nike

在 Linux 上,我有一个程序只有在 ulimit -s 设置为无限制时才会崩溃。它发生段错误的地方是在 Libmicrohttpd 的连接回调中,因此回溯非常深(大约 10 个函数被添加)。无论我在此回调中首先调用的函数是什么,它都会崩溃,即使它只是 printf。这是来自 coredump 的堆栈跟踪:

#0  0x000000341fa44089 in vfprintf () from /lib64/libc.so.6
#1 0x000000341fa4ef58 in fprintf () from /lib64/libc.so.6
#2 0x000000000044488d in answer_to_connection (cls=0x7fffc57b0170, connection=0x2b59bc0008c0, url=0x2b59bc000a84 "/remote.html", method=0x2b59bc000a80 "GET", version=0x2b59bc000a9f "HTTP/1.0", upload_data=0x0, upload_data_size=0x2b59b94247b8, con_cls=0x2b59bc000918) at network.c:149
#3 0x00000000004f7f9f in call_connection_handler (connection=connection@entry=0x2b59bc0008c0) at../../../src/microhttpd/connection.c:2284
#4 0x00000000004f92f8 in MHD_connection_handle_idle (connection=connection@entry=0x2b59bc0008c0) at ../../../src/microhttpd/connection.c:3361
#5 0x00000000004fae81 in call_handlers (con=con@entry=0x2b59bc0008c0, read_ready=<optimized out>, write_ready=<optimized out>, force_close=<optimized out>) at ../../../src/microhttpd/daemon.c:1113
#6 0x00000000004fd93b in thread_main_handle_connection (data=0x2b59bc0008c0) at ../../../src/microhttpd/daemon.c:1965
#7 0x0000003420607aa1 in start_thread () from /lib64/libpthread.so.0
#8 0x000000341fae8bcd in clone () from /lib64/libc.so.6

如果我将 ulimit -s 设置为 8192,一切正常。我习惯了必须增加堆栈大小的错误。但为什么它会在较小的堆栈上工作,而在 unlimited 时失败?

编辑:

它肯定与线程有关。简单的例子:

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void function(char arg){
char buffer[666666];

if(arg > 0){
memset(buffer, arg, 6666);
fprintf(stderr, "DONE %p\n", &buffer);
function(arg - 1);
}
}

void *thread(void *arg){
int a;

fprintf(stderr, "THREAD %p\n", &a);

function(6);

return NULL;
}

int main(){
int i;
pthread_t p;

fprintf(stderr, "MAIN %p\n", &i);

pthread_create(&p, NULL, thread, NULL);

pthread_join(p, NULL);
}

使用 ulimit -s 8192 :

$ ./test 
MAIN 0x7ffd73f9cc5c
THREAD 0x7fa4d12bfeac
DONE 0x7fa4d121d250
DONE 0x7fa4d117a600
DONE 0x7fa4d10d79b0
DONE 0x7fa4d1034d60
DONE 0x7fa4d0f92110
DONE 0x7fa4d0eef4c0

使用 ulimit -s unlimited

$ ./test 
MAIN 0x7ffd1438d4dc
THREAD 0x2ab91aef6eac
DONE 0x2ab91ae54250
DONE 0x2ab91adb1600
DONE 0x2ab91ad0e9b0
Segmentation fault (core dumped)

最佳答案

作为Mark Plotnick解释,问题来自线程的默认堆栈大小。 ulimit -s unlimited 为您提供 2MB 的堆栈大小,以今天的标准来看,这是一个很小的大小。

__pthread_initialize_minimal_internal()

中更仔细地查看 pthread 代码
 /* Determine the default allowed stack size.  This is the size used
in case the user does not specify one. */
struct rlimit limit;
if (__getrlimit (RLIMIT_STACK, &limit) != 0
|| limit.rlim_cur == RLIM_INFINITY)
/* The system limit is not usable. Use an architecture-specific
default. */
limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
else if (limit.rlim_cur < PTHREAD_STACK_MIN)
/* The system limit is unusably small.
Use the minimal size acceptable. */
limit.rlim_cur = PTHREAD_STACK_MIN;

/* Make sure it meets the minimum size that allocate_stack
(allocatestack.c) will demand, which depends on the page size. */
const uintptr_t pagesz = GLRO(dl_pagesize);
const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
if (limit.rlim_cur < minstack)
limit.rlim_cur = minstack;

/* Round the resource limit up to page size. */
limit.rlim_cur = ALIGN_UP (limit.rlim_cur, pagesz);
lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
__default_pthread_attr.stacksize = limit.rlim_cur;
__default_pthread_attr.guardsize = GLRO (dl_pagesize);
lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);

pthread_create(3) 的手册页仅提及 Linux/x86-32 的默认堆栈大小,但这里是 glibc 2.3.3 及更高版本中其他架构的值 (ARCH_STACK_DEFAULT_SIZE) :

  • Sparc-32:2MB
  • Sparc-64:4MB
  • PowerPC:4MB
  • S/390 : 2MB
  • IA-64:32MB
  • i386 : 2MB
  • x86_64:2MB

我已经向手册页提交了一个补丁以包含此信息。再次感谢您帮助调查此问题。

关于c - 使用 ulimit -s unlimited 的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49196462/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com