在使用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的更多相关文章

  1. 写了一个bug,最后却变成了feature,要不要修呢?

    事情是这样子的,前不久接到一个需求,为一个游戏开发礼包码功能 通常一款游戏运营期间会搞各种各样的活动吸引玩家,其中最常见的就是发放礼包,  玩家可以通过礼包码兑换礼包. 用礼包码兑换礼包有个一限制,游 ...

  2. winform中如何在多线程中更新UI控件--ListView实时显示执行信息

    1.在winform中,所有对UI的操作,都得回到UI线程(主线程)上来,才不会报错 线程间操作无效: 从不是创建控件的线程访问它. 2.在winform中,允许通过Control.invoke对控件 ...

  3. WinForm中 事件 委托 多线程的应用【以一个下载进度条为例】

    第一步:首先我们创建一个winfor的项目 第二步:我们建一个窗体 在一个窗体里面 打开一个另外的窗体 另外的窗体有一个按钮 点击后就开始下载 下载完成后 在注册窗体上面 显示下载完成(达到在一个窗体 ...

  4. SLua 中继承 C# 类接口 Slua.Class 的一个 Bug。

    由于目前要把大量的代码移植到 lua 中(真是够虐心的),面向对象肯定少不了,项目的代码都是这么设计的,于是就测试 Slua.Class 接口来扩展 C# 的类,发现有点问题,给作者提交了一个 Iss ...

  5. 终于,帮开发写了一个bug

    写在文章的开头 最近项目比较紧,尤其前端的的需求比较多,作为一名测试,也会些vue,本着加快项目进度的美好想法,就自告奋勇的向组长承接了一部分开发的任务,其中有个需求需要在我们的广告管理后台新增一个上 ...

  6. WinForm中 事件 委托 多线程的应用

    WinForm中 事件 委托 多线程的应用[以一个下载进度条为例] 第一步:首先我们创建一个winfor的项目 第二步:我们建一个窗体在一个窗体里面 打开一个另外的窗体 另外的窗体有一个按钮 点击后就 ...

  7. 多线程中的lua同步问题

    最近写paintsnow::start时出现了一个非常麻烦的BUG,程序的Release版本大约每运行十几次就会有一次启动时崩溃(Debug版本还没崩溃过),崩溃点也不固定.经过简单分析之后,确定是线 ...

  8. <转>多线程中的lua同步问题

    转自 http://www.cnblogs.com/ghost240/p/3526185.html 最近写paintsnow::start时出现了一个非常麻烦的BUG,程序的Release版本大约每运 ...

  9. Java多线程中的死锁问题

    Java程序基本都要涉及到多线程,而在多线程环境中不可避免的要遇到线程死锁的问题.Java不像数据库那么能够检测到死锁,然后进行处理,Java中的死锁问题,只能通过程序员自己写代码时避免引入死锁的可能 ...

随机推荐

  1. openjtag 的硬件连接踩坑历程

    这个事情踩了不少坑,这个要记录一下: 1 代码的下载和编译按照下面的来:https://github.com/pulp-platform/pulp-debug-bridge 注意点: A 要最好使用p ...

  2. JAVA面试题-数组字符串基础

    1.大写的Integer和String是可变类还是不可变类?怎么定义不可变类?不可变.用final关键字,如public final class Integer extends Number 2.比较 ...

  3. 全网最详细的基于Ubuntu14.04/16.04 + Anaconda2 / Anaconda3 + Python2.7/3.4/3.5/3.6安装Tensorflow详细步骤(图文)(博主推荐)

    不多说,直接上干货! 前言 建议参照最新的tensorflow安装步骤(Linux,官方网站经常访问不是很稳定,所以给了一个github的地址):         https://github.com ...

  4. 如何正确的在项目中接入微信JS-SDK

    微信JS-SDK的功能 如果你点进来,那么我相信你应该知道微信的JS-SDK可以用来做什么了.微信的官方文档描述如下. 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. ...

  5. Long类型时间如何转换成视频时长?

    数据库中存放的视频时长是一个Long类型的毫秒/秒时间,现在需要把这个时间转换成标准的视频时长格式,在我看来这应该是一个很常用的转化有一个很常用的转换方法工具才对,可是我百度找了许久,没有一个简单直观 ...

  6. IDEA远程仓库版本回滚

    访问我的博客 使用 git 进行项目的版本控制时,肯定会遇到回滚版本的情况,回滚有两种,一种是本地仓库回滚,另外一种是远程仓库回滚.以下详细讲解两种回滚方式,本文主要讲解远程回滚,以及常见使用误区. ...

  7. Win32文件系统编程

    Win32文件系统编程 一丶了解什么是文件系统 文件系统是抽象的.是windows在软件层面提供的一层虚拟的数据结构. 文件系统分为NTFS 跟 FAT32. 具体看看两者的区别吧. 磁盘分区容量. ...

  8. IDEA的几个常用配置,日常开发必备。

    用了IDEA有很长时间了,身边的同事朋友也都慢慢的开始都从Eclipse切换到IDEA了,其实无论是Eclipse还是IntelliJ IDEA都是开发工具而已,各自都有优点.但是刚从Eclipse切 ...

  9. shell编程基础(二): shell脚本语法之分支语句和循环语句

    一.分支语句 1.条件测试:test [ 命令test或[可以测试一个条件是否成立,如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为1(注意与 ...

  10. Spring Boot入门(13)自制音乐平台

      经过笔者这几天的辛勤劳作(其实就是苦逼地码代码),一个新的网站已经上线啦!该网站是用Spring Boot工具写的,主要实现的功能如下: 根据歌曲名称和音乐平台搜索歌曲,并实现歌曲的在线播放: 歌 ...