在做 http模块 reload 功能时有个遍历 static_location 三叉树的需求,写完想着检验一下遍历的是否正确,于是就输出了一些打印日志,但是发现日志中有很多乱码,gdb 调试 slen = va_arg(args, size_t);
获取的字符串长度为 236223201284
,和我传进去的node->len
完全对不上,后来发现 node->len
成员的类型竟然是 u_char,和size_t 没有匹配上。好隐蔽的错误, 为了不修改结构体,就老老实实用 “%V” 了.
code
/* 递归遍历三叉树 */
static void
ngx_http_log_foreach_static_location(ngx_http_location_tree_node_t *node, ngx_uint_t flags)
{
ngx_http_core_loc_conf_t *clcf;
ngx_http_log_loc_conf_t *llcf;
ngx_str_t name;
if (node == NULL) {
return;
}
ngx_http_log_foreach_static_location(node->left, flags);
ngx_http_log_foreach_static_location(node->right, flags);
if (node->exact) {
clcf = node->exact;
} else {
ngx_http_log_foreach_static_location(node->tree, flags);
clcf = node->inclusive;
}
llcf = clcf->loc_conf[ngx_http_log_module.ctx_index];
if (llcf->off) {
return;
}
name.data = node->name;
name.len = (size_t)node->len;
/* 修改前的代码 */
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"foreach location: \"%*s\"", node->len, node->name);
/* 修改后的代码 */
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"foreach location: %V", &name);
}
gdb
306 while (*fmt >= '0' && *fmt <= '9') {
(gdb)
312 switch (*fmt) {
(gdb) p *fmt
$60 = 42 '*'
(gdb) n
346 slen = va_arg(args, size_t);
(gdb)
347 fmt++;
(gdb) p slen
$61 = 236223201284 //这个值出来以后另我很诧异
(gdb) p *fmt
$62 = 42 '*'
(gdb) n
348 continue;
(gdb)
355 }
(gdb)
312 switch (*fmt) {
(gdb)
354 break;
(gdb)
358 switch (*fmt) {
(gdb)
379 p = va_arg(args, u_char *);
(gdb)
381 if (slen == (size_t) -1) {
(gdb) p p
$64 = (u_char *) 0x60a75ea ".xsl"
(gdb) n
387 len = ngx_min(((size_t) (last - buf)), slen);
(gdb)
/* buf 默认大小为2048,拷贝进去很多无效字符 */
388 buf = ngx_cpymem(buf, p, len);