Nginxhttpfilter异常排查
问题:
访问异常
root@cloud:/usr/local/nginx#curl-ihttp://localhost/test.html
curl:(52)Emptyreplyfromserver
错误日志
2016/09/1113:17:03[alert]63560#0:workerprocess63663exitedonsignal11(coredumped)
dmesg信息
[265950.220943]nginx[63663]:segfaultat128ip000000000048259dsp00007ffde898eab0error4innginx[400000+a5000]
coredump设置
默认Worker进程用户nobody:nogroup,无法写coredump.需在nginx.conf配置:
worker_rlimit_core1024m;#1G
working_directory/tmp/core#保证nobody:nogroup有W权限
执行"sbin/nginx-sreload"重新加载配置。
coredump分析
使用readelf工具
coredump是ELF格式文件,你可以用readelf-a查看coredump文件,但哪只是一堆数据。
使用gdb工具
gdb
一般会直接显示出错的代码位置
位置1
conf=ngx_http_conf_get_module_loc_conf(r,ngx_http_myfilter_module);#应该是ngx_http_get_module_loc_conf(...)
位置2
myfilter_ctx_tctx;
ctx=ngx_http_get_module_ctx(r,ngx_http_myfilter_module);
if(ctx->add_prefix!=1){应该先判断ctx==NULL
returnnext_body_filter(r,in);
}
Nginxhttpfilter示例源码
ngx_addon_name=ngx_http_myfilter_module
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULESngx_http_myfilter_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS$ngx_addon_dir/ngx_http_myfilter_module.c"
#include
#include
#include
staticngx_str_tfilter_prefix=ngx_string("[myfilterprefix]");
staticngx_http_output_header_filter_ptnext_header_filter;
staticngx_http_output_body_filter_ptnext_body_filter;
typedefstruct{
ngx_flag_tenable;
}myfilter_conf_t;
typedefstruct{
ngx_int_tadd_prefix;
}myfilter_ctx_t;
staticngx_int_tmyfilter_header_filter(ngx_http_request_tr);
staticngx_int_tmyfilter_body_filter(ngx_http_request_tr,ngx_chain_tin);
staticngx_int_tmyfilter_init(ngx_conf_tcf);
staticvoidmyfilter_create_loc_conf(ngx_conf_tcf);
staticcharmyfilter_merge_loc_conf(ngx_conf_tcf,voidparent,voidchild);
staticngx_http_module_tmyfilter_conf={
NULL,
myfilter_init,
NULL,
NULL,
NULL,
NULL,
myfilter_create_loc_conf,
myfilter_merge_loc_conf
};
staticngx_command_tmyfilter_commands[]={
{
ngx_string("add_prefix"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(myfilter_conf_t,enable),
NULL
},
ngx_null_command
};
ngx_module_tngx_http_myfilter_module={
NGX_MODULE_V1,
&myfilter_conf,
myfilter_commands,
NGX_HTTP_MODULE,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NGX_MODULE_V1_PADDING
};
staticngx_int_tmyfilter_init(ngx_conf_tcf){
next_header_filter=ngx_http_top_header_filter;
next_body_filter=ngx_http_top_body_filter;
ngx_http_top_header_filter=myfilter_header_filter;
ngx_http_top_body_filter=myfilter_body_filter;
returnNGX_OK;
}
staticngx_int_tmyfilter_header_filter(ngx_http_request_tr){
myfilter_conf_tconf;
myfilter_ctx_tctx;
if(r->headers_out.status!=NGX_HTTP_OK){
returnnext_header_filter(r);
}
ctx=ngx_http_get_module_ctx(r,ngx_http_myfilter_module);
if(ctx){
returnnext_header_filter(r);
}
conf=ngx_http_get_module_loc_conf(r,ngx_http_myfilter_module);
if(conf==NULL||conf->enable==0){
returnnext_header_filter(r);
}
ctx=ngx_pcalloc(r->pool,sizeof(myfilter_ctx_t));
if(ctx==NULL){
returnNGX_ERROR;
}
ctx->add_prefix=0;
ngx_http_set_ctx(r,ctx,ngx_http_myfilter_module);
r->headers_out.status=NGX_HTTP_MOVED_TEMPORARILY;
ngx_str_tkeys=ngx_stringwww.baiyuewang.net("Location");
ngx_str_tvals=ngx_string("http://www.163.com");
ngx_table_elt_theaders=ngx_list_push(&r->headers_out.headers);
if(headers){
headers->key.data=keys.data;
headers->key.len=keys.len;
headers->value.data=vals.data;
headers->value.len=vals.len;
headers->hash=1;
}
//if(r->headers_out.content_type.len>=sizeof("text/plain")-1
//&&ngx_strncasecmp(r->headers_out.content_type.data,
//(u_char)"text/plain",sizeof("text/plain")-1)==0){
ctx->add_prefix=1;
if(r->headers_out.content_length_n>0){
r->headers_out.content_length_n+=filter_prefix.len;
}
//}
returnnext_header_filter(r);
}
staticngx_int_tmyfilter_body_filter(ngx_http_request_tr,ngx_chain_tin){
myfilter_ctx_tctx;
ctx=ngx_http_get_module_ctx(r,ngx_http_myfilter_module);
if(ctx==NULL||ctx->add_prefix!=1){
returnnext_body_filter(r,in);
}
ctx->add_prefix=2;
ngx_buf_tb=ngx_create_temp_buf(r->pool,filter_prefix.len);
b->start=b->pos=filter_prefix.data;
b->last=b->pos+filter_prefix.len;
ngx_chain_tcl=ngx_alloc_chain_link(r->pool);
cl->buf=b;
cl->next=in;
returnnext_body_filter(r,cl);
}
staticvoidmyfilter_create_loc_conf(ngx_conf_tcf){
myfilter_conf_tmycf;
mycf=(myfilter_conf_t)ngx_pcalloc(cf->pool,sizeof(myfilter_conf_t));
if(mycf==NULL)returnNULL;
mycf->enable=NGX_CONF_UNSET;
returnmycf;
}
staticcharmyfilter_merge_loc_conf(ngx_conf_tcf,voidparent,voidchild){
myfilter_conf_tprev=(myfilter_conf_t)parent;
myfilter_conf_tconf=(myfilter_conf_t)child;
ngx_conf_merge_value(conf->enable,prev->enable,0);
returnNGX_CONF_OK;
}
|
|