您当前位置: 首页 »

[linux总结]

分类目录归档: [linux总结]

【ios、x264】将静态库打包成动态库,链接时的text relocations错误

最近在ios上出现将多个sdk放到一个app时,有各种开源静态库冲突的问题;于是考虑将自己用到的库进行打包成动态库版本,以此解决冲突问题。

在进行打包成动态库时,发现x264问题最大。打包出来的库在链接期出现text relocations错误,网上找了以后发现基本都是进行忽略这个错误,事实上这个错误忽略了没用,app启动时还是会出现相应的crash。

换了几个版本的xcode进行测试,发现x264编译会出现不同情况的告警和错误,根据底部罗列的参考文章,估计xcode的编译器可能也有一些bug。

后来模仿android上的编译方式,在x264里加入了–enable-pic和–disable-asm顺利编译通过,但由于osx和xcode版本的因素,模拟器上的并没有编译出来,仅仅编译了armv7和arm64。

 

参考文章:

MacOSX下编译linphone(text-relocation错误说明)

libxxx.so- text relocations问题的终极解决方案(android)

Linker error when using incremental builds on iPhone

Android Gradle编译so库或运行时出现 text relocations 崩溃的正确解决方法

2018-06-15 | | [linux总结], unix编程环境学习, 编码技巧, 音视频_图像相关, 音视频编解码

【ios、x264】将静态库打包成动态库,链接时的text relocations错误已关闭评论

【MAC、iOS、Webrtc】由于证书问题导致webrtc编译隐形失败问题

由于最近在接手一些脏活累活,所以就被拉来解决一下ios下关于播放设备切换的问题,实际上当听到这个问题的现象是基本可以判断播放设备切换的时候没有重设播放参数引起的。

后面说为了给我个环境去调一下,iMac拿过来很开心的执行编译,谁知道编译隐形失败。。。之所以说隐形失败是gyt_webrtc和ninjia没有报错什么让人感觉在意的错。

捣腾了几天,七弄八弄的最后查到由于在执行gyp_webrtc后通过gyp生成的ninja中有几个主要工程配置没有生成。

当时由于感觉找到完整的问题了,今天过来就直接干脆手动执行后续的步骤把整个编译执行完成。起初发现有问题,因为i386的构架被打包到静态库了,然后网上找到删除掉i386方法,随之删掉i386手工合成最终的包,加入到xcode工程里面跑,结果连接失败,出现符号找不到。

继续查问题,最终还是留意到了gyp_webrtc的错误,错误如下:

iMac:build hyt$ ./ios.sh release
Updating projects from gyp files...
Traceback (most recent call last):
  File "../src/webrtc/build/gyp_webrtc", line 115, in <module>
    gyp_rc = gyp.main(args)
  File "/Users/hyt/webrtc/src/chromium/src/tools/gyp/pylib/gyp/__init__.py", line 538, in main
    return gyp_main(args)
  File "/Users/hyt/webrtc/src/chromium/src/tools/gyp/pylib/gyp/__init__.py", line 523, in gyp_main
    generator.GenerateOutput(flat_list, targets, data, params)
  File "/Users/hyt/webrtc/src/chromium/src/tools/gyp/pylib/gyp/generator/ninja.py", line 2469, in GenerateOutput
    pool.map(CallGenerateOutputForConfig, arglists)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 251, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 567, in get
    raise self._value
AssertionError: Multiple codesigning fingerprints for identity: iPhone Developer

网上查到主要是证书冲突问题。
解决步骤大致如下:

1,列出有效证书

security find-identity

2,寻找证书配置gyp文件

find . -name common.gypi | xargs grep CODE_SIGN_IDENTITY

会看到这么几行:

./chromium/src/build/common.gypi: ‘CODE_SIGN_IDENTITY[sdk=iphoneos*]’: ‘iPhone Developer’,
./chromium/src/build/common.gypi: ‘CODE_SIGN_IDENTITY[sdk=iphoneos*]’: ”,

3,用之前证书列表中Valid identities only的字段替换‘iPhone Developer’里面的内容

 

4,重新执行gyp_webrtc即可

2017-03-01 | | [linux总结], chromium, iOS, 移动开发, 音视频_图像相关

【MAC、iOS、Webrtc】由于证书问题导致webrtc编译隐形失败问题已关闭评论

最近手头需要做的几件事情

  1. 看nat穿越中的开源代码,优先看udt。先把udt实现看明白(主要是重发包这些)
  2. webrtc之前项目中没有用到的代码继续学习
  3. tcp单边和双边加速的原理理解和学习
  4. opencv部分代码深入看
  5. *caffe,实在没办法了,模式识别中的模板匹配越做越复杂了,要换个路子走了
