您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > Linux on Power 上的调试工具和技术
简介调试程序有很多方法,例如向屏幕上打印消息,使用调试器,或者只需仔细考虑程序如何运行,并对问题进行有根有据的猜测。在修复bug之前,首先要确定在源程序中的位置。例如,当一个程序产生崩溃或生成核心转储(coredump)时,您就需要了解是哪行代码发生了崩溃。在找到有问题的代码行之后,就可以确定这个函数中变量的值,函数是如何调用的,更具体点说,为什么会发生这种错误。使用调试器查找这些信息非常简单。本文将简要介绍几种用于修复一些很难通过可视化地检查代码而发现的bug的技术,并阐述了如何使用在LinuxonPower架构上可用的工具。回页首调试内存问题的工具和技术动态内存分配看起来似乎非常简单:您可以根据需要分配内存——使用malloc()或其变种——并在不需要时释放这些内存。实际上,内存管理的问题是软件中最为常见的bug,因为通常在程序启动时这些问题并不明显。例如,程序中的内存泄漏可能开始并不为人注意,直到经过多天甚至几个月的运行才会被发现。接下来的几节将简要介绍如何使用流行的调试器Valgrind来发现并调试这些最常见的内存bug。在开始使用任何调试工具之前,请考虑这个工具是否对重新编译应用程序有益,是否可以支持具有调试信息的库(-g选项)。如果没有启用调试信息,调试工具可以做的最好的事情也不过是猜测一段特定的代码是属于哪个函数的。这使得错误消息和概要分析输出几乎没有什么用处。使用-g选项,您就有可能获得一些信息来直接指出相关的代码行。ValgrindValgrind已经在Linux应用程序开发社区中广泛用来调试应用程序。它尤其擅长发现内存管理的问题。它可以检查程序运行时的内存泄漏问题。这个工具目前正由JulianSeward进行开发,并由PaulMackerras移植到了Power架构上。要安装Valgrind,请从Valgrind的Web站点上下载源代码(参阅参考资料)。切换到Valgrind目录,并执行下面的命令:#make#makecheck#makeinstallValgrind的错误报告Valgrind的输出格式如下:清单1.Valgrind的输出消息#valgrinddu–x–s..==29404==Address0x1189AD84is0bytesafterablockofsize12alloc'd==29404==at0xFFB9964:malloc(vg_replace_malloc.c:130)==29404==by0xFEE1AD0:strdup(in/lib/tls/libc.so.6)==29404==by0xFE94D30:setlocale(in/lib/tls/libc.so.6)==29404==by0x10001414:main(in/usr/bin/du)==29404==是进程的ID。消息Address0x1189AD84is0bytesafterablockofsize12alloc'd说明在这个12字节的数组后面没有存储空间了。第二行以及后续几行说明内存是在130行(vg_replace_malloc.c)的strdup()程序中进行分配的。strdup()是在libc.so.6库的setlocale()中调用的;main()调用了setlocale()。未初始化的内存最为常见的一个bug是程序使用了未初始化的内存。未初始化的数据可能来源于:未经初始化的变量malloc函数所分配的数据,在写入值之前使用了下面这个例子使用了一个未初始化的数组:清单2.使用未初始化的内存2{3inti[5];45if(i[0]==0)6i[1]=1;7return0;8}在这个例子中,整数数组i[5]没有进行初始化;因此,i[0]包含的是一个随机数。因此使用i[0]的值来判断一个条件分支就会导致不可预期的问题。Valgrind可以很容易捕获这种错误条件。当您使用Valgrind运行这个程序时,就会接收到下面的消息:清单3.Valgrind的输出消息#gcc–g–otest1test1.c#valgrind./test1..==31363====31363==Conditionaljumpormovedependsonuninitialisedvalue(s)==31363==at0x1000041C:main(test1.c:5)==31363====31363==ERRORSUMMARY:1errorsfrom1contexts(suppressed:7from1)==31363==malloc/free:inuseatexit:0bytesin0blocks.==31363==malloc/free:0allocs,0frees,0bytesallocated.==31363==Forcountsofdetectederrors,rerunwith:-v==31363==Nomalloc'dblocks--noleaksarepossible.Valgrind的输出说明,有一个条件分支依赖于文件test1.c中第5行中的一个未初始化的变量。内存泄漏内存泄漏是另外一个常见的问题,也是很多程序中最难判断的问题。内存泄漏的主要表现为:当程序连续运行时,与程序相关的内存(或堆)变得越来越大。结果是,当这个程序所消耗的内存达到系统的上限时,就会自己崩溃;或者会出现更严重的情况:挂起或导致系统崩溃。下面是一个有内存泄漏bug的示例程序:清单4.内存泄漏示例1intmain(void)2{3char*p1;4char*p2;56p1=(char*)malloc(512);7p2=(char*)malloc(512);89p1=p2;1011free(p1);12free(p2);13}上面的代码分别给字符指针p1和p2分配了两个512字节的内存块,然后将指向第一个内存块的指针设置为指向第二个内存块。结果是,第二个内存块的地址丢失了,并导致内存泄漏。在使用Valgrind运行这个程序时,会返回如下的消息:清单5.Valgrind的输出消息#gcc–g–otest2test2.c#valgrind./test2..==31468==Invalidfree()/delete/delete[]==31468==at0xFFB9FF0:free(vg_replace_malloc.c:152)==31468==by0x100004B0:main(test2.c:12)==31468==Address0x11899258is0bytesinsideablockofsize512free'd==31468==at0xFFB9FF0:free(vg_replace_malloc.c:152)==31468==by0x100004A4:main(test2.c:11)==31468====31468==ERRORSUMMARY:1errorsfrom1contexts(suppressed:7from1)==31468==malloc/free:inuseatexit:512bytesin1blocks.==31468==malloc/free:2allocs,2frees,1024bytesallocated.==31468==Forcountsofdetectederrors,rerunwith:-v==31468==searchingforpointersto1not-freedblocks.==31468==checked167936bytes.==31468====31468==LEAKSUMMARY:==31468==definitelylost:512bytesin1blocks.==31468==possiblylost:0bytesin0blocks.==31468==stillreachable:0bytesin0blocks.==31468==suppressed:0bytesin0blocks.==31468==Use--leak-check=fulltoseedetailsofleakedmemory.正如您可以看到的一样,Valgrind报告说这个程序中有512字节的内存丢失了。非法写/读这种情况发生在程序试图对一个不属于程序本身的内存地址进行读写时。在有些系统上,在发生这种错误时,程序会异常结束,并产生一个段错误。下面这个例子就是一个常见的bug,它试图读写一个超出数组边界的元素。清单6.非法读写1intmain(){2inti,*iw,*ir;34iw=(int*)malloc(10*sizeof(int));5ir=(int*)malloc(10*sizeof(int));678for(i=0;i11;i++)9iw[i]=i;1011for(i=0;i11;i++)12ir[i]=iw[i];1314free(iw);15free(ir);16}从这个程序中我们可以看出,对于iw[10]和ir[10]的访问都是非法的,因为iw和ir都只有10个元素,分别是从0到9。请注意intiw[10]和iw=(int*)malloc(10*sizeof(int))是等效的——它们都是用来给一个整数数组iw分配10个元素。当您使用Valgrind运行这个程序时,会返回如下的消息:清单7.Valgrind的输出消息#gcc–g–otest3test3.c#valgrind./test3..==31522==Invalidwriteofsize4==31522==at0x100004C0:main(test3.c:9)==31522==Address0x11899050is0bytesafterablockofsize40alloc'd==31522==at0xFFB9964:malloc(vg_replace_malloc.c:130)==31522==by0x10000474:main(test10.c:4)==31522====31522==Invalidreadofsize4==31522==at0x1000050C:main(test3.c:12)==31522==Address0x11899050is0bytesafterablockofsize40alloc'd==31522==at0xFFB9964:malloc(vg_replace_malloc.c:130)==31522==by0x10000474:main(test10.c:4)==31522====31522==ERRORSUMMARY:2errorsfrom2contexts(suppressed:7from1)==31522==malloc/free:inuseatexit:0bytesin0blocks.==31522==malloc/free:2allocs,2frees,84bytesallocated.==31522==Forcountsofdetectederrors,rerunwith:-v==31522==Nomalloc'dblocks--noleaksarepossible.在test3.c的第9行发现一个非法的4字节写操作,在第12行发现一个非法的4字节读操作。Valgrind也可以帮助判断内存误用的问题,例如:读/写已经释放的内存C++环境中错误地使用malloc/new与free/delete的配对下面这个列表介绍了POWER架构上Valgrind的状态:memcheck和addrcheck工具都可以很好地工作。然而,其他工具还没有进行大量的测试。另外,Helgrind(一个数据竞争的检测程序)在POWER上尚不能使用。所有的32位PowerPC?用户模式的指令都可以支持,除了两条非常少用的指令:lswx和stswx。具体来说,所有的浮点和Altivec(VMX)指令都可以支持。Valgrind可以在32位或64位PowerPC/Linux内核上工作,但是只能用于32位的可执
本文标题:Linux on Power 上的调试工具和技术
链接地址:https://www.777doc.com/doc-6290639 .html