关键词:MALLOC_CHECK_、mtrace()、muntrace()、MALLOC_TRACE、mprobe()、-lmcheck等等。

1. MALLOC_CHECK_环境变量(double free)

MALLOC_CHECK_提供了类似于mcheck()和mprobe()函数的功能,但是无需对程序进行修改和重新编译。

设置不同整数值可以控制程序对内存分配错误的响应方式。

0 - 不产生错误信息,也不中止这个程序

1 - 产生错误信息,但是不中止这个程序

2 - 不产生错误信息,但是中止这个程序

3 - 产生错误信息,并中止这个程序

下面构造一个double free的错误程序验证一下:

#include <stdio.h>
#include <malloc.h> void main(void)
{
char *s = NULL; s = malloc();
free(s);
free(s);
}

env MALLOC_CHECK_=0 ./dfree的效果类似于直接执行./dfree。

env MALLOC_CHECK_=1 ./dfree产生如下的错误信息:

*** Error in `./dfree': free(): invalid pointer: 0x0000000000e22010 ***

env MALLOC_CHECK_=2 ./dfree简单的终止程序,生成coredump文件。

Aborted (core dumped)

通过分析core文件,然后bt full查看backtrace:

(gdb) bt full
# 0x00007fb4cd69c428 in __GI_raise (sig=sig@entry=) at ../sysdeps/unix/sysv/linux/raise.c:
resultvar =
pid =
selftid =
# 0x00007fb4cd69e02a in __GI_abort () at abort.c:
save_stage =
act = {__sigaction_handler = {sa_handler = 0x0, sa_sigaction = 0x0}, sa_mask = {__val = { <repeats times>, , }}, sa_flags = , sa_restorer = 0x0}
sigs = {__val = {, <repeats times>}}
# 0x00007fb4cd6e6430 in malloc_printerr (ar_ptr=<optimized out>, ptr=<optimized out>, str=<optimized out>, action=<optimized out>) at malloc.c:
No locals.
# free_check (mem=<optimized out>, caller=<optimized out>) at hooks.c:
No locals.
# 0x00007fb4cd6eb5e7 in __GI___libc_free (mem=<optimized out>) at malloc.c:
ar_ptr = <optimized out>
p = <optimized out>
hook = <optimized out>
# 0x000000000040059c in main ()
No symbol table info available.

env MALLOC_CHECK_=3 ./dfree显示更多的信息并且coredump。

*** Error in `./dfree': free(): invalid pointer: 0x0000000000aa0010 ***
======= Backtrace: =========--------------------------------------------------------------------问题点的backtrace。
/lib/x86_64-linux-gnu/libc.so.(+0x777e5)[0x7f640d3447e5]
/lib/x86_64-linux-gnu/libc.so.(+0x7f72a)[0x7f640d34c72a]
/lib/x86_64-linux-gnu/libc.so.(cfree+0xf7)[0x7f640d3515e7]
./dfree[0x40059c]
/lib/x86_64-linux-gnu/libc.so.(__libc_start_main+0xf0)[0x7f640d2ed830]
./dfree[0x400499]
======= Memory map: ========---------------------------------------------------------------------当前进程的maps。
- r-xp : /home/al/test/dfree
- r--p : /home/al/test/dfree
- rw-p : /home/al/test/dfree
00aa0000-00ac1000 rw-p : [heap]
7f640d0b7000-7f640d0cd000 r-xp : /lib/x86_64-linux-gnu/libgcc_s.so.
7f640d0cd000-7f640d2cc000 ---p : /lib/x86_64-linux-gnu/libgcc_s.so.
7f640d2cc000-7f640d2cd000 rw-p : /lib/x86_64-linux-gnu/libgcc_s.so.
7f640d2cd000-7f640d48d000 r-xp : /lib/x86_64-linux-gnu/libc-2.23.so
7f640d48d000-7f640d68d000 ---p 001c0000 : /lib/x86_64-linux-gnu/libc-2.23.so
7f640d68d000-7f640d691000 r--p 001c0000 : /lib/x86_64-linux-gnu/libc-2.23.so
7f640d691000-7f640d693000 rw-p 001c4000 : /lib/x86_64-linux-gnu/libc-2.23.so
7f640d693000-7f640d697000 rw-p :
7f640d697000-7f640d6bd000 r-xp : /lib/x86_64-linux-gnu/ld-2.23.so
7f640d890000-7f640d893000 rw-p :
7f640d8bb000-7f640d8bc000 rw-p :
7f640d8bc000-7f640d8bd000 r--p : /lib/x86_64-linux-gnu/ld-2.23.so
7f640d8bd000-7f640d8be000 rw-p : /lib/x86_64-linux-gnu/ld-2.23.so
7f640d8be000-7f640d8bf000 rw-p :
7ffc0fb27000-7ffc0fb49000 rw-p : [stack]
7ffc0fbb2000-7ffc0fbb5000 r--p : [vvar]
7ffc0fbb5000-7ffc0fbb7000 r-xp : [vdso]
ffffffffff600000-ffffffffff601000 r-xp : [vsyscall]
Aborted (core dumped)

