1) linux下printf会缓存
所以,你试试 sleep(1); printf("."); 很长时间也不会输出。还以为是sleep坏了, 添加一个printf("\n")或者fflush(stdout)可以解决。
2) bind到0.0.0.0, 对于新接入的网卡是可以收取到数据的
recv/recvfrom使用的socket句柄如果绑定的是0.0.0.0,那么对于所有的ip都是匹配的,所以说网卡的缓冲去的数据,只要是这个端口的,都可以取出来。另外新网卡插上以后,网卡驱动检查所有ip包,只要是发给自己的,都会放置到自己的缓冲区中。
3) sem_timedwait(arg1, arg2) 第一个参数是绝对时间,第二个时间是差值, 可能会sigsegv。
4) memalign(boudary, size), 第一个参数是对齐,恰恰和window实现的顺序相反。
5) 这段程序会SIGSEGV, 为什么,仔细看
#include <map>
#include <string>
#include <stdio.h>
int main(void)
{
std::map<std::string, int> testmap;
testmap["12.0.0.0 1234"] = 1;
testmap["12.0.0.1 1234"] = 1;
std::map<std::string, int>::iterator it = testmap.begin();
char szIp [100]; short sPort = 0; // short or int !?
sscanf(it->first.c_str(), "%s %d", szIp, &sPort);
++it;
}
6) 绝对时间的事件等待
错误的代码:
struct timespec abstime = {time(0) + (timeoutMills / 1000), (timeoutMills % 1000) * 1000000};
if (!sem_timedwait(pSem, &abstime))
return 0;
正确的代码:
struct timespec abstime; struct timeval tv;
gettimeofday(&tv, NULL);
abstime.tv_sec = tv.tv_sec + ((timeoutMills*1000 + tv.tv_usec)/1000000);
abstime.tv_nsec = ((timeoutMills*1000 + tv.tv_usec) % 1000000)*1000;
if (!sem_timedwait(pSem, &abstime))
return 0;
7)不存在,占个位置
8) 难道a-b > 0, 就可以得到a>b吗?
uint32 a = 1, b=2;
if ( a - b > 0 ) alert("a>b?");
if ( a > b ) alert("a>b!");
9) 单核处理器读写一个字长的对齐的内存是原子的
其他情况不是,小于一个字长,需要先读出一个字长,在写回一个字长。 多核处理器即使是对齐的字长区域也不是原子的,因为其他处理器可能使用自己的缓存,使用lock可以保证原子性。原子整数读写是操作系统所有同步和互斥机制的基础。
10) 有一个代码获取linux下从纪元开始的毫秒数
return (long)(now.tv_sec*1000 + now.tv_usec/1000);
正确的代码是
long ms = now.tv_sec;
ms *= 1000;
ms += now.tv_usec/1000;
return ms;
有什么差别看出来了吗?
11) 杀毒软件,360会干扰malloc的分配。
12) 64bit字面值
uint64 x = 0x9590BD2B6EF7FE8C; // warning. not long enough!
uint64 y = 0x9590BD2B6EF7FE8Cull;
13) 这样的编译问题:
“was created with an older compiler than other objects;” 请禁用连接时代码生成,否则cl生成的代码会被link程序修改。或者所有依赖的库全部统一参数重新编译, e.g. log4c。
14) NetMeter 永久试用方法1
原理关键在于注册表
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced项下面一个名为ShellExStateN的值,初次运行软件时就会将当前系统日期换算成秒写进这个键值,以后每次打开该软件,都会读取该值与当前时间比较,每隔两天提醒一次,跟上图一样,30天以后就彻底不能用了。
http://bbs.pediy.com/showthread.php?t=102531&viewgoodnees=1&prefixid=phpforce_20
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced项下面一个名为ShellExStateN的值,初次运行软件时就会将当前系统日期换算成秒写进这个键值,以后每次打开该软件,都会读取该值与当前时间比较,每隔两天提醒一次,跟上图一样,30天以后就彻底不能用了。
http://bbs.pediy.com/showthread.php?t=102531&viewgoodnees=1&prefixid=phpforce_20
15) win7 x64 使用rundll32.exe调试dll的时候失败,为什么呢?
请使用syswow64下面的rundll32.exe 来启动调试。
16) windbg 启动调试
cd /d %~dp0
set workpath=%cd%
"C:\Program Files (x86)\Debugging Tools for Windows (x86)\windbg.exe" -srcpath "%workpath%\..\src" -y "%workpath%" %SystemRoot%\system32\rundll32.exe "%workpath%\libdecklink.dll" StartPlayback
17) windows时间获取函数精度不够,无法达到毫秒级别。
#ifdef _WIN32
static uint64 getSysTime64once()
{
uint64 tmNow = 0;
struct _timeb timebuffer;
_ftime(&timebuffer);
tmNow = timebuffer.time;
tmNow *= 1000;
tmNow += timebuffer.millitm;
return tmNow;
}
static uint64 getSysTime64()
{
static uint64 initmsec = 0;
static LARGE_INTEGER freq;
static LARGE_INTEGER now;
if (initmsec == 0){
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&now);
initmsec = getSysTime64once();
return initmsec;
}else {
LARGE_INTEGER testtime;
QueryPerformanceCounter(&testtime);
return initmsec + static_cast<uint64>(1.0 * (testtime.QuadPart - now.QuadPart)/freq.QuadPart*1000);
}
}
#else
static uint64 getSysTime64()
{
uint64 tmNow = 0;
struct timeval tv;
gettimeofday(&tv, NULL);
tmNow = tv.tv_sec;
tmNow *= 1000;
tmNow += tv.tv_usec/1000;
return tmNow;
}
#endif
18) windows高频计数器api查询系统时间的错误
(1),在多核处理器上,结果不准,可以考虑每次调用前使用线程亲和api指定cpu核。
http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms686247(v=vs.85).aspx
static uint64 getSysTime64()
{
static DWORD dwProcNum = 0;
if (dwProcNum == 0){
SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo);
dwProcNum = sysInfo.dwNumberOfProcessors;
}
if (dwProcNum > 1){
SetThreadAffinityMask(GetCurrentThread(), 1);
}
//...
(2), 另外系统本地时间也是会漂移,不信的话,运行一个ntpd,然后对比上面的cpu计数得到的时间和ntp修正过的本地时间看看。
运行ntp以后,使用系统时间api就可以获取系统时间了。
uint64 tmNow = 0;
struct _timeb timebuffer;
_ftime(&timebuffer);
tmNow = timebuffer.time;
tmNow *= 1000;
tmNow += timebuffer.millitm;
return tmNow;
19) dumpbin /exports显示dll的导出函数名
如果当前dll目录下有pdb文件,dumpbin会读取并参考导出函数的内部名称。
20) window上的一个脚本,双击就是不执行,能气死司马懿
::test.exe –i %group% –d -f %card%
.\test.exe -i %group% -d -f %card%
用winhex一看,原来-d前面的那个-号是一个中文的减号,编码0xA843,而真正的英文的减号是0x2d。
一定要选择一个能够区分中文和英文输入法的编辑器来写脚本,我用的notepad++结果就是看不出来。
21) udp的系统收取速度和自己统计出来的速度相差很大。
在windows的资源管理的网络便签,以及linux的iftop -i eth0里面都可以看到
linux端的发送已经查过100M了,windows这里的接收也超过100M了,但是代码里面自己收取的字节数除总时间得到的带宽却只有half左右,
原来是系统的udp收取缓冲区太小了,linux默认大概是64K左右吧,windows估计也差不多吧,导致已经进入系统缓冲区udp包不停的被冲掉。
修改代码,设置缓冲区大小:
static int Tvup_SetSockSendBuf(int sockfd, uint32 bufsize)
{
int sendbuff = bufsize;
socklen_t optlen = sizeof(sendbuff);
return setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sendbuff, sizeof(sendbuff));
}
static int Tvup_SetSockRecvBuf(int sockfd, uint32 bufsize)
{
int recvbuff = bufsize;
socklen_t optlen = sizeof(recvbuff);
return setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&recvbuff, sizeof(recvbuff));
}
设置成2M基本够用了
Tvup_SetSockRecvBuf(m_nIncomingUdpSocket, SIZE_1M*2);
22) 创建一个可以被本机其他用户访问的的事件对象
HANDLE CreateRecordEvent(void){
#ifdef WIN32
// Initialize a security descriptor.
PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
return NULL;
}
// Add the ACL to the security descriptor.
if (!SetSecurityDescriptorDacl(pSD,
TRUE, // bDaclPresent flag
NULL, // All Access By EveryOne
FALSE)) // not a default DACL
{
return NULL;
}
SECURITY_ATTRIBUTES sa; memset(&sa, 0, sizeof sa);
sa.nLength = sizeof(sa); sa.bInheritHandle = false;
sa.lpSecurityDescriptor = pSD;
HANDLE hEvt = CreateEventA(&sa, FALSE, FALSE, "\\Global\\DeclinkRecordEvent");
return hEvt;
#endif
return NULL;
}
\Global\Something这样的命名方式,只是让其他进程(包括其他用户的进程)都可以看见,但是只有创建者本身创建的其他进程才可以在其他调用SetEvent等api对这个对象进行修改,其他用户创建的进程没有权限访问。如果希望其他用户可以访问,需要设置DACL,具体的访问控制列表。
23) gentoo 找不到网卡eth0
eth0的设备驱动已经加载,设备以及创建,但是就是找不到eth0,导致net.eth0无法初始化网络。
跟踪dmesg发现那个,udev会把eth0重命名。
从udev v197开始就有这个功能,参考这个:
但是这也有一些不方便。
解决办法,touch一个空的命名规则文件,
touch /etc/udev/rules.d/80-net-name-slot.rules
好了,熟悉的eth0又出现了。
24) windows蓝屏(BSOD, blue screen of death)的原因
1)、运行在内核模式下的设备驱动程序或者操作系统函数引发了一个未被处理的异常,比如内存访问违例(由于企图写一个只读页面或者企图读一个当前未被映射的内存地址(即无效地址)而引起)。
2)、调用一个内核支持例程导致了重新调度,比如当中断请求级别(IRQL)为DPC/Dispatch级别或更高级别时等待一个标记为需要等待的调度对象。
3)、在DPC/Dispatch级别或更高的IRQL级别时由于数据存在于页面文件或内存映射文件中而发生了页面错误(Page Fault)。(这将要求内存管理器必须等待一个I/O操作发生。但正如上面一项所说,在DPC/Dispatch级别或更高IRQL级别上不能够进行等待,因为那将要求一次重新调度)。
4)、当检测到一个内部状态表明数据已遭受破坏或者在保证数据不被破坏的情况下系统无法继续执行时,设备驱动程序或操作系统函数明确地要求系统崩溃(通过调用系统函数KeBugCheckEx)。
5、发生硬件错误,比如处理器的计算机检查异常功能(Machine Check)报告有异常或者发生不可屏蔽中断(NMI)。
25) netmeter v3.6 永久试用
C:\Users\Administrator>reg delete "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /f /v ShellExStateN
26)交叉编译的一些故事
./ide/bin/i686-w64-mingw32-gcc
调用
./ide/i686-w64-mingw32/bin/gcc
完成编译,用户不从从命令行执行后者,所以,一般都是把前者的路径添加的环境变量中。
交叉工具链的命名规则
$ ct-ng list-samples
Status Sample name
[G.X] alphaev56-unknown-linux-gnu
[G.X] alphaev67-unknown-linux-gnu
[G.X] arm-bare_newlib_cortex_m3_nommu-eabi
[G.X] arm-cortex_a15-linux-gnueabi
[G..] arm-cortex_a8-linux-gnueabi
[G..] arm-davinci-linux-gnueabi
[G..] armeb-unknown-eabi
[G.X] armeb-unknown-linux-gnueabi
[G.X] armeb-unknown-linux-uclibcgnueabi
[G..] arm-unknown-eabi
[G..] arm-unknown-linux-gnueabi
[G.X] arm-unknown-linux-uclibcgnueabi
[G.X] armv6-rpi-linux-gnueabi
[G.X] avr32-unknown-none
[G..] bfin-unknown-linux-uclibc
[G..] i586-geode-linux-uclibc
[G.X] i586-mingw32msvc,i686-none-linux-gnu
[G.X] i686-nptl-linux-gnu
[G.X] i686-unknown-mingw32
[G.X] m68k-unknown-elf
[G.X] m68k-unknown-uclinux-uclibc
[G.X] mips64el-n32-linux-uclibc
[G.X] mips64el-n64-linux-uclibc
[G.X] mips-ar2315-linux-gnu
[G..] mipsel-sde-elf
[G..] mipsel-unknown-linux-gnu
[G.X] mips-malta-linux-gnu
[G..] mips-unknown-elf
[G.X] mips-unknown-linux-uclibc
[G..] powerpc-405-linux-gnu
[G.X] powerpc64-unknown-linux-gnu
[G..] powerpc-860-linux-gnu
[G.X] powerpc-e300c3-linux-gnu
[G.X] powerpc-e500v2-linux-gnuspe
[G..] powerpc-unknown_nofpu-linux-gnu
[G..] powerpc-unknown-linux-gnu
[G..] powerpc-unknown-linux-uclibc
[G.X] s390-ibm-linux-gnu
[G.X] s390x-ibm-linux-gnu
[G..] sh4-unknown-linux-gnu
[G..] x86_64-unknown-linux-gnu
[G..] x86_64-unknown-linux-uclibc
[G.X] x86_64-unknown-mingw32
L (Local) : sample was found in current directory
G (Global) : sample was installed with crosstool-NG
X (EXPERIMENTAL): sample may use EXPERIMENTAL features
B (BROKEN) : sample is currently broken
http://www.crifan.com/files/doc/docbook/cross_compile/release/html/cross_compile.html
arch-vendor-kernel-system
27) Women Drivers( sorry, no gender-biase, it's theory about possibility)