文章17:Nginx中的测试方法:加桩调试(20121021版)

欢迎大家阅读和讨论,转载请注明出处  http://blog.csdn.net/yankai0219/article/details/8093752
内容
0.序
1.情况一:加桩测试函数中没有使用内存池
2.情况二:加桩测试函数中使用内存池


0.序
我看到有篇文档讲的是利用gdb来进行Nginx的加桩测试,可是对于我这个从windows转过来的选手,已经习惯了使用IDE来进行调试,一下子让我用gdb进行调试,我还不会~这可就得想法,我之前的文章中有讲过用Eclipse来进行Nginx的开发,那么我就想能否使用Eclipse来进行加桩调试呢?

答案是可喜的,完全可以利用Eclipse进行加桩测试,伟大的Eclipse啊。
我们将会分两种情况来进行说明,一种是加桩测试函数中没有使用内存池,一种是加桩测试函数中使用内存池,有所区别。
1.情况一:加桩测试函数中没有使用内存池

下文中出现的代码是他人的代码,本文章只是介绍调试方法。

1)复制源码

void ngx_slab_test()
	{
	    ngx_shm_t shm;
	    ngx_slab_pool_t *sp;
	    u_char *file;
	    void *one_page;
	    void *two_page;
	    
	    ngx_memzero(&shm, sizeof(shm));
	    shm.size = 4 * 1024 * 1024;
	    if (ngx_shm_alloc(&shm) != NGX_OK) {
	        goto failed;
	    }
	    printf("test slb\n");
	    sp = (ngx_slab_pool_t *) shm.addr;
	    sp->end = shm.addr + shm.size;
	    sp->min_shift = 3;
	    sp->addr = shm.addr;
	
	#if (NGX_HAVE_ATOMIC_OPS)
	    file = NULL;
	#else
	    #error must support NGX_HAVE_ATOMIC_OPS.
	#endif
	    if (ngx_shmtx_create(&sp->mutex, &sp->lock, file) != NGX_OK) {
	        goto failed;
	    }
	    
	    ngx_slab_init(sp);
	    
	    one_page = ngx_slab_alloc(sp, ngx_pagesize);
	    two_page = ngx_slab_alloc(sp, 2 * ngx_pagesize);
	
	    ngx_slab_free(sp, one_page);
	    ngx_slab_free(sp, two_page);
	    
	    ngx_shm_free(&shm);
	    
	    exit(0);
	failed:
	    printf("failed.\n");
	    exit(-1);
	}

2)在nginx根目录/src/core/nginx.c中添加上面代码,需要改动的有三处:

1.在文件开始处,添加函数声明 void ngx_slab_test();

2.在文件结尾处,添加函数定义:即上述代码

3.在文件中间部位,添加调用函数代码

    if (ngx_os_init(log) != NGX_OK) {
        return 1;
    }

    ngx_slab_test();/*edited by yankai*/

3)设置断点,在ngx_slab_test()处设置断点,点击调试按钮,如下图所示

4)进行单步调试,会发现会进行ngx_slab_test函数内部执行。

5)由于我在ngx_slab_test函数中添加了printf语句,因此,在Console窗口中会显示test slb如下图所示:

情况二:加桩测试中使用内存池

在对于 http://code.google.com/p/nginxsrp/wiki/NginxCodeReview 这类牵涉到内存池分配的情况,如何进行加桩测试呢?



方法其实很简单,但是我们必须认识到为什么要按照下面的方法来做。
首先介绍一点基本知识:
      nginx对内存的管理均统一完成,例如在特定的生命周期内统一建立内存池。如main函数系统启动初期即分配1024字节大小的内存池。即init_cycle.pool = ngx_create_pool(1024,log);
正是上面这段话决定了我们下面所采用的方法。
 注意:本方法中的加桩测试不能用于测试内存池的分配的情况,因为本加桩测试是从已有的init_cycle.pool内存池中分配内存。
     