下面是详细的栈信息:

#  0x00007f640d302428 in __GI_raise (sig=sig@entry=) at ../sysdeps/unix/sysv/linux/raise.c:
resultvar =
pid =
selftid =
# 0x00007f640d30402a in __GI_abort () at abort.c:
save_stage =
act = {__sigaction_handler = {sa_handler = 0x2070782d72203030, sa_sigaction = 0x2070782d72203030}, sa_mask = {__val = {, , , ,
, , , , , , , , , ,
, }}, sa_flags = , sa_restorer = 0x48}
sigs = {__val = {, <repeats times>}}
# 0x00007f640d3447ea in __libc_message (do_abort=do_abort@entry=, fmt=fmt@entry=0x7f640d45ded8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:
ap = <error reading variable ap (Attempt to dereference a generic pointer.)>
fd =
on_2 = <optimized out>
list = <optimized out>
nlist = <optimized out>
cp = <optimized out>
written = <optimized out>
# 0x00007f640d34c72a in malloc_printerr (ar_ptr=0x7f640d691b20 <main_arena>, ptr=<optimized out>, str=0x7f640d45acaf "free(): invalid pointer", action=<optimized out>) at malloc.c:
buf = "0000000000aa0010"
cp = <optimized out>
ar_ptr = 0x7f640d691b20 <main_arena>
ptr = <optimized out>
str = 0x7f640d45acaf "free(): invalid pointer"
action = <optimized out>
# free_check (mem=<optimized out>, caller=<optimized out>) at hooks.c:
No locals.
# 0x00007f640d3515e7 in __GI___libc_free (mem=<optimized out>) at malloc.c:
ar_ptr = <optimized out>
p = <optimized out>
hook = <optimized out>
# 0x000000000040059c in main ()
No symbol table info available.

2. mtrace/muntrace/MALLOC_TRACE(重复释放、泄漏)

mtrace()和muntrace()函数分别在程序中打开和关闭对内存分配调用进行跟踪的功能。

这两个函数要与环境变量MALLOC_TRACE搭配使用,该变量定义了写入跟踪信息的文件名。

2.1 构造测试用例

构造malloc()但是不释放的场景:

#include <stdlib.h>
#include <stdio.h>
#include <mcheck.h> int main(int argc, char **argv)
{
mtrace(); char * p = malloc();
free(p); p = malloc(); muntrace(); return ;
}

2.2 mtrace()跟踪结果分析

gcc mtrace.c -o mtrace -g编译带调试信息。

export MALLOC_TRACE=/home/al/test/mtrace.log设置mtrace()信息输出路径。

然后执行./mtrace,就会在MALLOC_TRACE下生成malloc()/free()轨迹信息。

= Start
@ ./mtrace:[0x400624] + 0x10b4450 0x64
@ ./mtrace:[0x400634] - 0x10b4450
@ ./mtrace:[0x40063e] + 0x10b44c0 0x3e8
= End

上面的信息格式为:@ 程序名称:[内存分配释放调用的地址] +/- 操作的内存地址 参数

