allocator
来源:互联网 发布:java cas原理 编辑:程序博客网 时间:2024/05/06 13:51
替换CRT堆处理函数
base/allocator 中有个python文件用于处理VS中libcmt.lib静态库中堆的处理函数,将其obj文件去除,这对于我来说是一个比较新颖的思路,一直以为只有hook才是一个方案,没想到这种静态链接的方法也是不错的。
import osimport shutilimport subprocessimport sysdef run(command, env_dict): """Run |command|. If any lines that match an error condition then terminate. The env_dict, will be used for the environment. None can be used to get the default environment.""" error = 'cannot find member object' # Need shell=True to search the path in env_dict for the executable. popen = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, env=env_dict) out, _ = popen.communicate() for line in out.splitlines(): print line if error and line.find(error) != -1: print 'prep_libc.py: Error stripping object from C runtime.' sys.exit(1)def main(): bindir = 'SELF_X86' objdir = 'INTEL' vs_install_dir = sys.argv[1] outdir = sys.argv[2] if "x64" in sys.argv[3]: bindir = 'SELF_64_amd64' objdir = 'amd64' vs_install_dir = os.path.join(vs_install_dir, 'amd64') if len(sys.argv) == 5: env_pairs = open(sys.argv[4]).read()[:-2].split('\0') env_dict = dict([item.split('=', 1) for item in env_pairs]) else: env_dict = None # Use the default environment. output_lib = os.path.join(outdir, 'libcmt.lib') shutil.copyfile(os.path.join(vs_install_dir, 'libcmt.lib'), output_lib) shutil.copyfile(os.path.join(vs_install_dir, 'libcmt.pdb'), os.path.join(outdir, 'libcmt.pdb')) cvspath = 'f:\\binaries\\Intermediate\\vctools\\crt_bld\\' + bindir + \ '\\crt\\prebuild\\build\\' + objdir + '\\mt_obj\\nativec\\\\'; cppvspath = 'f:\\binaries\\Intermediate\\vctools\\crt_bld\\' + bindir + \ '\\crt\\prebuild\\build\\' + objdir + '\\mt_obj\\nativecpp\\\\'; cobjfiles = ['malloc', 'free', 'realloc', 'heapinit', 'calloc', 'recalloc', 'calloc_impl'] cppobjfiles = ['new', 'new2', 'delete', 'delete2', 'new_mode', 'newopnt', 'newaopnt'] for obj in cobjfiles: cmd = ('lib /nologo /ignore:4006,4221 /remove:%s%s.obj %s' % (cvspath, obj, output_lib)) run(cmd, env_dict) for obj in cppobjfiles: cmd = ('lib /nologo /ignore:4006,4221 /remove:%s%s.obj %s' % (cppvspath, obj, output_lib)) run(cmd, env_dict)if __name__ == "__main__": sys.exit(main())
这是python语言,核心语句是要执行下面这个命令:
cmd = ('lib /nologo /ignore:4006,4221 /remove:%s%s.obj %s' % (cvspath, obj, output_lib))
主要的方式就是移除堆管理的obj数据。这里不深挖具体怎么处理,因为目前暂时遇不到这种情况,只是作为一个了解。
堆的管理
那么chromium接管了系统的heap处理后,他是要干什么呢,进行了那些优化呢,chromium如下这样注释,似乎表明了它的用意。
// Heap functions are stripped from libcmt.lib using the prep_libc.py// for each object file stripped, we re-implement them here to allow us to// perform additional checks:// 1. Enforcing the maximum size that can be allocated to 2Gb.// 2. Calling new_handler if malloc fails.
其实接管系统的heap处理,如果在Linux平台下是可以直接使用tcmalloc来接替内存申请,然而在window平台还是接着使用默认系统堆内存。
我们来看看它是如何接管内存处理的,先看堆的初始化
int _heap_init() { base::allocator::g_is_win_shim_layer_initialized = true; return win_heap_init() ? 1 : 0;}// VS2013 crt uses the process heap as its heap, so we do the same here.// See heapinit.c in VS CRT sources.bool win_heap_init() { // Set the _crtheap global here. THis allows us to offload most of the // memory management to the CRT, except the functions we need to shim. _crtheap = GetProcessHeap(); if (_crtheap == NULL) return false; ULONG enable_lfh = 2; // NOTE: Setting LFH may fail. Vista already has it enabled. // And under the debugger, it won't use LFH. So we // ignore any errors. HeapSetInformation(_crtheap, HeapCompatibilityInformation, &enable_lfh, sizeof(enable_lfh)); return true;}
这里默认设置LFH堆属性,使用进程堆,那么堆又是如何申请的呢
// Call the new handler, if one has been set.// Returns true on successfully calling the handler, false otherwise.inline bool call_new_handler(bool nothrow, size_t size) { // Get the current new handler. _PNH nh = _query_new_handler();#if defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS if (!nh) return false; // Since exceptions are disabled, we don't really know if new_handler // failed. Assume it will abort if it fails. return nh(size);#else#error "Exceptions in allocator shim are not supported!"#endif // defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS return false;}// Implement a C++ style allocation, which always calls the new_handler// on failure.inline void* generic_cpp_alloc(size_t size, bool nothrow) { void* ptr; for (;;) { ptr = malloc(size); if (ptr) return ptr; if (!call_new_handler(nothrow, size)) break; } return ptr;}// new.cppvoid* operator new(size_t size) { return generic_cpp_alloc(size, false);}// delete.cppvoid operator delete(void* p) throw() { free(p);}
这里和CRT的实现已经无什么差异了。
0 0
- allocator
- allocator
- allocator
- allocator
- allocator
- slab allocator
- C++ Allocator
- allocator使用
- C++ Allocator
- hash_map && allocator
- Allocator rebind
- bootmem allocator
- 理解allocator
- std allocator
- Slab Allocator
- allocator类
- C++ Allocator
- C++ allocator
- 越努力,越幸运
- 更牛的开源
- eclipse tasks 过滤
- 数据库报错说明( Every derived table must have its own alias)
- 学会接受与拒绝
- allocator
- 面试总结
- Java 用POST方式 传对象给 Servlet
- Git
- c++实验6——项目3——矩阵求和
- Imageloader在listview/gridview中scroll滚动时图片重载的问题及解决
- Python中dict详解
- Java面试集锦
- 【bzoj3576】【HNOI2014】江南乐