erl_mtrace_sys_wrap.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 245 行
C
245 行
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ */#ifdef HAVE_CONFIG_H# include "config.h"#endif#include "sys.h"#include "erl_mtrace.h"#ifdef ERTS_CAN_TRACK_MALLOC#if defined(HAVE_END_SYMBOL)extern char end;#elif defined(HAVE__END_SYMBOL)extern char _end;#endifstatic int inited = 0;static int init(void);static volatile char *heap_start = NULL;static volatile char *heap_end = NULL;#if defined(ERTS___AFTER_MORECORE_HOOK_CAN_TRACK_MALLOC) /* ----------------- */#ifdef HAVE_MALLOC_H# include <malloc.h>#endif#undef SBRK_0#define SBRK_0 sbrk(0)static voidinit_hook(void){ __after_morecore_hook = erts_mtrace_update_heap_size; if (inited) return; heap_end = NULL;#if defined(HAVE_END_SYMBOL) heap_start = &end;#elif defined(HAVE__END_SYMBOL) heap_start = &_end;#else heap_start = SBRK_0; if (heap_start == (SBRK_RET_TYPE) -1) { heap_start = NULL; return; }#endif inited = 1;}static intinit(void){ init_hook(); return inited;}void (*__malloc_initialize_hook)(void) = init_hook;#elif defined(ERTS_BRK_WRAPPERS_CAN_TRACK_MALLOC) /* ------------------------ */#ifdef HAVE_DLFCN_H# include <dlfcn.h>#endif#undef SBRK_0#define SBRK_0 (*real_sbrk)(0)#ifndef HAVE_SBRK# error no sbrk()#endif#if !defined(HAVE_END_SYMBOL) && !defined(HAVE__END_SYMBOL)# error no 'end' nor '_end'#endifstatic void update_heap_size(char *new_end);#define SBRK_IMPL(RET_TYPE, FUNC, ARG_TYPE) \RET_TYPE FUNC (ARG_TYPE); \static RET_TYPE (*real_ ## FUNC)(ARG_TYPE) = NULL; \RET_TYPE FUNC (ARG_TYPE arg) \{ \ RET_TYPE res; \ if (!inited && !init()) \ return (RET_TYPE) -1; \ res = (*real_ ## FUNC)(arg); \ if (erts_mtrace_enabled && res != ((RET_TYPE) -1)) \ update_heap_size((char *) (*real_ ## FUNC)(0)); \ return res; \}#define BRK_IMPL(RET_TYPE, FUNC, ARG_TYPE) \RET_TYPE FUNC (ARG_TYPE); \static RET_TYPE (*real_ ## FUNC)(ARG_TYPE) = NULL; \RET_TYPE FUNC (ARG_TYPE arg) \{ \ RET_TYPE res; \ if (!inited && !init()) \ return (RET_TYPE) -1; \ res = (*real_ ## FUNC)(arg); \ if (erts_mtrace_enabled && res != ((RET_TYPE) -1)) \ update_heap_size((char *) arg); \ return res; \}SBRK_IMPL(SBRK_RET_TYPE, sbrk, SBRK_ARG_TYPE)#ifdef HAVE_BRK BRK_IMPL(BRK_RET_TYPE, brk, BRK_ARG_TYPE)#endif#ifdef HAVE__SBRK SBRK_IMPL(SBRK_RET_TYPE, _sbrk, SBRK_ARG_TYPE)#endif#ifdef HAVE__BRK BRK_IMPL(BRK_RET_TYPE, _brk, BRK_ARG_TYPE)#endif#ifdef HAVE___SBRK SBRK_IMPL(SBRK_RET_TYPE, __sbrk, SBRK_ARG_TYPE)#endif#ifdef HAVE___BRK BRK_IMPL(BRK_RET_TYPE, __brk, BRK_ARG_TYPE)#endifstatic intinit(void){ if (inited) return 1;#define INIT_XBRK_SYM(SYM) \do { \ if (!real_ ## SYM) { \ real_ ## SYM = dlsym(RTLD_NEXT, #SYM); \ if (!real_ ## SYM) { \ errno = ENOMEM; \ return 0; \ } \ } \} while (0) heap_end = NULL;#if defined(HAVE_END_SYMBOL) heap_start = &end;#elif defined(HAVE__END_SYMBOL) heap_start = &_end;#endif INIT_XBRK_SYM(sbrk);#ifdef HAVE_BRK INIT_XBRK_SYM(brk);#endif#ifdef HAVE__SBRK INIT_XBRK_SYM(_sbrk);#endif#ifdef HAVE__BRK INIT_XBRK_SYM(_brk);#endif#ifdef HAVE___SBRK INIT_XBRK_SYM(__sbrk);#endif#ifdef HAVE___BRK INIT_XBRK_SYM(__brk);#endif return inited = 1;#undef INIT_XBRK_SYM}#endif /* #elif defined(ERTS_BRK_WRAPPERS_CAN_TRACK_MALLOC) */ /* ----------- */static voidupdate_heap_size(char *new_end){ volatile char *new_start, *old_start, *old_end; Uint size; if (new_end == ((char *) -1)) return; new_start = (old_start = heap_start); old_end = heap_end; heap_end = new_end; if (new_end < old_start || !old_start) heap_start = (new_start = new_end); size = (Uint) (new_end - new_start); if (!old_end) { if (size) erts_mtrace_crr_alloc((void *) new_start, ERTS_ALC_A_SYSTEM, ERTS_MTRACE_SEGMENT_ID, size); else heap_end = NULL; } else { if (old_end != new_end || old_start != new_start) { if (size) erts_mtrace_crr_realloc((void *) new_start, ERTS_ALC_A_SYSTEM, ERTS_MTRACE_SEGMENT_ID, (void *) old_start, size); else { if (old_start) erts_mtrace_crr_free(ERTS_ALC_A_SYSTEM, ERTS_MTRACE_SEGMENT_ID, (void *) old_start); heap_end = NULL; } } }}#endif /* #ifdef ERTS_CAN_TRACK_MALLOC */voiderts_mtrace_update_heap_size(void){#ifdef ERTS_CAN_TRACK_MALLOC if (erts_mtrace_enabled && (inited || init())) update_heap_size((char *) SBRK_0);#endif}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?