+表示malloc,-表示free。

或者如下类型log:

@ 程序名称:(函数名称+偏移量) [内存分配释放调用地址] +/-/</> 操作内存地址 参数

+:对应一个malloc()操作。

-:对应一个free()操作。

</>:对应一个realloc()操作,成对出现。<表示释放之前内存,>表示申请后结果。如果realloc()的内存第一次申请,那么就对应一个+号。

@ /usr/lib/libglib-2.0.so.:(g_malloc+0x2a)[0x2ac7c412] + 0x2b510f50 0x3------------------------g_malloc()中申请0x3字节大小内存,返回地址为0x2b510f50。
@ /usr/lib/libglib-2.0.so.:(g_realloc+0x38)[0x2ac7c4cc] + 0x2b510f60 0x20----------------------g_realloc()指针之前没有对应内存,所以对应+。表示申请0x20字节大小内存,返回地址为0x2b510f60。
@ /usr/lib/libglib-2.0.so.:(g_free+0x20)[0x2ac7c524] - 0x2b510f40
@ /usr/lib/libglib-2.0.so.:(g_malloc+0x2a)[0x2ac7c412] + 0x2b510f40 0xc------------------------在g_malloc()中申请0xc字节大小内存,返回地址为0x2b510f40.
@ /usr/lib/libglib-2.0.so.:(g_malloc+0x2a)[0x2ac7c412] + 0x2b510f88 0xc
@ /usr/lib/libglib-2.0.so.:(g_realloc+0x38)[0x2ac7c4cc] < 0x2b510f60---------------------------g_realloc()对应的内存已经存在,所以先释放0x2b510f60内存。
@ /usr/lib/libglib-2.0.so.:(g_realloc+0x38)[0x2ac7c4cc] > 0x2b510f98 0x40----------------------然后重新申请0x40大小的内存,返回地址为0x2b50f98.
@ /usr/lib/libglib-2.0.so.:(g_free+0x20)[0x2ac7c524] - 0x2b510f40------------------------------在g_free()中释放地址为0x2b510f40的内存。
@ /usr/lib/libglib-2.0.so.:(g_realloc+0x38)[0x2ac7c4cc] < 0x2b510f98---------------------------g_realoc()对应内存已经存在,释放0x2b510f98对应内存。
@ /usr/lib/libglib-2.0.so.:(g_realloc+0x38)[0x2ac7c4cc] > 0x2b513660 0x80----------------------然后重新申请0x80大小内存,返回地址为0x2b513660。

通过mtrace mtrace mtrace.log可以可读性更强的信息。第一个mtrace是解析mtrace.log的工具,第二个mtrace是测试程序。

Memory not freed:
-----------------
Address Size Caller
0x00000000010b44c0 0x3e8 at /home/al/test/mtrace.c:

这里面对过滤掉正常malloc()/free()信息,留下的是泄漏内存。

Address表示泄漏地址,Size表示泄漏大小,Caller表示泄漏点代码位置。

2.3 重复释放问题

如下是重复释放问题,mtrace()会如何处理呢?

#include <stdio.h>
#include <malloc.h>
#include <mcheck.h> void main(void)
{
char *s = NULL;
mtrace();
s = malloc();
free(s);
free(s);
muntrace();
}

执行./dfree结果如下:

*** Error in `./dfree': double free or corruption (fasttop): 0x000000000188b450 ***

2.4 mtrace输出解释

mtrace输出结果还有一些可能不是异常的提示。

= Start
[0x8048209] - 0x8064cc8
[0x8048209] - 0x8064ce0
[0x8048209] - 0x8064cf8
[0x80481eb] + 0x8064c48 0x14
[0x80481eb] + 0x8064c60 0x14
[0x80481eb] + 0x8064c78 0x14
[0x80481eb] + 0x8064c90 0x14
= End

输出结果如下:

- 0x08064cc8 Free  was never alloc'd /home/drepper/tst.c:39
- 0x08064ce0 Free was never alloc'd /home/drepper/tst.c:39
- 0x08064cf8 Free was never alloc'd /home/drepper/tst.c:39
(-表示free异常) (free内存对应指针) Free (在原log中的行号) was never alloc'd (free函数调用点) Memory not freed:
-----------------
Address Size Caller
0x08064c48 0x14 at /home/drepper/tst.c:
0x08064c60 0x14 at /home/drepper/tst.c:
0x08064c78 0x14 at /home/drepper/tst.c:
0x08064c90 0x14 at /home/drepper/tst.c:

参考资料:《3.2.4.4 Interpreting the traces》。

- 0x000000000002ba00 Realloc  was never alloc'd 0x2af654bc
(-表示释放) (free对应内存地址) Realloc (在log中行号) was never alloc'd (free释放点)

realloc()首先释放然后重新申请内存,表示在realloc()释放内存的时候没有找到对应的alloc()。

+ 0x000000000006ea48 Alloc  duplicate: 0x2b2ef800 /lib/libstdc++.so.:(_Znwj+0x24)[0x2b2ef800]
(+表示alloc()) (alloc()内存地址) Alloc (在log中行号) duplicate: (alloc()调用点)

表示两次alloc两次,申请的内存地址是一样的。前一次alloc()到本次alloc()之间没有free。

3. mcheck()检查内存一致性(重复释放、越界)

mcheck()函数允许程序对已分配内存块进行一致性检查。

3.1 mcheck()介绍

#include <mcheck.h>

int mcheck(void (*abortfunc)(enum mcheck_status mstatus));

调用该函数后,后续内存分配、释放都将进行内存连续性检查,并在内存连续性检查失败后,调用abortfunc。

枚举体mcheck_status如下:

enum mcheck_status
{
MCHECK_DISABLED = -, /* Consistency checking is not turned on. */
MCHECK_OK, /* Block is fine. */
MCHECK_FREE, /* Block freed twice. */
MCHECK_HEAD, /* Memory before the block was clobbered. */
MCHECK_TAIL /* Memory after the block was clobbered. */
};

3.2 mcheck()实例

下例创建捕获错误函数abortfun(),三种你错误类型:重复释放、头覆盖、尾覆盖。

#include <stdio.h>
#include <malloc.h>
#include <mcheck.h>
#include <errno.h>
#include <string.h> void abortfun(enum mcheck_status mstatus)
{
if(mstatus == MCHECK_FREE)
fprintf(stderr, "Block freed twice.\n");
else if(mstatus == MCHECK_HEAD)
fprintf(stderr, "Memory before the block was clobbered.\n");
else if(mstatus == MCHECK_TAIL)
fprintf(stderr, "Memory after the block was clobbered.\n");
else
fprintf(stderr, "Block is fine.\n");
} void main(void)
{
char *s = NULL; if(mcheck(abortfun) != )
{
fprintf(stderr, "mcheck:%s\n", strerror(errno));
return;
}
s = malloc();
*(s-) = ;--------------------------头覆盖。
*(s+) = ;-------------------------尾覆盖。
free(s);
free(s);-----------------------------重复释放。
}

执行后结果如下,捕获到了尾覆盖和重复释放,头覆盖没有捕获到;但是单独头覆盖是可以捕获到的。

并且产生了coredump文件。

Memory after the block was clobbered.
Block freed twice.
*** Error in `./dfree': double free or corruption (fasttop): 0x0000000000957030 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.(+0x777e5)[0x7fc2eac267e5]
/lib/x86_64-linux-gnu/libc.so.(+0x8037a)[0x7fc2eac2f37a]
/lib/x86_64-linux-gnu/libc.so.(cfree+0x4c)[0x7fc2eac3353c]
/lib/x86_64-linux-gnu/libc.so.(+0x87fa0)[0x7fc2eac36fa0]
/lib/x86_64-linux-gnu/libc.so.(cfree+0xf7)[0x7fc2eac335e7]
./dfree[0x40084a]
/lib/x86_64-linux-gnu/libc.so.(__libc_start_main+0xf0)[0x7fc2eabcf830]
./dfree[0x400659]
======= Memory map: ========
- r-xp : /home/al/test/dfree
- r--p : /home/al/test/dfree
- rw-p : /home/al/test/dfree
- rw-p : [heap]
7fc2e4000000-7fc2e4021000 rw-p :
7fc2e4021000-7fc2e8000000 ---p :
7fc2ea999000-7fc2ea9af000 r-xp : /lib/x86_64-linux-gnu/libgcc_s.so.
7fc2ea9af000-7fc2eabae000 ---p : /lib/x86_64-linux-gnu/libgcc_s.so.
7fc2eabae000-7fc2eabaf000 rw-p : /lib/x86_64-linux-gnu/libgcc_s.so.
7fc2eabaf000-7fc2ead6f000 r-xp : /lib/x86_64-linux-gnu/libc-2.23.so
7fc2ead6f000-7fc2eaf6f000 ---p 001c0000 : /lib/x86_64-linux-gnu/libc-2.23.so
7fc2eaf6f000-7fc2eaf73000 r--p 001c0000 : /lib/x86_64-linux-gnu/libc-2.23.so
7fc2eaf73000-7fc2eaf75000 rw-p 001c4000 : /lib/x86_64-linux-gnu/libc-2.23.so
7fc2eaf75000-7fc2eaf79000 rw-p :
7fc2eaf79000-7fc2eaf9f000 r-xp : /lib/x86_64-linux-gnu/ld-2.23.so
7fc2eb172000-7fc2eb175000 rw-p :
7fc2eb19d000-7fc2eb19e000 rw-p :
7fc2eb19e000-7fc2eb19f000 r--p : /lib/x86_64-linux-gnu/ld-2.23.so
7fc2eb19f000-7fc2eb1a0000 rw-p : /lib/x86_64-linux-gnu/ld-2.23.so
7fc2eb1a0000-7fc2eb1a1000 rw-p :
7ffcc5840000-7ffcc5862000 rw-p : [stack]
7ffcc58df000-7ffcc58e2000 r--p : [vvar]
7ffcc58e2000-7ffcc58e4000 r-xp : [vdso]
ffffffffff600000-ffffffffff601000 r-xp : [vsyscall]
Aborted (core dumped)

