pcre在设计的时候考虑到线程安全,提供了内存管理回调函数(pcre_malloc, pcre_free),nginx在封装pcre库的时候替换了默认的回调函数,具体代码在src/core/ngx_regex.c
void ngx_regex_init(void) { // 替换回调函数,ngx_regex_malloc会在全局的ngx_pcre_pool上进行内存分配 pcre_malloc = ngx_regex_malloc; pcre_free = ngx_regex_free; }
接下来看ngx_regex_compile
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc) { ............ //ngx_regex_malloc_init会把rc->pool复制给全局ngx_pcre_pool,共ngx_pcre_malloc使用 ngx_regex_malloc_init(rc->pool); re = pcre_compile((const char *) rc->pattern.data, (int) rc->options, &errstr, &erroff, NULL); /* ensure that there is no current pool */ //这里会把ngx_pcre_pool置空 ngx_regex_malloc_done(); ........... }
到这里,我们已经知道了,如果在我们代码中如果直接使用pcre的接口,会调到ngx_pcre_malloc函数,并且全局的ngx_pcre_pool为空,分配内存失败,就出现“failed to get memory”这类错误。
修改方法:
void *(origin_pcre_malloc)(size_t); void *(origin_pcre_free)(void *); origin_pcre_malloc = pcre_malloc; origin_pcre_free = pcre_free; // 匹配逻辑 pcre_malloc = origin_pcre_malloc; pcre_free = orgin_pcre_free;