首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

函数指针运行时跑飞,平分析

2013-03-16 
函数指针运行时跑飞,急等分析应用程序:GUI_FLASH const GUI_FONT_PROP GUI_FontHZ17x19_Prop_a1 {0xa1a1,

函数指针运行时跑飞,急等分析
应用程序:


GUI_FLASH const GUI_FONT_PROP GUI_FontHZ17x19_Prop_a1 =
{
0xa1a1,
0xa1fe,
&GUI_FontHZ17x19_CharInfo[96],
(void *)&GUI_FontHZ17x19_Prop_a2
};

GUI_FLASH const GUI_FONT_PROP GUI_FontHZ17x19_Prop_ASC =
{
0x0020, // first character
0x007f, // last character
&GUI_FontHZ17x19_CharInfo[0], // address of first character
(void *)&GUI_FontHZ17x19_Prop_a1 // pointer to next GUI_FONT_PROP
};

GUI_FLASH const GUI_FONT GUI_FontHZ17x19 =
{
//GUI_FONTTYPE_PROP_SJIS, // type of font
19, // height of font
19, // space of font y
1,  // magnification x
1,  // magnification y
(void GUI_FLASH *)&GUI_FontHZ17x19_Prop_ASC
};
extern void Uart_Printf(char *fmt,...);
void printftest()
{
const GUI_FONT_PROP *p = (const GUI_FONT_PROP *)GUI_FontHZ17x19.pProp;

Uart_Printf ("GUI_FontHZ17x19.pProp=0x%x\n", GUI_FontHZ17x19.pProp);
Uart_Printf ("&GUI_FontHZ17x19_Prop_ASC=0x%x\n", &GUI_FontHZ17x19_Prop_ASC);
Uart_Printf ("p=0x%x\n", p);
Uart_Printf ("GUI_FontHZ17x19.pProp->First=0x%x\n", GUI_FontHZ17x19.pProp->First);
Uart_Printf ("GUI_FontHZ17x19_Prop_ASC.First=0x%x\n", GUI_FontHZ17x19_Prop_ASC.First);
Uart_Printf ("GUI_FontHZ17x19_Prop_ASC.pNext=0x%x\n", GUI_FontHZ17x19_Prop_ASC.pNext);
Uart_Printf ("&GUI_FontHZ17x19_Prop_a1=0x%x\n", &GUI_FontHZ17x19_Prop_a1);
Uart_Printf ("&GUI_FontHZ17x19_Prop_a2=0x%x\n", &GUI_FontHZ17x19_Prop_a2);
Uart_Printf ("&GUI_FontHZ17x19_Prop_a3=0x%x\n", &GUI_FontHZ17x19_Prop_a3);
Uart_Printf ("&GUI_FontHZ17x19_Prop_a4=0x%x\n", &GUI_FontHZ17x19_Prop_a4);
Uart_Printf ("&GUI_FontHZ17x19_Prop_a5=0x%x\n", &GUI_FontHZ17x19_Prop_a5);
Uart_Printf ("&GUI_FontHZ17x19_Prop_a6=0x%x\n", &GUI_FontHZ17x19_Prop_a6);
Uart_Printf ("&GUI_FontHZ17x19_Prop_a7=0x%x\n", &GUI_FontHZ17x19_Prop_a7);
Uart_Printf ("&GUI_FontHZ17x19_Prop_a8=0x%x\n", &GUI_FontHZ17x19_Prop_a8);
for ( ; p; p = (const GUI_FONT_PROP *)(p->pNext))
{
Uart_Printf ("p=0x%x\n",p);
}
}

头文件:

typedef struct 
{
I16P c0;
I16P c1;
} GUI_FONT_TRANSLIST;

typedef struct 
{
U16P FirstChar;
U16P LastChar;
const GUI_FONT_TRANSLIST* pList;
} GUI_FONT_TRANSINFO;

typedef struct {
U8 XSize;
U8 XDist;
U8 BytesPerLine;
void* pData;
} GUI_CHARINFO;

typedef struct 
{
U16P First;         /* first character               */
U16P Last;          /* last character                */
const GUI_CHARINFO* paCharInfo;    /* address of first character    */
void* pNext;        /* pointer to next */
} GUI_FONT_PROP;


typedef struct
{
  U8 YSize;
  U8 YDist;
  U8 XMag;
  U8 YMag;
  const  GUI_FONT_PROP* pProp;
  //U8 Baseline;
} GUI_FONT;


运行结果为图:
函数指针运行时跑飞,平分析
实验环境:tq2440开发板,应用程序的文件是ucgui的汉字库。应用程序没显示完全,能看出整个结构。
问题1:从运行结果上可以看出,如果使用Uart_Printf ("&GUI_FontHZ17x19_Prop_a8=0x%x\n", &GUI_FontHZ17x19_Prop_a8);将函数指针打印出来了,那么结构体中的pnext就能正确指向。(如红色的标记)。我没有将函数指针打印出来的地方,后面的pnext指向就飞了(蓝色的标记地方)。这个可能是什么原因引起的?
问题2:将同样的程序移植到cfree中windwos环境下运行就没有跑飞的情况,这个跟2440有关吗?
问题3:在进行gui的移植的时候发现函数指针跑飞的情况很多,可能和主要的原因有哪些?

希望能帮忙解决,谢谢!
[解决办法]
1. 不建议使用函数指针。
2. 设置软狗,屏蔽同时对函数操作。设置退出前清理现场代码。
3. 注意指针类型赋值默认转换规则。
4. 结构体占用内存比较大,注意溢出异常判断。
[解决办法]
是不是多任务,是不是中断引起的?
[解决办法]
这个得看你的程序里GUI_FontHZ17x19_Prop_a8的pnext指向什么了,貌似这个指针指的位置不对了,
造成了飞指针。

如果你在Windows的模拟环境下是正确的,我觉得这个可能跟你在tq2440下程序的存储分配有关系。

比如说各存储段分配的是否正确;RO端和RW段是否需要搬移和初始化;ZI段是否都初始化为0了等等。

如果能联仿真器,实时仿真一下就OK了。
[解决办法]
注意堆栈设置;
如果函数中使用了非常大的局部变量或者嵌套层数过多,会导致堆栈溢出;
可以尝试把堆栈设置大几倍再看看。
[解决办法]
指针跑飞一般原因有以下几种:
1.中断
2.看门狗
3.内存溢出
4.编译器优化的问题

[解决办法]
问题还真是挺奇怪的,也许和2440的CACHE有关

不知你的指令cache和数据cache怎么配置的,在启动汇编里。

把cache禁止掉试试。

另外,如果启用了虚拟地址映射,把那个也关了试试。

再不行建议你把上面这个字库链表从UCGUI中拿出来,建个小工程,调试一下,如果没问题,证明你的程序
其他部分某个地方把这里的内存内容修改了,那你就只有慢慢找了。
[解决办法]
我大致看了下,觉得是你的for循环的结束条件没有满足,指针指向了一个未知地方,导致程序跑飞了。你仔细检查一下。
[解决办法]
看过一遍,比较感兴趣a8的初始化:
GUI_FLASH const GUI_FONT_PROP GUI_FontHZ17x19_Prop_a8 =
{
    /// ????
};

不明白你说的跑飞是指什么?指针地址不对还是程序崩溃?

一个猜测是a8.pnext没有设置为null,for循环没有了停止条件,然后在循环多次后指向了某块禁止访问的内存区域,crash
[解决办法]
#if 0
#endif

多设置几个这样的,定位是哪一段程序出问题

热点排行