4. mprobe()

函数格式介绍:

#include <mcheck.h>

enum mcheck_status mprobe(void *ptr);

mprobe()示例:

#include <stdio.h>
#include <malloc.h>
#include <mcheck.h>
#include <errno.h>
#include <string.h> void abortfun(enum mcheck_status mstatus)
{
if(mstatus == MCHECK_FREE)
fprintf(stderr, "Block freed twice.\n");
else if(mstatus == MCHECK_HEAD)
fprintf(stderr, "Memory before the block was clobbered.\n");
else if(mstatus == MCHECK_TAIL)
fprintf(stderr, "Memory after the block was clobbered.\n");
else
fprintf(stderr, "Block is fine.\n");
} void main(void)
{
char *s = NULL; if(mcheck(abortfun) != )
{
fprintf(stderr, "mcheck:%s\n", strerror(errno));
return;
}
s = malloc();
mprobe(s);------------------------------正确
mprobe(s-);----------------------------错误,返回MCHECK_HEAD错误类型。
mprobe(s+);---------------------------错误,返回MCHECK_HEAD错误类型。
free(s);
}

返回结果:

Memory before the block was clobbered.
Memory before the block was clobbered.

5. -lmcheck自动开启检查

在编译的时候加上-lmcheck,不需要修改代码就可以对malloc()/free()进行检查。

#include <stdio.h>
#include <malloc.h> void main(void)
{
char *s = NULL; s = malloc();
free(s);
free(s);
}

gcc dfree.c -o dfree -lmcheck编译后,执行./dfree。

block freed twice
Aborted (core dumped)

查看coredump bt full如下:

#  0x00007fdf1e826428 in __GI_raise (sig=sig@entry=) at ../sysdeps/unix/sysv/linux/raise.c:
resultvar =
pid =
selftid =
# 0x00007fdf1e82802a in __GI_abort () at abort.c:
save_stage =
act = {__sigaction_handler = {sa_handler = 0x3065383363666637, sa_sigaction = 0x3065383363666637}, sa_mask = {__val = {, , , ,
, , , , , , , , , ,
, }}, sa_flags = , sa_restorer = 0x54}
sigs = {__val = {, <repeats times>}}
# 0x00007fdf1e8687ea in __libc_message (do_abort=do_abort@entry=, fmt=fmt@entry=0x7fdf1e981ed8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:
ap = <error reading variable ap (Attempt to dereference a generic pointer.)>
fd =
on_2 = <optimized out>
list = <optimized out>
nlist = <optimized out>
cp = <optimized out>
written = <optimized out>
# 0x00007fdf1e87137a in malloc_printerr (ar_ptr=<optimized out>, ptr=<optimized out>, str=0x7fdf1e981fa0 "double free or corruption (fasttop)", action=) at malloc.c:
buf = "000000000186a010"
cp = <optimized out>
ar_ptr = <optimized out>
str = 0x7fdf1e981fa0 "double free or corruption (fasttop)"
action =
# _int_free (av=<optimized out>, p=<optimized out>, have_lock=) at malloc.c:
size = <optimized out>
fb = <optimized out>
nextchunk = <optimized out>
nextsize = <optimized out>
nextinuse = <optimized out>
prevsize = <optimized out>
bck = <optimized out>
fwd = <optimized out>
errstr = <optimized out>
locked = <optimized out>
# 0x00007fdf1e87553c in __GI___libc_free (mem=<optimized out>) at malloc.c:
ar_ptr = <optimized out>
p = <optimized out>
hook = <optimized out>
# 0x000000000040059c in register_tm_clones ()
No symbol table info available.
# 0x00007ffc38dc54c0 in ?? ()
No symbol table info available.
# 0x000000000186a010 in ?? ()
No symbol table info available.
# 0x00000000004005a0 in register_tm_clones ()
No symbol table info available.
# 0x00007fdf1e811830 in __libc_start_main (main=0x400566 <deregister_tm_clones+>, argc=, argv=0x7ffc38dc54c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffc38dc54b8)
at ../csu/libc-start.c:
result = <optimized out>
unwind_buf = {cancel_jmp_buf = {{jmp_buf = {, , , , , , -, -}, mask_was_saved = }}, priv = {pad = {0x0, 0x0, 0x400610 <main+>,
0x7fdf1ebcbab0 <_dl_fini>}, data = {prev = 0x0, cleanup = 0x0, canceltype = }}}
not_first_call = <optimized out>
# 0x0000000000400499 in ?? ()
No symbol table info available.
# 0x00007ffc38dc54b8 in ?? ()
No symbol table info available.
# 0x000000000000001c in ?? ()
No symbol table info available.
# 0x0000000000000001 in ?? ()
No symbol table info available.
# 0x00007ffc38dc5fba in ?? ()
No symbol table info available.
# 0x0000000000000000 in ?? ()
No symbol table info available.

6. 小结

对比以上几个内存你检查手段:MALLOC_CHECK_最简单,其次是-lmcheck,最后是mtrace()/muntrace()、mcheck()、mprobe()。

但是这几种技术检查的全面性都不够,没有一种能够全面检查内存泄漏、内存踩踏、重复释放的。

要想全面的检查还是需要Valgrind这种技术,参考《valgrind使用方法》。

参考文档:《mtrace-内存使用追踪(内存)》、《mcheck 函数使用(glibc-3-内存)

