手机应用测试如何测试java栈溢出出类错误

tomcat启动时检测到循环继承而栈溢出的问题 | 写点什么白盒工具--NuMega DevPartner Studio_单元测试方法_领测软件测试网
白盒工具--NuMega DevPartner Studio
发表于:来源:未知作者:领测软件测试网采编点击数:
这是一组白盒测试工具,主要是用于代码开发阶段,检查应用的可靠性和稳定性。它提供了先进的错误检查和调试解决方案,充分地改善生产力和开发团队的软件开发质量。NuMega产品线是一个全面的SmartDebugging工具包,自动地检查企业级或Internet级用多语言创建
  这是一组,主要是用于代码阶段,检查应用的可靠性和稳定性。它提供了先进的错误检查和调试,充分地改善生产力和团队的软件质量。NuMega产品线是一个全面的SmartDeging工具包,自动地检查企业级或Internet级用多语言创建的组件和应用中出现的软件错误和问题,并能很快地给予解决。
  NuMega DecPartner Studio满足在软件开发过程中每一个开发人员的,无论我们是使用一种或多种语言,NuMega产品都能够帮助我们提高生产力。它的产品主要有自动地错误检测、性能分析、代码覆盖分析等功能,分别用于捕获、定位错误,抽取代码执行频度,以及抽取代码覆盖率等数据,产品包括:
  1.BoundsChecker
  程序员在开发过程中可能会经常遇到这样的问题:调试时语法没有问题,代码也没有错误,但应用程序运行就是不正常甚至死机,其实这有可能是由于逻辑错误引起的内存溢出或资源泄露等问题,这些错误一般是不容易被检测出来的。而这类错误就是BoundsChecker错误检测范围之一。
  通过对被测应用程序的操作,BoundsChecker提供清晰的、详细的程序错误分析,自动查明静态的堆栈错误及内存/资源泄露,并能够迅速的定位出错的源代码,即使在没有源代码的情况下也可检查第三方组件的错误。
  BoundsChecker错误检测范围主要包括:
  1).指针和泄露错误
  接口泄露
  内存泄露
  资源泄露
  未分配的指针错误
  2).内存错误
  动态存储溢出
  无效的句柄被锁定
  句柄没有被锁定
  内存分配冲突
  栈空间溢出
  静态存储溢出
  3).API和OLE错误
  API函数返回失败
  API函数未执行
  无效的变量(包括指针变量、字符串变量等)
  OLE接口方法的变量无效
  OLE接口方法失败
  线程调用库函数错误
  BoundsChecker支持的语言和主机平台:
  , Delphi
   NT, 95/98
  2.TrueCoverage
  在开发过程中,对一个应用程序通过,总会有一部分代码功能没有被检测到,或者说逐个检测每一个函数的调用是相当费时间的;未被检测的代码我们不能保证它的可靠性,以后程序的失败可能往往就是由这部分未检测的代码造成的。现在我们可以用TrueCoverage来帮助我们解决这些问题,我们在程序时,每完成一次应用话路,TrueCoverage就能够列出在这次对话中所有函数被调用次数、所占比率等,并可以直接定位到源代码,当然我们也可以合并多个应用话路来进行检测。所以说TrueCoverage能通过衡量和跟踪代码执行及代码稳定性,帮助开发团队节省时间和改善代码可靠性。
  TrueCoverage支持的语言和主机平台
  C++, JAVA, Visual Basic
  Windows NT, Windows95/98
  3. TrueTime
  代码运行缓慢是开发过程中一个重要问题。一个应用程序运行速度较慢,程序员不容易找到到底是在哪里出现了问题,如果不能解决应用程序的性能将降低并极大的影响应用程序的质量,于是查找和修改性能瓶颈是调整整个代码性能的关键。如何快速的查找性能瓶颈呢?TrueTime的出现就使这个问题变得很容易了。当我们在测试程序时,每完成一次应用话路,TrueTime都能提供这次对话中函数的调用时间,提供详细的应用程序和组件性能的分析,并自动定位到运行缓慢的代码。这样就能帮助程序员尽快地调整应用程序的性能。
  TrueTime支持的语言和主机平台
  C++, JAVA, Visual Basic
  Windows NT, Windows95/98
  4. SmartCheck
  作为一名Visual Basic的开发人员,在开发的过程中经常会遇到许多问题难以解决,包括象隐藏的run-time错误、Windows API函数在Visual Basic中正确使用的问题、一些组件的错误等等,它们很难被定位到具体的代码中,令开发人员花费大量时间去寻找并解决。SmartCheck就是能很快地查找到这些问题的一个的工具,它是对于Visual Basic来说最好的run-time调试工具,它检测所有的Windows API函数调用、内存分配以及其它一些重要的程序错误。SmartCheck检错的种类包括泄露、接口方法失败、存储错误、程序和函数失败和Visual Basic的Runtime错误等,它能够将检测到的错误快速地定位到源代码。使用SmartCheck将会极大地提高开发人员的工作效率。
  SmartCheck 支持的语言和主机平台:
  Visual Basic
  Windows NT, Windows95/98
  5. FailSafe
  FailSafe是用于Visual Basic开发的一个自动错误处理和恢复系统。VB开发人员经常能够遇到程序执行时意外地终止,但是对于为什麽出现错误只提供了简短的、模糊的出错信息,使开发人员不能方便地发现错误的根源。如果使用了FailSafe,它将插入额外的代码对你的程序进行插装,当程序执行时,FailSafe通过这些插装的代码捕获、记录执行时程序和系统的重要信息,直接指出错误发生时程序和系统的状态,这些丰富的信息使开发人员能够快速且正确的解决问题。
  FailSafe 支持的语言和主机平台:
  Visual Basic
  Windows NT, Windows95/98
  6.CodeReview
  对于Visual Basic开发人员来说,CodeReview是最好的自动源代码分析工具,它对应用程序的组件、逻辑、Windows和Vb自身潜在的数百个问题进行严格地源代码检查。CodeReview分析的类型包括Y2K问题,逻辑错误,应用程序性能和可用性问题,Windows API调用和标准一致性问题等。CodeReview可以检测整个的VB工程或指定的模块,并能定制检错的种类;对检测的结果有详细的说明,提供帮助和推荐解决方案,而且能够直接的链接到源代码。
  CodeReview系统还提供了两个子模块,一个是Metrics:通过对VB工程(vbp)的执行,计算出代码的长度、复杂度、理解度、语言的使用等级、出错的可能性等数据;另一个是Namer:它调用一个VB工程,自动并规则地对其中的对象重新命名,并备份原来没有规则命名的工程文件,使开发人员对程序能够有条理地管理。
