c++ abi::__cxa_demangle,无动态内存分配/解除分配

5jvtdoz2  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(599)

我正在使用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或更少。

w41d8nur

w41d8nur1#

当我将输出缓冲区作为第二个参数传递给__cxa_demangle时,为什么/如何进行堆内存分配,并且缓冲区足够大,可以容纳结果?
作为demangling实现的一部分,d_demangle分配了一个缓冲区。结果被复制到输出缓冲区。由于输出缓冲区足够长,因此不进行realloc
__cxa_demangle不承诺在其工作期间不进行分配,或者通常是信号安全的。
(2)更重要的是,是否有一个替代的/现代的API可以用来代替__cxa_demangle,它不动态分配内存。或者,是否有任何方法可以让__cxa_demangle不在堆上动态分配内存?
crashpad这样的库可以收集崩溃信息,它们通常尝试在进程外执行此操作。
我被限制在c17或更少。
这超出了标准C
的范围。

相关问题