社区导航

 

搜索
查看: 4192|回复: 23

一个任务异常挂起(有相关的定位数据),求进一步的定位方法

[复制链接]

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-2-28 22:37 | 显示全部楼层 |阅读模式
操作系统:VxWorks,CPU:MPC860,IDE:Tornado2.0
现象:
1.程序(此程序很大有几十个任务运行)运行一段时间后异常复位,每次复位之间的时间间隔无规律,有时半个小时,有时2个小时,有时5,6个小时。
2.通过打印了解到,是由于一个任务tlongtimer被异常挂起(suspended)了,该任务1S执行一次,主要执行两个函数:A(先),B(后),即:
tlongTimer
{
  A;
  B;
  delay(1s);
}

又由于需要,A和B两个函数都用了两个二进制信号量(Mutex1,Mutex2)与其他的函数进行互斥,即
A                                         
{
  semtake(Mutex1);
  semtake(Mutex2);
..................
  semGive(Mutex2);
  semGive(Mutex1);
}

B
{
  semtake(Mutex1);
  semtake(Mutex2);
..................
  semGive(Mutex2);
  semGive(Mutex1);
}

这里我个人认为有必要介绍一下另外一个任务的情况:tShortTimer,10ms执行一次,它的优先级和tLongTimer一样,它主要执行一个函数C,但C只用了Mutex2与A和B进行互斥,即
C
{
semTake(Mutex2);
....
semGive(Mutex2);
}

3.当出现tlongtimer被挂起后,我用tt命令查看了它的调用栈,发现被挂起之前最后调用的函数是A的semGive,或者B的semGive,至于是semGive哪个信号量,不知道(有方法可以定位出来吗?)

4.再用ti命令查看tLongtimer的TCB信息,打印出N个(大概30多个,有什么R31,R3....,当然有SP和PC)寄存器的值(我不知道绝大部分的寄存器代表什么意思,所以无法定位,有资料可以看吗?),同时还打印出出现异常时该任务的PC地址,我用lkaddr查了一下,该地址对应的函数就是semGive。

我的问题:
收集到这些数据后,我感觉离异常的根因很近了,但又觉得很远。
1.是不是因为采用了二进制信号量?因为我看VxWorkx的帮助文档,说二进制信号量主要用于同步,而互斥信号量用于互斥,但我个人觉得二进制信号量这样用应该也可以起到互斥的作用。
2.是不是tLongtimer的堆栈信息被其他的任务或自身的函数改写了?导致信号量的ID为无效值,所以semGive失败?

定位到这里,我不知道该如何定位下去了,还需要采集其他数据吗?如何采集(用什么命令)?还有什么好的定位策略吗?
这个鸟问题烦了我10多天了,请各位大虾帮忙拯救我




1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-1 10:56 | 显示全部楼层
什么时候eeworld也变冷了?还是觉得问题多分太少?那我再加分

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-1 22:50 | 显示全部楼层
感觉LZ的程序逻辑上有问题
从现象上看 是没有规律的 也就是说这种现象是由一种随机出现的事件引起的
看一下两个任务 一个是1S执行一次 一个是10S执行一次
而且 从现象上推断 估计两个任务的执行时间长度肯定是不规律的
出现这种情况通常都是任务间共享资源互斥逻辑上出现问题
不妨在程序中适当输出一些打印信息 例如把每次获取和释放信号量之后的情况打印出来 判断信号量是否获取成功之类的信息

然后在超级终端里捕获一下LOG 对比对比  也许能发现任务死锁的原因

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-6 00:31 | 显示全部楼层
谢谢15楼的兄弟共享的调试方法,非常不错的文章,思路清晰,定位准确,值得学习!
同时,提个问题,这种定位方法是不是需要CPU支持呢?怎么知道哪些CPU支持这种调试方法?
你们说的OCD是集成在CPU内部的吧?
还是说OCD是我需要额外去买的器件?我很想用这种方法去定位我的那个鸟问题!


我非常赞成FireAngel关于去定位寄存器的说法,但是
r0     =        0   sp     =  2692420   r2     =        0    r3     =        0
r4     =        0   r5      =        0       r6     =        0    r7     =        0
r8     =        0   r9      =        0      r10    =        0    r11    =        0
r12    =        0   r13    =        0      r14    =        0    r15    =        0
r16    =        0   r17    =        0      r18    =        0    r19    =        0
r20    =        0   r21    =        0      r22    =        0    r23    =        0
r24    =        0   r25    =        0      r26    =        0    r27    =        0
r28    =        0   r29    =    ffffffff      r30    =   b030    r31    =  17e0700
msr   =  b030     lr     =        0       ctr    =        0     pc     =   1423c0
cr     = 20000043  xer =        0
这些寄存器的含义是什么?有没有说明文档?发给小弟,谢谢!

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-6 23:35 | 显示全部楼层
从信号量的使用上来说,不应该用二进制信号量进行代码互斥,而应该使用互斥的信号量来保护。二进制信号量谁都可以take和give,很难保证不出问题。
当然这个一般不会出现导致异常的情况,除非其他任务中有对信号量删除操作之类的。
出异常后,应该会有一段提示出错的信息的,查一下。同时看一下任务堆栈有没有溢出之类的,很多情况下异常都跟堆栈溢出有关

回复

使用道具 举报

8

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2009-3-1 13:26 | 显示全部楼层
锁的顺序不太对像,会不会锁起了?