2016-11-21 | | [linux总结], *生活*, 思考

最近手头需要做的几件事情已关闭评论

【pthread、多线程、同步】关于pthread条件变量的疑惑

由于最近在看开源代码,手里的开源代码为了能够比较好的可移植性,在代码中加了很多宏,并在linux用了pthread库。

其中对于pthread的条件变量理解很是疑惑,看pthread手册后还是有不解,感觉条件变量用起来太奇怪,在pthread_cond_wait时,互斥到底有没有释放等问题上没搞明白,上代码调试后遍便豁然开朗。先贴一个修改过的官方代码例子:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#include <iostream>

#include <unistd.h>

using namespace std;

#define NUM_THREADS  3
#define TCOUNT 10
#define COUNT_LIMIT 12

int     count = 0;
pthread_mutex_t count_mutex;
pthread_cond_t count_threshold_cv;

void *inc_count(void *t)
{
  int i;
  long my_id = (long)t;

  for (i=0; i < TCOUNT; i++) {
    pthread_mutex_lock(&count_mutex);
    count++;

    /*
    Check the value of count and signal waiting thread when condition is
    reached.  Note that this occurs while mutex is locked.
    */
    /*if (count == COUNT_LIMIT)*/ {
      printf("inc_count(): thread %ld, count = %d  Threshold reached. ",
             my_id, count);
      pthread_cond_signal(&count_threshold_cv);
      printf("Just sent signal.\n");
      }
    printf("inc_count(): thread %ld, count = %d, unlocking mutex\n",
	   my_id, count);
    pthread_mutex_unlock(&count_mutex);

    /* Do some work so threads can alternate on mutex lock */
    sleep(1);
    }
  pthread_exit(NULL);
}

void *watch_count(void *t)
{
  long my_id = (long)t;

  printf("Starting watch_count(): thread %ld\n", my_id);

  /*
  Lock mutex and wait for signal.  Note that the pthread_cond_wait routine
  will automatically and atomically unlock mutex while it waits.
  Also, note that if COUNT_LIMIT is reached before this routine is run by
  the waiting thread, the loop will be skipped to prevent pthread_cond_wait
  from never returning.
  */
  pthread_mutex_lock(&count_mutex);
  while (1) {
    printf("watch_count(): thread %ld Count= %d. Going into wait...\n", my_id,count);
    pthread_cond_wait(&count_threshold_cv, &count_mutex);
    printf("watch_count(): thread %ld Condition signal received. Count= %d\n", my_id,count);
    printf("watch_count(): thread %ld Updating the value of count...\n", my_id,count);
    //count += 125;
    printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
    }
  printf("watch_count(): thread %ld Unlocking mutex.\n", my_id);
  pthread_mutex_unlock(&count_mutex);
  pthread_exit(NULL);
}

void cond_test()
{
	cout << "---------- cond_test ----------" << endl;

	int i, rc;
	long t1=1, t2=2, t3=3;
	pthread_t threads[3];
	pthread_attr_t attr;

	/* Initialize mutex and condition variable objects */
	pthread_mutex_init(&count_mutex, NULL);
	pthread_cond_init (&count_threshold_cv, NULL);

	/* For portability, explicitly create threads in a joinable state */
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

	pthread_create(&threads[0], &attr, watch_count, (void *)t1);
	usleep(1000*20);
	pthread_create(&threads[1], &attr, inc_count, (void *)t2);
	//pthread_create(&threads[2], &attr, inc_count, (void *)t3);

	/* Wait for all threads to complete */
	for (i = 0; i < NUM_THREADS; i++) {
		pthread_join(threads[i], NULL);
	}
	printf ("Main(): Waited and joined with %d threads. Final value of count = %d. Done.\n",
	          NUM_THREADS, count);

	/* Clean up and exit */
	pthread_attr_destroy(&attr);
	pthread_mutex_destroy(&count_mutex);
	pthread_cond_destroy(&count_threshold_cv);
	//pthread_exit (NULL);
}

首先说一下例子,主线程创建一个inc线程和watch线程,每次inc线程激活条件变量,这时watch线程被激活。
为了测试在pthread_cond_wait函数进入是,互斥有没有被释放掉。因此注释掉高亮部分的代码,发现inc线程永远不会被激活。说明在pthread_cond_wait时会将互斥进行释放,接下来等有空一定要抽空看看pthread的实现代码。以及比较一下vs是如何将pthread库进行伪封装后在windows上提供使用的。

2016-11-15 | | [linux总结]

【pthread、多线程、同步】关于pthread条件变量的疑惑已关闭评论

通过windows和linux在socket上的几点相同点,来揣测windows和linux在某些实现上的相似