glibc提供的malloc()的调试工具的更多相关文章

  1. 几个系统调用分析 glibc中的malloc调用和共享内存原理

    本文主要分析内存以及I/O相关的系统调用和库函数的实现原理,根据原理给出在使用过程中需要注意的问题和优化的侧重点,本文涉及到的系统调用包括readahead,pread/pwrite,read/wri ...

  2. Libheap:一款用于分析Glibc堆结构的GDB调试工具

    Libheap是一个用于在Linux平台上分析glibc堆结构的GDB调试脚本,使用Python语言编写.         安装 Glibc安装 尽管Libheap不要求glibc使用GDB调试支持和 ...

  3. python 内存问题(glibc库的malloc相关)

    题记: 这是工作以来困扰我最久的问题.python 进程内存占用问题. 经过长时间断断续续的研究,终于有了一些结果. 项目(IM服务器)中是以C做底层驱动python代码,主要是用C完成 网络交互部分 ...

  4. 内存优化总结:ptmalloc、tcmalloc和jemalloc(转)

    转载于:http://www.cnhalo.net/2016/06/13/memory-optimize/ 概述 需求 系统的物理内存是有限的,而对内存的需求是变化的, 程序的动态性越强,内存管理就越 ...

  5. Linux下库打桩机制分析 function Interposition

    [时间:2017-08] [状态:Open] [关键词:linux, libray,打桩,interposition,函数替换,链接器,gcc,malloc,free] 0 引言 本文主要参考< ...

  6. ptmalloc、tcmalloc和jemalloc

    内存优化总结:ptmalloc.tcmalloc和jemalloc 转载 2017年09月05日 18:57:12 3674 转载于:http://www.cnhalo.net/2016/06/13/ ...

  7. 内存优化总结:ptmalloc、tcmalloc和jemalloc

    概述 需求 系统的物理内存是有限的,而对内存的需求是变化的, 程序的动态性越强,内存管理就越重要,选择合适的内存管理算法会带来明显的性能提升.比如nginx, 它在每个连接accept后会malloc ...

  8. linux调试工具glibc的演示分析-core dump double free【转】

    转自:http://www.cnblogs.com/jiayy/p/3475544.html 偶然中发现,下面的两端代码表现不一样 void main(){ void* p1 = malloc(32) ...

  9. linux调试工具glibc的演示分析

    偶然中发现,下面的两端代码表现不一样 void main(){ void* p1 = malloc(32);       free(p1); free(p1); // 这里会报double free ...

随机推荐

  1. YII2中andWhere多个or查询

    使用多个or的复杂查询: AND ((`name`='张三') OR (`name`='李四') OR (`name`='王五')) // AND ((`name`='张三') OR (`name`= ...

  2. CefSharp 无法输入中文的问题

    在CefSharp75版本,使用了WpfImeKeyboardHandler支持后,无法支持搜狗中文输入法 其中的一个修复方案: 在ChrominumWebBrowser中,添加焦点事件的重写,对In ...

  3. Dynamics 365中的分派(Assign)。

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  4. Zstack的安装部署

    ZStack是下一代开源的云计算IaaS(基础架构即服务)软件. 它主要面向的是未来的智能数据中心,通过提供全完善的API来管理包括计算.存储和网络在内的数据中心的各种资源.跟OpenStack相比, ...

  5. IP安全,DDoS攻击、tearDrop攻击和微小IP碎片攻击

    目录 arp安全 IP报文格式 DoS攻击 tear drop攻击 微小碎片攻击 IP欺骗,留后门 arp安全 以太网帧的type =0806 表示arp arp攻击:hack伪造arp应答包给tar ...

  6. Oracle GoldenGate常用参数详解

    Oracle GoldenGate常用参数详解http://blog.itpub.net/28389881/viewspace-2564461/

  7. [Go] 使用net包作为tcp客户端读取http

    1.tcp的客户端,并且直接读取http协议的全部内容,每次读取4096字节,直到最后一个字节是\n并且读取的长度小于4096 conn, err := net.Dial("tcp" ...

  8. C语言 复习函数

    什么是函数呢? 首先函数是在完成特定任务的程序代码中,拥有自己独立的单元. 举个例子 “你可以拿本书吗?” ”你可以拿本语文书吗?“ “你可以拿苹果吗?”..... 如果要是放到程序里面估计要重复很多 ...

  9. Linux下动态切换EHCI控制器下端口的速率(即切换为12M)

    在sys目录下找到对应的控制器 例如:/sys/devices/platform/soc/ehci,直接操作该目录下的companion echo 1  > companion  将port1设 ...

  10. Vue小练习 03

    """ 1.有以下广告数据(实际数据命名可以略做调整) ad_data = { tv: [ {img: 'img/tv/tv1.jpg', title: 'tv1'}, ...