错误的做法:我们在加桩测试的函数中自己分配内存池。
如果自己分配内存池,就会造成ngx_create_pool时保存,在单步调试时可以发现会进入ngx_create_pool中报错。
void  test_chain_c()  /*edited by yankai*/
{
                
                  ngx_pool_t  * hpnl_pool;
       printf  ( "test 1 "  );
                hpnl_pool = ngx_create_pool(50,NULL);
                  //create chain
                  printf  ( "test 2 "  );
   
                ngx_destroy_pool(hpnl_pool);
                  exit  (0);

}


正确做法:使用init_cycle.pool作为加桩测试的内存池,即加桩测试中的小内存都从init_cycle.pool中获取。
void  test_chain_c(  ngx_cycle_t  *init_cycle) /*edited by yankai*/
{


                  ngx_chain_t  *hpnl_cl;
                  ngx_chain_t  *hpnl_cl_next;
                  ngx_buf_t  * hpnl_buf;
                  ngx_buf_t  * hpnl_buf_next;
                  ngx_str_t  hpnl_str = ngx_string( "hello"  );
                  ngx_str_t  hpnl_str_next = ngx_string( "world"  );
                  int  hpnl_n;

                  //create chain
                  printf  ( "test 1 \n"  );
                  printf  ( " sizeof(ngx_pool_t) is %d\n"  , sizeof  (  ngx_pool_t ));
                  printf  ( "max of init_cycle is %d \n"  ,init_cycle->  pool ->  max  );
                hpnl_cl = ngx_alloc_chain_link(init_cycle->  pool  );
                hpnl_cl_next = ngx_alloc_chain_link(init_cycle->  pool  );
                  if  ( hpnl_cl == NULL || hpnl_cl_next == NULL ){
                                  printf  ( " alloc chain link error\n"  );
                                  exit  (-1);
                }
                  printf  ( "test 2 \n"  );
                  //create buf
                hpnl_buf = ngx_create_temp_buf(init_cycle->  pool  ,1000);
                hpnl_buf_next = ngx_create_temp_buf(init_cycle->  pool  ,1000);
                  if  (hpnl_buf == NULL || hpnl_buf_next == NULL){
                                  printf  ( " alloc buffer error\n"  );
                                  exit  (-1);
                }
                  //initial chain
                hpnl_cl->  buf  = hpnl_buf;
                hpnl_cl->  next  = NULL;
                hpnl_cl_next->  buf  = hpnl_buf_next;
                hpnl_cl_next->  next  = NULL;

                  if  (hpnl_cl == NULL){
                                hpnl_cl = hpnl_cl_next;
                }
                  else  {
                                hpnl_cl->  next  = hpnl_cl_next;
                }
                hpnl_buf->  last  = ngx_cpymem(hpnl_buf-> last  ,hpnl_str.  data ,hpnl_str.  len  );
                hpnl_buf_next->  last  = ngx_cpymem(hpnl_buf_next-> last  ,hpnl_str_next.  data ,hpnl_str_next.  len  );
                  printf  ( "begin to output hpnl_cl"  );



                hpnl_n = 0;
                  for  (hpnl_cl_next = hpnl_cl; hpnl_cl_next;hpnl_cl_next = hpnl_cl_next->  next ){
                                  printf  ( "hpnl_cl-> buf->start  is %s\n"  ,hpnl_cl_next-> buf  ->  start );
                                  printf  ( "@@@%d @@@\n"  ,hpnl_n);
                                hpnl_n++;
                }

                  printf  ( "end up output\n"  );
                  exit  (0);


}

测试步骤:除了代码部分与情况一不同外,其测试方法一样
保存以后点击运行,出现下面结果。
test 1
sizeof(ngx_pool_t) is 40
max of init_cycle is 984
test 2
begin to output hpnl_clhpnl_cl->buf->start  is hello
@@@0 @@@
hpnl_cl->buf->start  is world
@@@1 @@@
end up output



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值