原文转自:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)二次元同好交流新大陆
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
以无法为有法,以无限为有限!
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(21296)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'软件测试面试题完全版',
blogAbstract:'一、测试总体\n1. 什么是软件测试?\n答:为了发现程序中的错误而执行程序的过程\n2. 软件测试的目的?\n答:首先,测试并不仅仅是为了要找出错误。通过分析错误产生的原因和错误的分布\n特征,可以帮助项目管理者发现当前所采用的软件过程的缺陷,以便改进。同时,这种分\n析也能帮助我们设计出有针对性地检测方法,改善测试的有效性。\n其次,没有发现错误的测试也是有价值的,完整的测试是评定测试质量的一种方法。\n',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:4,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:2,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:true,
hostIntro:'以无法为有法,以无限为有限!',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}4890人阅读
硬件相关(31)
今天搞的一个stm32 的程序发生了错误。全局变量遭到了局部变量的篡改。新手感觉很奇特。
看了一些资料,发现时栈区设置太小所导致的,全局变量向上生长,栈区向下生长。stm32的栈顶是程序自动生成的(暂时是这么认为的,有待进一步确定),程序会地洞生成栈顶。并且栈底和全局变量区是紧挨的,因此如果栈溢出的话,会直接将全局变量去的地址拿来自己用,于是全局变量区的地址和栈区的地址重合,导致全局变量遭到局部变量篡改的错误。
看看下面一些专业的解释会更清晰!
对于单片机这种封闭代码的运行平台,内存分配有2个大方向,一个是静态变量,一个是动态变量,具体到作用域,又分为局部变量和全局变量.
全局静态变量:不管是否调用,它都在那里,比如LZ示例&test.c&的 line:11 和 line:15,注意这里加了&static&关键字,指明这个变量是并不是真正意义的全局变量,只是在这个文件的所有位置&声明位置以后的所有位置&可用.
局部静态变量:和全局静态变量类似,也是不管拉不拉屎先占坑的货,比如LZ示例&test.c&的 line:23 .特点是加了关键字&static&,意思是在这个位置,它是唯一的.在&find_stack_direction&函数里使用了递归,但局部静态变量是不在递归里重新分配空间的,原子也是通过这个方式来判断两次进入之间的地址关系.
局部动态变量:这个是最常见的,比如LZ示例&test.c&的 line:24,在这个示例里,每次声明&神灯啊神灯&,结果出来的都是新的神灯,许了愿就溜掉,是这种变量的特点.它不会记得它曾经是什么.注意,由于每次都喝了孟婆汤,有经验的码农会在召唤时默认赋一个初值,避免出现不可预料的使用.
全局动态变量:存在吗?全局可见但又可以踢掉的奇葩吗?抱歉,这句话对&全局&是个误解.&全局&的意思是变量本身没有编译器指定的生命周期,也就是&作用域&,但还有代码指定的生命周期.在LZ的示例里,&堆&就是这么一个东西,代码说&你在&就在,&你不在&就不在.申请了堆后,只要谁(任何位置的代码)知道这个位置是可以用的,谁都可以用(**具有进程内存保护的平台除外**),即使申请空间的变量&挂了&,这个空间也一直存在,直到有代码把它&销毁&掉.
顺便推销老帖/posts/list/19693.htm
修改+注释.
**新的linux把uclinux统一了,不知道是否在单片机实现进程内存保护,同求证.不过这也不在&封闭代码平台&这个前提下了.
一、内存基本构成&&
可编程内存在基本上分为这样的几大部分:静态存储区、堆区和栈区。他们的功能不同,对他们使用方式也就不同。&&
静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。&&
栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。&&
堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。
按照这个说法,我在.s文件里面设置了:
Heap_Size&&&&&& EQU&&&& 0x
也就是,没有任何动态内存分配。
这样,内存=静态存储区+栈区了。
不存在堆!!!
因为我没有用malloc来动态分配内存。
因此,前面提到的一切堆区,其实就是静态存储区。
栈增长和大端/小端问题是和CPU相关的两个问题.
1,首先来看:栈(STACK)的问题.
函数的局部变量,都是存放在&栈&里面,栈的英文是:STACK.STACK的大小,我们可以在stm32的启动文件里面设置,以战舰stm32开发板为例,在startup_stm32f10x_hd.s里面,开头就有:
Stack_Size&&&&& EQU&&&& 0x
表示栈大小是0X800,也就是2048字节.这样,CPU处理任务的时候,函数局部变量做多可占用的大小就是:2048字节,注意:是所有在处理的函数,包括函数嵌套,递归,等等,都是从这个&栈&里面,来分配的.
所以,如果一个函数的局部变量过多,比如在函数里面定义一个u8 buf[512],这一下就占了1/4的栈大小了,再在其他函数里面来搞两下,程序崩溃是很容易的事情,这时候,一般你会进入到hardfault....
这是初学者非常容易犯的一个错误.切记不要在函数里面放N多局部变量,尤其有大数组的时候!
对于栈区,一般栈顶,也就是MSP,在程序刚运行的时候,指向程序所占用内存的最高地址.比如附件里面的这个程序序,内存占用如下图:
图中,我们可以看到,程序总共占用内存:20+2348字节=
那么程序刚开始运行的时候:MSP=0X+0X940=0X.
事实上,也是如此,如图:
图中,MSP就是:0X.
程序运行后,MSP就是从这个地址开始,往下给函数的局部变量分配地址.
再说说栈的增长方向,我们可以用如下代码测试:&
//保存栈增长方向
//0,向下增长;1,向上增长.
static u8 stack_
//查找栈增长方向,结果保存在stack_dir里面.
void find_stack_direction(void)
&&& static u8 *addr=NULL;&//用于存放第一个dummy的地址。
&&& u8&&&&&&&&&&&&& &//用于获取栈地址&
&&& if(addr==NULL)& &&//第一次进入
&&& {&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&& addr=&&& &&//保存dummy的地址
&&&&&&& find_stack_direction ();& //递归&
&&& }else&&&&&&&&&&&&&& &//第二次进入&
&&&&&&& if(&dummy&addr)stack_dir=1; //第二次dummy的地址大于第一次dummy,那么说明栈增长方向是向上的.&
&&&&&&& else stack_dir=0;&&&&&&&&&& //第二次dummy的地址小于第一次dummy,那么说明栈增长方向是向下的.&&
这个代码不是我写的,网上抄来的,思路很巧妙,利用递归,判断两次分配给dummy的地址,来比较栈是向下生长,还是向上生长.
如果你在STM32测试这个函数,你会发现,STM32的栈,是向下生长的.事实上,一般CPU的栈增长方向,都是向下的.
2,再来说说,堆(HEAP)的问题.
全局变量,静态变量,以及内存管理所用的内存,都是属于&堆&区,英文名:&HEAP&
与栈区不同,堆区,则从内存区域的起始地址,开始分配给各个全局变量和静态变量.
堆的生长方向,都是向上的.在程序里面,所有的内存分为:堆+栈. 只是他们各自的起始地址和增长方向不同,他们没有一个固定的界限,所以一旦堆栈冲突,系统就到了崩溃的时候了.
同样,我们用附件里面的例程测试:
stack_dir的地址是0X,也就是STM32的内存起始端的地址.
这里本来应该是从0X开始分配的,但是,我仿真发现0X总是存放:0X,这个值,貌似是MSP,但是又不变化,还请高手帮忙解释下.
其他的,全局变量,则依次递增,地址肯定大于0X,比如cpu_endian的地址就是0X.
这就是STM32内部堆的分配规则.
3,再说说,大小端的问题.
大端模式:低位字节存在高地址上,高位字节存在低地址上&
小端模式:高位字节存在高地址上,低位字节存在低地址上
STM32属于小端模式,简单的说,比如u32 temp=0X;
假设temp地址在0X.
那么在内存里面,存放就变成了:
地址&&&&&&&&&&&&& |&&&&&&&&&&& HEX&&&&&&&&&|
0X&&|&&78&& 56&& 43& 12& |
CPU到底是大端还是小端,可以通过如下代码测试:
//CPU大小端
//0,小端模式;1,大端模式.
static u8 cpu_
//获取CPU大小端模式,结果保存在cpu_endian里面
void find_cpu_endian(void)
&if(*(char*)&x==1)cpu_endian=0;&//小端模式&
&else cpu_endian=1;&&&&//大端模式&&
以上测试,在STM32上,你会得到cpu_endian=0,也就是小端模式.
3,最后说说,STM32内存的问题.
&&& 还是以附件工程为例,在前面第一个图,程序总共占用内存:20+2348字节,这么多内存,到底是怎么得来的呢?
我们可以双击Project侧边栏的:Targt1,会弹出test.map,在这个里面,我们就可以清楚的知道这些内存到底是怎么来的了.在这个test.map最后,Image 部分有:
==============================================================================
Image component sizes
&&&&& Code (inc. data)&& RO Data&&& RW Data&&& ZI Data&&&&& Debug&& Object Name
&&&&&&&172&&&&&&&& 10&&&&&&&&& 0&&&&&&&&& 4&&&&&&&&& 0&&&&&&& 995&& delay.o//delay.c里面,fac_us和fac_ms,共占用4字节
&&&&&& 112&&&&&&&& 12&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&& 427&& led.o
&&&&&&&&72&&&&&&&& 26&&&&&&& 304&&&&&&&&& 0&&&&&& 2048&&&&&&& 828&& startup_stm32f10x_hd.o& //启动文件,里面定义了Stack_Size为0X800,所以这里是2048.
&&&&&& 712&&&&&&&& 52&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&& 2715&& sys.o
&&&&&&&348&&&&&&& 154&&&&&&&&& 0&&&&&&&&& 6&&&&&&&&& 0&&&& 208720&& test.o//test.c里面,stack_dir和cpu_endian&以及*addr&&,占用6字节.
&&&&&&&384&&&&&&&& 24&&&&&&&&& 0&&&&&&&&& 8&&&&&&& 200&&&&&& 3050&& usart.o//usart.c定义了一个串口接收数组buffer,占用200字节.
&&& ----------------------------------------------------------------------
&&&&&&1800&&&&&&& 278&&&&&&& 336&&&&&&&& 20&&&&&& 2248&&&& 216735&& Object Totals //总共字节
&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 32&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& (incl. Generated)
&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 0&& (incl. Padding)//2字节用于对其
&&& ----------------------------------------------------------------------
&&&&& Code (inc. data)&& RO Data&&& RW Data&&& ZI Data&&&&& Debug&& Library Member Name
&&&&&&&& 8&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 68&& __main.o
&&&&&& 104&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 84&& __printf.o
&&&&&&& 52&&&&&&&&& 8&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& __scatter.o
&&&&&&& 26&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& __scatter_copy.o
&&&&&&& 28&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& __scatter_zi.o
&&&&&&& 48&&&&&&&&& 6&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 96&& _printf_char_common.o
&&&&&&& 36&&&&&&&&& 4&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 80&& _printf_char_file.o
&&&&&&& 92&&&&&&&&& 4&&&&&&&& 40&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 88&& _printf_hex_int.o
&&&&&& 184&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 88&& _printf_intcommon.o
&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& _printf_percent.o
&&&&&&&& 4&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& _printf_percent_end.o
&&&&&&&& 6&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& _printf_x.o
&&&&&&& 12&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 72&& exit.o
&&&&&&&& 8&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 68&& ferror.o
&&&&&&&& 6&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&& 152&& heapauxi.o
&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& libinit.o
&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& libinit2.o
&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& libshutdown.o
&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& libshutdown2.o
&&&&&&&&&8&&&&&&&&& 4&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 96&&&&&&&& 68&& libspace.o&&&&&&&&& //库文件(printf使用),占用了96字节
&&&&&&& 24&&&&&&&&& 4&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 84&& noretval__2printf.o
&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& rtentry.o
&&&&&&& 12&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& rtentry2.o
&&&&&&&& 6&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& rtentry4.o
&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& rtexit.o
&&&&&&& 10&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& rtexit2.o
&&&&&&& 74&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 80&& sys_stackheap_outer.o
&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 68&& use_no_semi.o
&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 68&& use_no_semi_2.o
&&&&&& 450&&&&&&&&& 8&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&& 236&& faddsub_clz.o
&&&&&& 388&&&&&&&& 76&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 96&& fdiv.o
&&&&&&& 62&&&&&&&&& 4&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 84&& ffixu.o
&&&&&&& 38&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 68&& fflt_clz.o
&&&&&& 258&&&&&&&&& 4&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 84&& fmul.o
&&&&&& 140&&&&&&&&& 4&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 84&& fnaninf.o
&&&&&&& 10&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&& 68&& fretinf.o
&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&& usenofp.o
&&& ----------------------------------------------------------------------
&&&&& 2118&&&&&&& 126&&&&&&&& 42&&&&&&&&& 0&&&&&&& 100&&&&&& 1884&& Library Totals& //调用的库用了100字节.
&&&&&&& 10&&&&&&&&& 0&&&&&&&&& 2&&&&&&&&& 0&&&&&&&&& 4&&&&&&&&& 0&& (incl. Padding)&& //用于对其多占用了4个字节
&&& ----------------------------------------------------------------------
&&&&& Code (inc. data)&& RO Data&&& RW Data&&& ZI Data&&&&& Debug&& Library Name
&&&&&& 762&&&&&&&& 30&&&&&&&& 40&&&&&&&&& 0&&&&&&&& 96&&&&&& 1164&& c_w.l
&&&&& 1346&&&&&&&& 96&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0&&&&&&& 720&& fz_ws.l
&&& ----------------------------------------------------------------------
&&&&& 2118&&&&&&& 126&&&&&&&& 42&&&&&&&&& 0&&&&&&& 100&&&&&& 1884&& Library Totals
&&& ----------------------------------------------------------------------
==============================================================================
&&&&& Code (inc. data)&& RO Data&&& RW Data&&& ZI Data&&&&& Debug&&
&&&&& 3918&&&&&&& 404&&&&&&& 378&&&&&&&& 20&&&&&& 2348&&&& 217111&& Grand Totals
&&&&& 3918&&&&&&& 404&&&&&&& 378&&&&&&&& 20&&&&&& 2348&&&& 217111&& ELF Image Totals
&&&&& 3918&&&&&&& 404&&&&&&& 378&&&&&&&& 20&&&&&&&&& 0&&&&&&&&& 0&& ROM Totals
==============================================================================
&&& Total RO& Size (Code + RO Data)&&&&&&&&&&&&&&&& 4296 (&& 4.20kB)
&&&&Total RW& Size (RW Data + ZI Data)&&&&&&&&&&&&& 2368 (&& 2.31kB)&& //总共占用:+100=2368.
&&& Total ROM Size (Code + RO Data + RW Data)&&&&&& 4316 (&& 4.21kB)
==============================================================================
通过这个文件,我们就可以分析整个内存,是怎么被占用的,具体到每个文件,占用多少.一目了然了.
4,最后,看看整个测试代码:
main.c代码如下,工程见附件.
#include &sys.h&
#include &usart.h&&&
#include &delay.h&&
#include &led.h&&
#include &beep.h&& &&
#include &key.h&& &&
//ALIENTEK战舰STM32开发板堆栈增长方向以及CPU大小端测试
//保存栈增长方向
//0,向下增长;1,向上增长.
static u8 stack_
//CPU大小端
//0,小端模式;1,大端模式.
static u8 cpu_
//查找栈增长方向,结果保存在stack_dir里面.
void find_stack_direction(void)
&&& static u8 *addr=NULL;&//用于存放第一个dummy的地址。
&&& u8&&&&&&&&&&&&& &//用于获取栈地址&
&&& if(addr==NULL)& &&//第一次进入
&&& {&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&& addr=&&& &&//保存dummy的地址
&&&&&&& find_stack_direction ();& //递归&
&&& }else&&&&&&&&&&&&&& &//第二次进入&
&&&&&&& if(&dummy&addr)stack_dir=1; //第二次dummy的地址大于第一次dummy,那么说明栈增长方向是向上的.&
&&&&&&& else stack_dir=0;&&&&&&&&&& //第二次dummy的地址小于第一次dummy,那么说明栈增长方向是向下的.&&
//获取CPU大小端模式,结果保存在cpu_endian里面
void find_cpu_endian(void)
&if(*(char*)&x==1)cpu_endian=0;&//小端模式&
&else cpu_endian=1;&&&&//大端模式&&
int main(void)
&Stm32_Clock_Init(9);&//系统时钟设置
&uart_init(72,9600);& &//串口初始化为9600
&delay_init(72);&&& & &//延时初始化&
&LED_Init();&&& &&//初始化与LED连接的硬件接口&&
&&& printf(&stack_dir:%x\r\n&,&stack_dir);
&&& printf(&cpu_endian:%x\r\n&,&cpu_endian);
&find_stack_direction();&//获取栈增长方式
&find_cpu_endian();&&//获取CPU大小端模式
&&while(1)
&&if(stack_dir)printf(&STACK DIRCTION:向上生长\r\n\r\n&);
&&else printf(&STACK DIRCTION:向下生长\r\n\r\n&);
&&if(cpu_endian)printf(&CPU ENDIAN:大端模式\r\n\r\n&);
&&else printf(&CPU ENDIAN:小端模式\r\n\r\n&);&
&&delay_ms(500);
&&LED0=!LED0;&&
测试结果如图:
4、内存基本构成&&
可编程内存在基本上分为这样的几大部分:静态存储区、堆区和栈区。他们的功能不同,对他们使用方式也就不同。&&
静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。&&
栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。&&
堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。
按照这个说法,我在.s文件里面设置了:
Heap_Size&&&&&& EQU&&&& 0x
也就是,没有任何动态内存分配。
这样,内存=静态存储区+栈区了。
不存在堆!!!
因为我没有用malloc来动态分配内存。
因此,前面提到的一切堆区,其实就是静态存储区。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:450842次
积分:3703
积分:3703
排名:第5838名
原创:21篇
转载:264篇
评论:35条
(1)(2)(7)(10)(12)(9)(5)(4)(5)(4)(5)(10)(16)(12)(3)(13)(2)(3)(9)(8)(13)(3)(15)(5)(7)(6)(1)(2)(5)(3)(29)(37)(12)(1)(4)(1)(2)

我要回帖

更多关于 cad堆栈溢出 的文章

 

随机推荐