首先,我是一个完全的linux开发初学者,我仅仅在windows做开发,由于兴趣与工作的缘故碰到了通过已有的socket模型搭建好的网络库。下面就说说在windows下,我了解到socket模型(准确是标准socket模型,对于微软封装过的一些模型我不是很清楚)

1,普通阻塞是socket:

普通的socket模型,就是msdn中对socket api族介绍中最简单的那个例子。这种最简单,在执行效率上相对较低,在处理send/recv(sendto/recvfrom)时,函数是处于阻塞的。在简单环境,或者写一些简单的测试工具时,这是一种比较理想的用法。

2,同步 select模型

同步select模型,其实可以是理解为普通阻塞式sokcet的一个扩展,就是利用select来对socket句柄进行监听,避免由于调用send/recv(sendto/recvfrom)时出现阻塞。

3,异步select模型

异步select模型,可以看成是同步select的一种变化。即send/recv(sendto/recvfrom)函数不会阻塞,调用立即返回,并需要同时配合select函数一同使用。

4,IOCP

异步IO模型,使用上可以和异步select模型类比;但这并非标准socket模型。

 

然后接下来再说一下几个模型的差别:

1,普通socket、select模型,在调用send/recv(sendto/recvfrom)函数时,均会出现一次多余的内存拷贝。即,用户态传如一个buffer时,在转为交给协议栈之前,必须通过内存拷贝的方式,将数据复制到内核态的内存中。

2,windows上select集合最大值大约是64/128(有系统版本决定);换句话说一个调用select函数的线程,最大可监听64/128个socket句柄

*3,据网上各种文档介绍到,select是基于内核态线程轮询完成,具体不详,有待考证!

4,IOCP 和其他几者最大区别在于内存拷贝上,由于IOCP是通过共享内存(即内存映射)。在windows中内存映射属于一个特殊的内存管理器的管辖范围,他即不属于内核态,也不属于用户态内存,当对于内核态或用户态线程来说,只要通过调用内存映射函数,就可以直接访问这块内存(但得到的逻辑地址或许是不同的)。

由于在WSARecv/WSASend之类函数中,提交的均为共享内存,因此无需做任何内存拷贝。所以在IOCP上,性能要更好的多。同时本人的了解范畴也仅限于这一块,对于IOCP的事件投递过程并不是很清楚,但根据《软件调试》一书中对“windows系统调试/windows软件调试”设计的讲述来看,IOCP这种的实现应该是在内核态也同样创建了和用户态以之对应的内核服务线程。

 

接着再说说linux,刚刚看了一下epoll的介绍。

发现epoll是基于事件回调+内存映射来实现IO上的高效;同时这篇文章也还介绍了几个常用的socket模型在linux中的大概实现。通过这篇文章至少能够看出,linux和windows在对socket的实现上存在很大的相似。

可见linux和windows存在很多相似的地方,如果linux和windows互相对应着学,理解起来可能会快很多。

2015-11-16 | | [linux总结], linux kernel, unix编程环境学习, win api

通过windows和linux在socket上的几点相同点,来揣测windows和linux在某些实现上的相似已关闭评论

linux环境下调试真机的usb配置问题

在windows上调试真机,只需要装驱动就行了。

linux上简单一些,直接插上去就可以认出usb设备,但麻烦的是需要配置相应的usb配置项,步骤如下:

1,执行一下lsusb,得到下面的东西

Bus 002 Device 002: ID 2299:1411  
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

2,因为手里面的是个山寨机,所以显示不出描述来也是正常的。下面这条就是

Bus 002 Device 002: ID 2299:1411 

修改/etc/udev/rules.d/51-android.rules的配置文件(如果没有这个配置文件,就直接创建好了)

SUBSYSTEM=="usb", ATTR{idVendor}=="2299", MODE="0666", GROUP="plugdev"

然后重启一下udev服务

/etc/init.d/udev restart

接着在重启adb

adb kill-server
adb start-server
2015-09-11 | | [linux总结], android

linux环境下调试真机的usb配置问题已关闭评论

linux环境的中的eclipse里的logcat日志无法正常显示

装了debian 8以后,在用最新版的eclipse(mars)+adt调试android代码时,发现logcat日志是有的,但是无法显示在界面上。

查了一下网上的情况,好像很多人都有过。问题都好像出现在gtk相关的界面问题上。

有两种修改方法

— 第一种 —
相应的配置修改配置文件 /workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.ddms.prefs

为如下内容:

ddms.logcat.auotmonitor.level=error
ddms.logcat.automonitor=false
ddms.logcat.automonitor.userprompt=true
eclipse.preferences.version=1
logcat.view.colsize.Application=200
logcat.view.colsize.Level=70
logcat.view.colsize.PID=50
logcat.view.colsize.TID=50
logcat.view.colsize.Tag=170
logcat.view.colsize.Text=300
logcat.view.colsize.Time=140

