У меня есть некоторые проблемы с new
оператор в libstdc++
, Я написал программу на C ++ и у меня были некоторые проблемы с управлением памятью.
После отладки с помощью gdb, чтобы определить, что съедает мой баран, я получил следующее для info proc mappings
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x404000 0x4000 0 /home/sebastian/Developement/powerserverplus-svn/psp-job-distributor/Release/psp-job-distributor
0x604000 0x605000 0x1000 0x4000 /home/sebastian/Developement/powerserverplus-svn/psp-job-distributor/Release/psp-job-distributor
0x605000 0x626000 0x21000 0 [heap]
0x7ffff0000000 0x7ffff0021000 0x21000 0
0x7ffff0021000 0x7ffff4000000 0x3fdf000 0
0x7ffff6c7f000 0x7ffff6c80000 0x1000 0
0x7ffff6c80000 0x7ffff6c83000 0x3000 0
0x7ffff6c83000 0x7ffff6c84000 0x1000 0
0x7ffff6c84000 0x7ffff6c87000 0x3000 0
0x7ffff6c87000 0x7ffff6c88000 0x1000 0
0x7ffff6c88000 0x7ffff6c8b000 0x3000 0
0x7ffff6c8b000 0x7ffff6c8c000 0x1000 0
0x7ffff6c8c000 0x7ffff6c8f000 0x3000 0
0x7ffff6c8f000 0x7ffff6e0f000 0x180000 0 /lib/x86_64-linux-gnu/libc-2.13.so
0x7ffff6e0f000 0x7ffff700f000 0x200000 0x180000 /lib/x86_64-linux-gnu/libc-2.13.so
0x7ffff700f000 0x7ffff7013000 0x4000 0x180000 /lib/x86_64-linux-gnu/libc-2.13.so
0x7ffff7013000 0x7ffff7014000 0x1000 0x184000 /lib/x86_64-linux-gnu/libc-2.13.so
Это просто вырвано из этого. Впрочем, все нормально. Часть этого относится к коду для стандартных библиотек, некоторые, если это куча, а некоторые — секции стека для потоков, которые я создал.
Но. есть один раздел, который я не могу понять, почему он выделен:
0x7ffff0000000 0x7ffff0021000 0x21000 0
0x7ffff0021000 0x7ffff4000000 0x3fdf000 0
Эти два раздела создаются в случайное время. Существует несколько часов отладки без сходства во времени или в определенном созданном потоке или около того. Я установил аппаратную точку наблюдения с awatch *0x7ffff0000000
и дал ему несколько run
Снова
Эти два раздела создаются практически в одно и то же время в одном и том же разделе кода не отлаживаемой функции (GDB показывает это в стеке как in ?? () from /lib/x86_64-linux-gnu/libc.so.6
). Точнее, это пример стека, где это произошло:
#0 0x00007ffff6d091d5 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6d0b2bd in calloc () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff7dee28f in _dl_allocate_tls () from /lib64/ld-linux-x86-64.so.2
#3 0x00007ffff77c0484 in pthread_create@@GLIBC_2.2.5 () from /lib/x86_64-linux-gnu/libpthread.so.0
#4 0x00007ffff79d670e in Thread::start (this=0x6077c0) at ../src/Thread.cpp:42
#5 0x000000000040193d in MultiThreadedServer<JobDistributionServer_Thread>::Main (this=0x7fffffffe170) at /home/sebastian/Developement/powerserverplus-svn/mtserversock/src/MultiThreadedServer.hpp:55
#6 0x0000000000401601 in main (argc=1, argv=0x7fffffffe298) at ../src/main.cpp:29
Другой пример был бы здесь (из другой серии):
#0 0x00007ffff6d091d5 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6d0bc2d in malloc () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff751607d in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x000000000040191b in MultiThreadedServer<JobDistributionServer_Thread>::Main (this=0x7fffffffe170) at /home/sebastian/Developement/powerserverplus-svn/mtserversock/src/MultiThreadedServer.hpp:53
#4 0x0000000000401601 in main (argc=1, argv=0x7fffffffe298) at ../src/main.cpp:29
Все это говорит о том, что это происходит на calloc
вызывается из библиотеки pthread или в другой ситуации это было new operator
или malloc
звонил от этого. Не важно какой new
это — в нескольких сериях это происходило почти в каждом new
или создание потока в моем коде. Единственная «постоянная» вещь с этим — то, что это происходит каждый раз в libc.so.6
,
Независимо от того в какой точке кода,
независимо от того если используется с malloc или calloc,
независимо от того через сколько времени программа запускалась,
независимо от того после того, как сколько потоков было создано,
это всегда тот раздел: 0x7ffff0000000 — 0x7ffff4000000.
Каждый раз, когда программа запускается. Но каждый раз в другой момент в программе. Я действительно смущен, потому что он выделил 67 МБ виртуального пространства, но это не использует это.
При просмотре переменных, которые он там создал, особенно смотрел те, которые создаются при malloc
или же calloc
были вызваны libc, ни одно из этого пространства не используется ими. Они создаются в секции кучи, которая находится далеко от этого диапазона адресов (0x7ffff0000000 — 0x7ffff4000000).
Редактировать:
Я также проверил размер стека родительского процесса и получил 8388608 байт, что составляет 0x800000 (~ 8 МБ). Чтобы получить эти значения я сделал:
pthread_attr_t attr;
size_t stacksize;
struct rlimit rlim;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &stacksize);
getrlimit(RLIMIT_STACK, &rlim);
fit into a size_t variable. */
printf("Resource limit: %zd\n", (size_t) rlim.rlim_cur);
printf("Stacksize: %zd\n", stacksize);
pthread_attr_destroy(&attr);
Пожалуйста, помогите мне с этим. Я действительно смущен этим.
Похоже, он выделяет пространство стека для потока.
Пространство будет использоваться при вызове функции в потоке.
Но на самом деле то, что делает, это не ваше дело. Это часть внутренней реализации pthread_create()
там он может делать все, что ему нравится.
Других решений пока нет …