我正在使用abi::__cxa_demangle API对backtrace_symbols_fd()返回的名称进行解角。我在SIGSEGV的信号处理程序中有这些函数调用。为了避免在进程中segv之后分配内存,我使用了一个自定义分配器,该分配器已经在进程开始时分配了一些内存。我将一个指向此预分配缓冲区的指针作为第二个参数传递给abi::_cxa_demangle。
char* d = abi::__cxa_demangle(mangled, resDemangled, &len, &status);
这里mangled
是函数的变形名称,resDemangled
是一个指向大小为10000的预分配缓冲区的指针,预期在该缓冲区中会得到解变形结果,len
是10000。文档(https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html)指出,“如果output_buffer不够长,则使用realloc扩展”。
我的解Map名称小于100个字符,输出缓冲区为10000个字符,但是函数内部似乎发生了一些动态内存分配,因为在gdb中我到达了调用free的代码行(如下所示):
char * __cxa_demangle (const char *mangled_name, char *output_buffer, size_t *length, int *status) {
...
demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc);
...
if (strlen (demangled) < *length) {
strcpy (output_buffer, demangled);
free (demangled);
demangled = output_buffer;
}
...
}
在gdb中,我无法访问内存分配行或内存重新分配行。我的问题是:
(1)当我将输出缓冲区作为第二个参数传递给__cxa_demangle时,为什么/如何进行堆内存分配,并且缓冲区足够大,可以容纳结果?
(2)更重要的是,是否有一个替代的/现代的API可以用来代替__cxa_demangle,它不动态分配内存。或者,是否有任何方法可以让__cxa_demangle不在堆上动态分配内存?
我被限制在c++17或更少。
1条答案
按热度按时间w41d8nur1#
当我将输出缓冲区作为第二个参数传递给__cxa_demangle时,为什么/如何进行堆内存分配,并且缓冲区足够大,可以容纳结果?
作为demangling实现的一部分,
d_demangle
分配了一个缓冲区。结果被复制到输出缓冲区。由于输出缓冲区足够长,因此不进行realloc
。__cxa_demangle
不承诺在其工作期间不进行分配,或者通常是信号安全的。(2)更重要的是,是否有一个替代的/现代的API可以用来代替__cxa_demangle,它不动态分配内存。或者,是否有任何方法可以让__cxa_demangle不在堆上动态分配内存?
crashpad这样的库可以收集崩溃信息,它们通常尝试在进程外执行此操作。
我被限制在c17或更少。
这超出了标准C的范围。