— 第二种 —
或者在执行eclipse之前,设置环境变量

export SWT_GTK3=0
eclipse

我采用了第二种方式,就可以正常显示了

2015-09-09 | | [linux总结], android, NDK

linux环境的中的eclipse里的logcat日志无法正常显示已关闭评论

沉默式-防火墙-软件(ARP)

现在在一些小型局域网里面,由于网络分配问题,导致网内进场出现一些攻击。

针对网络争夺,最简单的就是arp攻击。他的原理很简单,将目标机的arp缓存表中的网管mac地址,频繁刷新,并将其写成目标机的mac地址。这样在数据包在第二层打包时,就会将错误的mac写进去,这时数据包就会被转发到目标机上。而目标机具有一定的转发能力,并且还会动态控制报文速度,报文大小等等。这样就可以达到了,争夺网速的目的。

arp防火墙具有如下几个功能:

1,通过sniff识别。侦查攻击者,而这种侦查是不准确的,如果出现2个以上的攻击者,同时攻击者稍微有些技巧,就能让防火墙很难区分出是谁在攻击。

readmore

2011-01-16 | | [linux总结], *生活*, object, 思考

沉默式-防火墙-软件(ARP)已关闭评论

goto和setjmp,longjmp的理解

首先搞清楚goto的作用范围。

goto的作用范围仅仅在一个函数内,跨越函数是不行的。

setjmp和longjmp组成一个对。用来达成goto的作用,但作用域比较大。

setjmp有点像label。执行他之后,会在该代码段记录下指令地址。

longjmp和goto类似,用于跳转用。

2010-08-31 | | [linux总结], 思考

goto和setjmp,longjmp的理解已关闭评论

流量整形和数据包时间片的一些认识

为什么会在深更半夜来提及这个问题?

因为在校时的网络流量一直让我非常在意。学校的组网我并不了解,当时没有往网络方向靠拢,更就不太可能研究这些了。

记得当时学校的网络实际联网大概我还是偶然见过一次。在接入层,学校用了tplink的24/48口的便宜交换机。交换机的上行方向与一个快速的G级交换机连接,这样就完成了一个很小片区 的布局了。这个快速G级交换机又与一台汇聚层交换机连接。连接方式好像是光缆。条数不明,应该不会很多的。因为学校就屁大一点。

汇聚一类的交换机,学校好像也就有2台。这样就走到了一台路由那,这台路由估计应该用了核心层中最便宜的。因为汇聚层本来就是作为快速交换用的,只有核心层才是用来做路由协议的。

下面进入正题。

readmore

2010-08-22 | | [linux总结], object, 思考

流量整形和数据包时间片的一些认识已关闭评论

堆栈的几点理解

首先要明确,堆栈是2个东西,不是一个东西。

即堆和栈!

readmore

2009-09-11 | | [linux总结], now-way, object, Qt, 思考

堆栈的几点理解已关闭评论

重新理解text().asd()

首先理解这么一个玩意

class a

{

public:

int b()

{…..}

}

a c;

要访问b,可以这么访问c.b();

readmore

2009-09-10 | | [linux总结], *生活*, now-way, object, Qt, 思考

重新理解text().asd()已关闭评论

text().asd()用于还在寻找方法理解中…..

首先text().asd()这种用法是第一次见到。

问了网友,其实我也不太明白。说是text()是一个返回指向自己的函数,这一点理解起来的确比较困难,翻译成代码?

就是int text(){return &text;}吗?

readmore

2009-09-10 | | [linux总结], *生活*, now-way, Qt, 思考

text().asd()用于还在寻找方法理解中…..已关闭评论

Qt信号和槽细记

信号和槽。

信号类似于操作系统中的信号,它主要是在程序之间通讯或者线程之间通讯用的,也可以和系统通讯。说白了,就和操作系统的信号差不多,但实现方式可能有些不同。

槽是用于处理某个信号的实例,一般都是function。不知道class有没有。。。至少目前还没学到。

readmore

2009-09-08 | | [linux总结], *生活*, now-way, object, Qt, 思考

Qt信号和槽细记已关闭评论

ssh正式开始启用

我是一个死板的人,从来都不喜欢接受新事物。准确的说,应该是大学以来就这样了。相比之前这样的情况截然不存在。

不能说懒惰,小时候我很喜欢接受新事物的。对新事物都很好奇。

随着年龄和阅历的增加,对新事物的兴趣越来越少,甚至到冷漠的地步。其中除了不冲动思考以外,还有很多“老师”的影响。

readmore

2009-09-08 | | [linux总结], now-way, object, 思考

ssh正式开始启用已关闭评论