标签: glibc

以线程安全的方式使用glibc malloc钩子

我想通过使用malloc和free hook监视应用程序中mallocs和frees的使用.

这是文档http://www.gnu.org/s/libc/manual/html_node/Hooks-for-Malloc.html

在示例页面中,您可以看到,my_malloc_hook在重新调用malloc之前,会暂时关闭malloc挂钩(或链中的前一个挂钩).

监视多线程应用程序时这是一个问题(请参阅问题末尾以获得解释).

我在互联网上找到的使用malloc钩子的其他例子也有同样的问题.

有没有办法重新编写此函数以在多线程应用程序中正常工作?

例如,是否有一个内部libc函数,malloc钩子可以调用它来完成分配,而不需要停用我的钩子.

由于公司的法律政策,我无法查看libc源代码,因此答案可能很明显.

我的设计规范说我不能用不同的malloc设计替换malloc.

我可以假设没有其他钩子在玩.


UPDATE

由于在为malloc提供服务时临时删除了malloc钩子,因此另一个线程可能会调用malloc而不是获取钩子.

有人建议malloc有一个很大的锁定来防止这种情况发生,但它没有记录,而且我有效地递归调用malloc的事实表明任何锁必须存在于钩子之后,或者是快活的聪明:

caller -> 
  malloc -> 
    malloc-hook (disables hook) -> 
      malloc -> # possible hazard starts here
        malloc_internals
      malloc <-
    malloc-hook (enables hook) <-
  malloc
caller
Run Code Online (Sandbox Code Playgroud)

c malloc glibc

12
推荐指数
1
解决办法
9316
查看次数

glibc backtrace - 无法将输出重定向到文件

我正在调试一个C程序(我没写过).我启用了所有内部调试工具(一大堆printf),我编写了一个使用proc_open()的小PHP脚本,只抓取stdout和stderr,并将它们在一个文件中进行时间坐标.

目前,二进制文件正在死于一个由glibc捕获的realloc()错误,并且打印了一个glibc backtrace,从以下开始:

*** glibc detected *** /sbin/rsyslogd: realloc(): invalid next size: 0x00002ace626ac910 ***
Run Code Online (Sandbox Code Playgroud)

这是我不明白的事情:我已经确认PHP脚本正在从二进制文件的进程中捕获stdout和stderr并将它们写入正确的文件,但是这个回溯仍然打印到控制台.这是从哪里来的?除了stdout和stderr之外还有一些神奇的输出通道吗?

有关如何将此回溯捕获到文件或使用stderr发送出去的任何想法?

谢谢你,杰森

debugging glibc

12
推荐指数
1
解决办法
1637
查看次数

设置全局gcc默认搜索路径

跑步的时候

arm-none-linux-gnueabi-gcc -print-search-dirs | grep libraries | sed 's/:/\n/g'
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

libraries
 =/opt/codesourcery/lib/gcc/arm-none-linux-gnueabi/4.4.1/
/opt/codesourcery/lib/gcc/arm-none-linux-gnueabi/4.4.1/../../../../arm-none-linux-gnueabi/lib/arm-none-linux-gnueabi/4.4.1/
/opt/codesourcery/lib/gcc/arm-none-linux-gnueabi/4.4.1/../../../../arm-none-linux-gnueabi/lib/
/opt/codesourcery/arm-none-linux-gnueabi/libc/lib/arm-none-linux-gnueabi/4.4.1/
/opt/codesourcery/arm-none-linux-gnueabi/libc/lib/
/opt/codesourcery/arm-none-linux-gnueabi/libc/usr/lib/arm-none-linux-gnueabi/4.4.1/
/opt/codesourcery/arm-none-linux-gnueabi/libc/usr/lib/
Run Code Online (Sandbox Code Playgroud)

当交叉编译一些包时,它会使我的生活更容易附加到这些路径.我知道-L选项,我想使用它,但许多软件包在交叉编译时不尊重它,而且使用它与代码源会导致问题.(有关详细信息,请参阅本文末尾).基本上我有一个完整的目录树,其中包含编译包所需的所有文件,我想将该目录树添加到默认搜索路径中.例如,-print-search-dirs也将输出类似于的路径:

/target/usr/lib
/target/lib
Run Code Online (Sandbox Code Playgroud)

除了已经列出的路径.我不是在寻找一个具有代码性的特定答案,因为我有几个可以使用的工具链.

对于那些好奇的人,这是codeourcery安装的错误:

