NDK中使用pthread多线程中自己写的一个BUG
在使用pthread进行NDK中的多线程开发时,自己写了一个BUG,
void *darkGrayThread(void *args)
{
ThreadParam *param = (ThreadParam *)args;
LOG("start%d end%d ", param->start, param->end);
int end = param->end;
for(int i = param->start, j = i * ; i < end; ++i, j+=)
{
LOG("d1");
param->r[i] = param->rgba[j];
param->g[i] = param->rgba[j + ];
param->b[i] = param->rgba[j + ];
LOG("d2 %d end%d", i, param->end);
param->dark[i] = MINT(param->rgba[j], param->rgba[j + ], param->rgba[j + ]);
param->gray[i] = (UCHAR)((param->rgba[j] * + param->rgba[j + ] * +param->rgba[j + ] * ) >> );
LOG("d3");
}
}
这个是启动函数,即相当于Java中的Thread的run方法。初一看没啥问题,编译也能过,APP也能跑,但是每次都会crash。我把crash线程的log贴出来如下:
- ::31.577 D MyJni : d2 end2073600
- ::31.637 D MyJni : d3
- ::31.641 D MyJni : d3
- ::31.641 D MyJni : d1
- ::31.641 D MyJni : d2 end2073600
- ::31.642 D MyJni : d3
- ::31.642 D MyJni : d1
- ::31.642 D MyJni : d1
- ::31.642 D MyJni : d2 end2073600
- ::31.642 D MyJni : d3
- ::31.642 D MyJni : d3
- ::31.785 D MyJni : d2 end2073600
- ::31.785 D MyJni : d3
- ::31.785 D MyJni : d1
- ::31.786 D MyJni : d1
- ::31.786 D MyJni : d2 end2073600
- ::31.786 D MyJni : d2 end2073600
- ::31.786 D MyJni : d3
- ::31.786 D MyJni : d2 end2073600
- ::32.339 F libc : Fatal signal (SIGSEGV), code , fault addr 0xc6800000 in tid (Thread-)
- ::32.339 F libc : Fatal signal (SIGSEGV), code , fault addr 0xc6800000 in tid (Thread-)
- ::32.340 W : debuggerd: handling request: pid= uid= gid= tid=
- ::32.381 F DEBUG : pid: , tid: , name: Thread- >>> com.willhua.opencvstudy <<<
- ::32.381 F DEBUG : signal (SIGSEGV), code (SEGV_MAPERR), fault addr 0xc6800000
- ::32.381 F DEBUG : r0 000000a7 r1 c6600000 r2 cac6ef0e r3 000000be
- ::32.381 F DEBUG : r4 caa4ca9c r5 r6 r7 c62038f8
- ::32.381 F DEBUG : r8 r9 000001d3 sl cac6ef0e fp cac6ebe0
- ::32.381 F DEBUG : ip c7680000 sp c62038e8 lr caa8e93f pc caa8e99a cpsr 200f0030
- ::32.383 F DEBUG :
- ::32.383 F DEBUG : backtrace:
- ::32.383 F DEBUG : # pc 0004099a /data/app/com.willhua.opencvstudy-/lib/arm/libOpenCV.so (_Z14darkGrayThreadPv+)
- ::32.383 F DEBUG : # pc 000475d3 /system/lib/libc.so (_ZL15__pthread_startPv+)
- ::32.383 F DEBUG : # pc 00019d3d /system/lib/libc.so (__start_thread+)
从log中看出,是内存访问错误,然后使用addr2line工具定位到是上述代码中的第13行。
再仔细一点可以看到,log中打印的end都比前面的数字小!!!上面不是有for循环的条件语句吗?怎么会出现这种情况!?其中的MINT只是我使用define定义的求三个数中的最小数的宏。
为了确定问题,我把13写成了
UCHAR uu = MINT(param->rgba[j], param->rgba[j + ], param->rgba[j + ]);
param->dark[i] = uu;
然后根据log分析,还是param->dark[i] = uu; 这行报错。然后我又跑去前面的代码确定给dark分配的内存没有问题。还是没找到原因。
后面突然发现,写的darkGrayThread没有写返回值!于是赶紧再后面添加一句return (void *)0; 再测试,发现没问题,原因就是这个了。
为了知道原因,我在没有写return的版本的最后添加LOG("endend"); 发现每次都会有数量不等的endend日志打印出来。这说明for的条件语句还是有退出循环的作用的。
要想继续分析,可能需要对比有没有return的两个版本的汇编代码,来比较一下有没有return他们翻译成汇编的区别,待后续分析。
这个问题的收获就是:写启动程序一定记得有return语句,即使你的return值没有用!
NDK中使用pthread多线程中自己写的一个BUG的更多相关文章
- 写了一个bug,最后却变成了feature,要不要修呢?
事情是这样子的,前不久接到一个需求,为一个游戏开发礼包码功能 通常一款游戏运营期间会搞各种各样的活动吸引玩家,其中最常见的就是发放礼包, 玩家可以通过礼包码兑换礼包. 用礼包码兑换礼包有个一限制,游 ...
- winform中如何在多线程中更新UI控件--ListView实时显示执行信息
1.在winform中,所有对UI的操作,都得回到UI线程(主线程)上来,才不会报错 线程间操作无效: 从不是创建控件的线程访问它. 2.在winform中,允许通过Control.invoke对控件 ...
- WinForm中 事件 委托 多线程的应用【以一个下载进度条为例】
第一步:首先我们创建一个winfor的项目 第二步:我们建一个窗体 在一个窗体里面 打开一个另外的窗体 另外的窗体有一个按钮 点击后就开始下载 下载完成后 在注册窗体上面 显示下载完成(达到在一个窗体 ...
- SLua 中继承 C# 类接口 Slua.Class 的一个 Bug。
由于目前要把大量的代码移植到 lua 中(真是够虐心的),面向对象肯定少不了,项目的代码都是这么设计的,于是就测试 Slua.Class 接口来扩展 C# 的类,发现有点问题,给作者提交了一个 Iss ...
- 终于,帮开发写了一个bug
写在文章的开头 最近项目比较紧,尤其前端的的需求比较多,作为一名测试,也会些vue,本着加快项目进度的美好想法,就自告奋勇的向组长承接了一部分开发的任务,其中有个需求需要在我们的广告管理后台新增一个上 ...
- WinForm中 事件 委托 多线程的应用
WinForm中 事件 委托 多线程的应用[以一个下载进度条为例] 第一步:首先我们创建一个winfor的项目 第二步:我们建一个窗体在一个窗体里面 打开一个另外的窗体 另外的窗体有一个按钮 点击后就 ...
- 多线程中的lua同步问题
最近写paintsnow::start时出现了一个非常麻烦的BUG,程序的Release版本大约每运行十几次就会有一次启动时崩溃(Debug版本还没崩溃过),崩溃点也不固定.经过简单分析之后,确定是线 ...
- <转>多线程中的lua同步问题
转自 http://www.cnblogs.com/ghost240/p/3526185.html 最近写paintsnow::start时出现了一个非常麻烦的BUG,程序的Release版本大约每运 ...
- Java多线程中的死锁问题
Java程序基本都要涉及到多线程,而在多线程环境中不可避免的要遇到线程死锁的问题.Java不像数据库那么能够检测到死锁,然后进行处理,Java中的死锁问题,只能通过程序员自己写代码时避免引入死锁的可能 ...
随机推荐
- gdb remote 使用
//设置halt (gdb) set {int}0x400b0000 = 0x1(gdb) load //设置下一个pc指针的值(gdb) set {int}0x400b2000 = 0x80(gdb ...
- Kubernetes 持续集成 SpringCloud
写在开始之前,在开始之前我们需要了解几个概念: 1.什么是持续集成? 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次 ...
- 使用 Kubeadm 升级 Kubernetes 版本
升级最新版 kubelet kubeadm kubectl (阿里云镜像) cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kuberne ...
- mysql 开发基础系列16 视图
一. 什么是视图视图是一种虚拟存在的表,行和列数据来自,定义视图的查询中使用的表,并且是在使用视图时动态生成的.优势有: 简单: 使用视图的用户完全不需要关心后面对应的表的结构,关联条件,筛选条件. ...
- web.xml配置web中的key points(下)
一.配置jsp页面 [jsp-config]中有两个子元素[taglib][jsp-property-group],注意,前者必须出现在后者之前. ①[taglib]替代jsp页面中taglib指令 ...
- python 闯关之路四(上)(并发编程与数据库理论)
并发编程重点: 并发编程:线程.进程.队列.IO多路模型 操作系统工作原理介绍.线程.进程演化史.特点.区别.互斥锁.信号. 事件.join.GIL.进程间通信.管道.队列. 生产者消息者模型.异步模 ...
- Java——static关键字
前言 static关键字算是Java中比较复杂的关键字之一,它可以修饰变量.方法.类以及代码块.下面将介绍static的具体使用. static引入的目的 static的作用 static修饰变量 s ...
- json数据格式说明
格式说明 json文件由对象(集合).数组.key/value元素组成,可以相互嵌套. 使用大括号包围的是对象,使用中括号包围的是数组,冒号分隔的是元素. 元素的key只能是字符串. 元素的value ...
- 高负载集群实战之lvs负载均衡-技术流ken
lvs简介 LVS的英文全称是Linux Virtual Server,即Linux虚拟服务器. 特点 跨平台:window,linux 作用 实现负载均衡 核心组件 ip_vs:linux的内核功能 ...
- Python中return self的用法
在Python中,有些开源项目中的方法返回结果为self. 对于不熟悉这种用法的读者来说,这无疑使人困扰,本文的目的就是给出这种语法的一个解释,并且给出几个例子. 在Python中,retur ...