回复

使用道具 举报

2

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-1 19:26 | 显示全部楼层
2楼的是说,任务死锁吗?
你的论据呢?
怎么样可以证明是任务死锁呢?

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-1 23:01 | 显示全部楼层
根据异常堆栈,结合addr2lineppc.exe小程序可以定位到哪一行调用被挂起.

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-1 23:22 | 显示全部楼层
4楼兄弟的意思我明白,有一个任务是10ms级的,如果要输出打印的话,似乎太多了吧?
兄弟你说我的程序逻辑似乎有问题,我曾经这么觉得,但有找不出哪里有问题,
或者你能帮我找一个特例说明我的程序逻辑有问题?

addr2lineppc没有用过,5楼的兄弟能不能说得更细些,我只能得到一个任务的调用函数之间的关系,如何能得到函数中局部变量的地址和值,有办法吗?

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-3 12:01 | 显示全部楼层
从逻辑上看来,两个进程之间这样是没问题的,不应该导致死锁。
有没有这样的可能:tShortTimer负载太重,以至于有时候不能在10ms内完成,新的中断又来了,导致自己挂在自己上面。这个时候tShortTimer无法释放mutex,导致两个进程都挂在mutex2上?

我觉得可以如下调试试试看:
1), 将tShortTimer中工作屏蔽掉,只是semTake后semGive,看会不会出现类似错误。
2), 将tlongtimer中A和B的工作屏蔽掉,只是semTake后semGive,看会不会出现类似错误
3), 将tlongtimer和tShortTimer中的工作都屏蔽掉,只是semTake后semGive,看会不会出现类似错误
4), 如果能确定是tLongTimer或tShortTimer引起的,在慢慢往里面回复以前的操作,反复实验,这样应该能找出问题来。

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-3 13:03 | 显示全部楼层
能否尝试将别的任务先不启动,只运行这几个任务,也许问题不一定是在这里。
关于调试查看寄存器,我不知道怎么发给你,所以就贴到我的博客中了,你看看,也许有用。

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-3 11:47 | 显示全部楼层
mark

回复

使用道具 举报

2

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-3 12:21 | 显示全部楼层
记号。

回复

使用道具 举报

2

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-4 14:34 | 显示全部楼层
楼上的兄弟,你说的没错,是需要OCD支持的。事实上,你没有OCD怎么调试呢?

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-4 20:39 | 显示全部楼层
用仿真器当然好啊
不过那东西好贵呀
我们这边一般都是轮着用
所以通常都是通过分析代码和SHELL接口调 其实有很多问题都可以通过分析代码搞定
LZ加油啊
解决了之后定要把分析方法拿来共享一下哈

回复

使用道具 举报

2

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-3 23:08 | 显示全部楼层
觉得楼主的这个问题挺有意思的
今天恰好有时间 就在PC上sim了一下
写的代码很简单
除了信号量操作之外只加了空的循环操作
因为要看看输出的结果 所以延时上也比LZ的10ms多了很多
跑了一个下午 没出问题
所以怀疑可能是LZ代码中其他的操作引起的问题或者阻塞
8楼兄弟提出的方法不错  建议楼主试试看 :)

回复

使用道具 举报

2

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-4 00:39 | 显示全部楼层
白天忙所以只有晚上看论坛。谢谢各位大侠出的点子,挺感动的,当一个人陷入困境的时候,有其他人的帮助,这种感觉真好。

7楼说的Mark和9楼说的记号,是一种工具还是一种调试手段?能说仔细点吗?

谢谢8楼和11楼的仁兄出点子,现在基本上可以排除是任务死锁造成的了,我怀疑是任务堆栈被异常改写,所以semGvie释放了一个无效的信号量。
10楼的兄弟,麻烦你把资料传给我,我的邮箱是hddream@163.com或者帮你的博客网址给我,谢谢了!

现在最重要的:定位数据堆栈被异常改写有什么好的、快速的调试手段或方法吗?
(数据断点也可以啊,怎么玩?)



回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-4 10:36 | 显示全部楼层
Mark的意思就是先做个记号,等会在回来看这个问题。
调试栈被修改是比较麻烦的问题哦。你不是可以用tt打印出来么?应该能看到一层层下来的调用关系啊。作为一个底层的programmer,错误定位到一定的方位后,通过读代码找出代码中的问题也是很重要的能力。
另外,你可以看看异常相关的寄存器,至少你能看出发生了什么异常,另外就是发生地址。

抱歉啊,860太古老了,从我工作开始,就没有机会接触过。但是应该跟其他MPC相似吧?

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-4 10:39 | 显示全部楼层
数据断点,就是硬件断点的一种啦,是硬件提供的一种调试能力,一般是CPU提供1-2套寄存器,将你要观察的地址设置好,下次针对该地址的有读/写操作,就会发生中断,然后你可以看到是谁访问了那里。挺好的方法。

另外还有硬件程序断点,类似上面,将代码的地址设置到寄存器里,下次PC跑到这的时候就断住了。跟软件断点不同的是,软件断点一般是调试器通过修改内存中的代码,插入调试代码后实现的。硬件断点无需这样。

回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2009-3-4 10:46 | 显示全部楼层
我的博客在eeworld上,你把鼠标移动到我的用户名上,就会显示这个链接的。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 /5 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2020-2-22 05:44 , Processed in 0.567794 second(s), 19 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表