arm-none-linux-gnueabi-gcc test.c
Run Code Online (Sandbox Code Playgroud)

作品

arm-none-linux-gnueabi-gcc -L/usr/arm-unknown-linux-gnueabi/usr/lib test.c 
Run Code Online (Sandbox Code Playgroud)

失败了:

/lib/libc.so.6: file not recognized: File format not recognized
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

显然它正在抓住主机的libc.我已经看到这种情况发生在一个以上的工具链上,但不是全部.

回应评论: 这是输出

arm-none-linux-gnueabi-gcc -L/usr/arm-unknown-linux-gnueabi/usr/lib test.c -v -Wl,-verbose
Run Code Online (Sandbox Code Playgroud)
Using built-in specs.
Target: arm-none-linux-gnueabi
Configured with: /scratch/julian/2010q1-release-linux-lite/src/gcc-4.4-2010q1/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --enable-extra-sgxxlite-multilibs --with-arch=armv5te --with-gnu-as --with-gnu-ld --with-specs='%{funwind-tables|fno-unwind-tables|mabi=*|ffreestanding|nostdlib:;:-funwind-tables} %{O2:%{!fno-remove-local-statics: -fremove-local-statics}} %{O*:%{O|O0|O1|O2|Os:;:%{!fno-remove-local-statics: -fremove-local-statics}}}' --enable-languages=c,c++ --enable-shared --disable-lto --enable-symvers=gnu …

gcc glibc cross-compiling codesourcery

12
推荐指数
2
解决办法
4万
查看次数

glibc函数检索当前的可执行文件名?

我想知道是否有一个glibc函数,我可以使用gcc/g ++来检索当前的可执行文件.

这样做的目的是提供-e参数, addr2line本答案所示

c gcc glibc addr2line

12
推荐指数
2
解决办法
9016
查看次数

这是拦截系统调用的好方法吗?

我正在写一个工具.该工具的一部分是它能够记录系统调用的参数.好吧,我可以ptrace用于此目的,但ptrace速度很慢.我想到的一种更快的方法是修改glibc.但这变得越来越困难,因为gcc神奇地将自己的内置函数作为系统调用包装器插入,而不是使用glibc中定义的代码.使用-fno-builtin也没有帮助.

所以我提出了编写共享库的想法,其中包括每个系统调用包装器,例如mmap然后在调用实际系统调用包装器函数之前执行日志记录.例如,mmap下面给出了我的样子的伪代码.

int mmap(...)
{
 log_parameters(...);
 call_original_mmap(...);
 ...
}
Run Code Online (Sandbox Code Playgroud)

然后我可以使用LD_PRELOAD首先加载这个库.你觉得这个想法会起作用,还是我错过了什么?

c linux gcc glibc x86-64

12
推荐指数
1
解决办法
1802
查看次数

为什么glibc和pthread库都定义了相同的API?

为什么glibc和pthread库都定义了相同的API?这是快照

ubuntu@ubuntu:/lib$ objdump -T /lib/i386-linux-gnu/libc.so.6 |grep pthread_cond_signal
000f8360 g    DF .text  00000039  GLIBC_2.3.2 pthread_cond_signal
0012b940 g    DF .text  00000039 (GLIBC_2.0)  pthread_cond_signal

ubuntu@ubuntu:/lib$ objdump -T /lib/i386-linux-gnu/libpthread.so.0 |grep pthread_cond_signal
0000b350 g    DF .text  0000007c (GLIBC_2.0)  pthread_cond_signal
0000af90 g    DF .text  000000fc  GLIBC_2.3.2 pthread_cond_signal
Run Code Online (Sandbox Code Playgroud)

linux gcc glibc pthreads

12
推荐指数
1
解决办法
6454
查看次数

ec2服务器postgres错误"找不到版本`GLIBC_2.14'"

尝试\i create_db.sqlpsql时会抛出错误:

psql:create_db.sql:123: ERROR:  could not load library 
"/usr/lib64/pgsql/plpgsql.so": /lib64/libc.so.6: version 
`GLIBC_2.14' not found (required by /usr/lib64/pgsql/plpgsql.so)
Run Code Online (Sandbox Code Playgroud)

create_db.sql的第123行是文件的最后一行,位于函数定义的末尾:

$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)

东西的版本:

$ psql --version
psql (PostgreSQL) 9.2.7

$ /lib64/libc.so.6 --version
GNU C Library (GNU libc) stable release version 2.17, by Roland McGrath et al.
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by …
Run Code Online (Sandbox Code Playgroud)

postgresql glibc libc amazon-ec2 psql

12
推荐指数
1
解决办法
1518
查看次数

在glibc(LD_HWCAP_MASK,/ etc/lt.so.nohwcap)中禁用AVX优化函数以获取valgrind和gdb记录

用glibc现代x86_64的Linux将检测到CPU具有支持AVX扩展,并会从通用实现许多字符串函数切换到AVX优化版(带ifunc调度员的帮助:1,2).

这个功能可以很好地提高性能,但它可以防止像valgrind(较旧的libVEXs,在valgrind-3.8之前)和gdb的" target record"(反向执行)之类的工具正常工作(Ubuntu"Z"17.04 beta,gdb 7.12 .50.20170207-0ubuntu2, gcc 6.3.0-8ubuntu1 20170221,Ubuntu GLIBC 2.24-7ubuntu2):

$ cat a.c
#include <string.h>
#define N 1000
int main(){
        char src[N], dst[N];
        memcpy(dst, src, N);
        return 0;
}
$ gcc a.c -o a -fno-builtin
$ gdb -q ./a
Reading symbols from ./a...(no debugging symbols found)...done.
(gdb) start
Temporary breakpoint 1 at 0x724
Starting program: /home/user/src/a

Temporary breakpoint 1, 0x0000555555554724 in main ()
(gdb) …
Run Code Online (Sandbox Code Playgroud)

linux linker gdb glibc avx

12
推荐指数
2
解决办法
2233
查看次数

为什么fread循环需要额外的Ctrl + D来用glibc发出EOF信号?

通常,为了向连接到Linux终端上的标准输入的程序指示EOF,如果我只按Enter键,则需要按Ctrl + D一次,否则按两次.但我注意到patch命令不同.有了它,如果我按下Enter键,我需要按两次Ctrl + D,否则按三次.(cat | patch相反,如果我在输入任何实际输入之前按下Ctrl + D,它就没有这种奇怪之处.)深入研究patch源代码,我追溯到它的方式循环fread.这是一个做同样事情的最小程序:

#include <stdio.h>

int main(void) {
    char buf[4096];
    size_t charsread;
    while((charsread = fread(buf, 1, sizeof(buf), stdin)) != 0) {
        printf("Read %zu bytes. EOF: %d. Error: %d.\n", charsread, feof(stdin), ferror(stdin));
    }
    printf("Read zero bytes. EOF: %d. Error: %d. Exiting.\n", feof(stdin), ferror(stdin));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在完全按原样编译和运行上述程序时,这是事件的时间表:

  1. 我的程序调用fread.
  2. fread调用read系统调用.
  3. 我输入"asdf".
  4. 我按Enter键.
  5. read系统调用返回5.
  6. freadread再次呼叫系统呼叫.
  7. 我按Ctrl + D.
  8. 该 …

c glibc libc fread eof

12
推荐指数
1
解决办法
278
查看次数

什么是glibc free/malloc/realloc无效的下一个大小/无效指针错误以及如何修复它?

您很可能会看到这个问题,因为您的问题已被关闭,因为它与此相关.有关相关问题的中等完整列表,请参阅可能重复的长列表 -元数据库溢出中的C内存分配和超限界限.


示例问题

来自免费char*:无效的下一个尺寸(快)noobie在2014-04-11 问.

char*在连接过程后释放了一个,但是我收到了这个错误:

free(): invalid next size (fast): 0x0000000001b86170
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

void concat(stringList *list) {
    char *res = (char*)malloc(sizeof(char*));

    strcpy(res, list->head->string);

    list->tmp = list->head->next;
    while (list->tmp != NULL) {
        strcat(res, ",");
        strcat(res, list->tmp->string);
        list->tmp = list->tmp->next;
    }

    printf("%s\n", res);
    free(res);
}
Run Code Online (Sandbox Code Playgroud)

通用问题

运行我的程序时,我看到如下错误消息:

*** glibc detected *** ./a.out: free(): corrupted unsorted chunks: 0x12345678 ***
Run Code Online (Sandbox Code Playgroud)

详细信息可以包含以下任何一个*** glibc detected ***和程序名称之后的消息,后面跟一个十六进制地址(显示为0x12345678)和另一个***:

  • free(): corrupted unsorted chunks: 0x12345678
  • free(): …

c c++ memory glibc

11
推荐指数
1
解决办法
9411
查看次数