开发随笔

一,最近在调试一个程序,发现一个死循环,不过怎么也看不出会死循环,代码如下:
        DWORD dwData;
        LPTSTR buffer = NULL;
        DWORD buffersize = 0;
        while (!SetupDiGetDeviceRegistryProperty ( hDevInfo, DeviceInfoData,  Property,  &dwData,                                                                                                                 (PBYTE)buffer, buffersize, &buffersize)
                   )
        {
            if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                    // Change the buffer size.
                    if (NULL != buffer)
                        ::LocalFree(buffer)
                    buffer = (LPTSTR)(::LocalAlloc(LPTR,buffersize));
            }
            else
                return E_FAIL;
        }
     这段代码从注册表中获取设备的相关属性,关键是SetupDiGetDeviceRegistryProperty 函数的最后一个参数并未     如它的文档所言(返回以“字节”为单位的尺寸),而是返回以“字符”为单位,当相关属性值为中文时,这段代码        会陷入死循环,后来我将buffersize加大了一倍,就可以了。

二,搭建基于phpeclipse开发环境时犯的错误:
    主要是参考这篇文章:Eclipse在PHP开发中的使用
    1,单击工具栏上的停启apache和mysql失败。
            解决方法:要先将apache和mysql注册成服务。
    2,PHP Browser不能正常工作,原来是配置apache出错,别名是用Alias而不是ScriptAlias(都是copy惹的祸)。
    3,最开始ctrl+空格可调出智能提示窗口,后来突然不管用了,原来要使用alt+/。

三,Linux下的用户权限问题:
 最近搭建了一个cvs服务器,在仓库的用户权限上吃足了苦头,使用的访问协议是ssh,希望只有cvs用户组成员和root用户才能访问仓库目录(其他用户无任何权限),仓库是初始化了,目录树的所属权和访问权限都设置好了,把我的个人用户帐号加入到cvs组中后,用wincvs登录成功,试了个项目动作正常,本以为万事大吉,但当加入第二个用户后,用wincvs访问仓库总是出现权限错误。原来,当我提交修改后,修改了的文件的所属权会变成我当前用户及我的缺省分组,问题就出在这个缺省分组上,我用adduser命令时一向不指定-g选项的,结果
用户的缺省分组名与用户名相同,这样改过文件别人都无法访问了,后来用usermod命令将所有cvs用户的缺省分组改成cvs后,就好了。

四,boost.regex中匹配中文正则表达式的一个错误:
     网上搜到了表达式:[/u4e00-/u9fa5],在vc2005下调了ok,但在其它编译器上调试后发现/u并非合法的转义用字符,估计表达式是用在其它语言里的,正确的应该是/x,表达式应该为:[/x4e00-/x9fa5]。

五,用ajax和setTimeout函数写一个动态刷新网页部分内容的javascript时,在Firefox下运行正常,但在IE下运行出现出错提示:对象不支持此属性或方法。
进入Microsoft Script Debugger后显示的详细错误信息如下:
A debugger break at "JScript - anonymous function" could not be handled because the source document could not be found.
出错的代码行:notify = document.getElementById("notify");
上面这一行代码是在XMLHttpRequest的回调函数中执行的,前一行代码更改了notify页面元素的内容。
经试验,发现将notify = document.getElementById("notify");放到回调函数之外,回调函数只使用notify变量就OK了。

六,在limodou的blog上看到的一则技巧:
执行一个reg文件,内容为:

    Windows Registry Editor Version 5.00

    [HKEY_CLASSES_ROOT/Directory/shell/cmd/command]
    @="cmd.exe /k /"cd %L/""

它的作用是在你的资源管理器上的右键菜单上增加一个菜单,名字为cmd。
那么以后你在目录栏中点击一个目录,然后点右键,再执行这个cmd菜单,就会直接进入这个目录的命令行。

七,页面完成后IE进度条仍在慢慢前进:
当执行某个脚本后会转到当前页面时该问题才会出现。利用排除法发现问题出在一个工具栏实现上,该工具栏上的按钮是用链接实现的,该链接的样式中用了背景图,鼠标放上去后(hover样式)用不同的背景图,该链接的代码如下:
<div class="toolbar">
  <ul>
    <li><a title="删除选中的所有记录" href="#" _fcksavedurl=""#"" _fcksavedurl=""#"" _fcksavedurl=""#"" _fcksavedurl=""#"" _fcksavedurl=""#"" onClick="execOperate('delete',); return false;">删除</a></li>
  </ul>
</div>
按此按钮后,会转到一个页面执行删除操作,从该页面执行完后会跳转到本页面。
似乎是因为IE在跳回本页面后对链接的背景图片的装入方面有点秀逗,因为鼠标放到链接上,IE进度条立刻正常了,链接不使用背景图也没这个问题,链接只使用 href或只使用onClick也没这个问题,不过href是少不了的,否则链接就生动不起来了,最后通过把链接改为:
        <a title="删除选中的所有记录" href="javascript:execOperate('delete',); ">删除</a>
问题似乎解决了,只是IE的这个迷团仍在。
当一个按钮是隐藏的且按钮的样式中有背景图时,也会出现该问题(隔一次出现一次),通过去除样式中的背景图可解决该问题。

八,信息号量使用不当导致死锁:
需要注意的是,信号量不像互斥体,一个线程两次占用信号量(第二次占用时,前一次占用并未释放)将导致线程最终占有了两个信号量。在程序中,共信号量的最大数是5个,代表了对数据库的5个连接,有多个线程(>5)要访问数据库,由于有的线程连续调用获取连接的接口(未释放先前获得的连接,会占用信号量),这样当有5个线程分别获取了一个连接,而为了完成工作又需要再获得一个连接(占用信号量),就会出现死锁。解决方法是调用代码注意尽早释放信号量,避免连续占用信号量,一个更好的办法或许是封装信号量的访问,让一个线程最多只能占用一个信号量。

九,vc6带的stl库的string类因为使用了引用计数导致在多线程应用中崩溃。
这是个老问题了,网上搜一下就一大把。
http://support.microsoft.com/kb/813810/zh-en
可以考虑使用stlport代替vc6的stl库,关闭vc6的stl库string中的引用计数,升级到更高版本的vc。

十,使程序在出现严重错误或异常时不弹出系统错误对话框
SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX);
参考:http://topic.csdn.net/t/20040913/23/3369198.html

十一,调用TerminateThread终止一个线程后,再调用GetExitCodeThread获取到的线程退出代码为什么不是TerminateThread中传入的值,而是STILL_ACTIVE?
因为TerminateThread函数是异步运行的函数。如果要确切地知道该线程已经终止运行,必须调用WaitForSingleObject或者类似的函数。

十二,bcc55中说找不到某个psdk中的库?
使用时我发现,代码或工程中不用指定psdk中的库,bcc55就工作正常了,但切换到其他编译器时又必需指定,
其实改变bcc55的配置就OK了,如下:
在bcc32.cfg中加入PSDK的路径:
-I"D:/Program Files/Borland/BCC55/include"
-L"D:/Program Files/Borland/BCC55/lib;D:/Program Files/Borland/BCC55/lib/PSDK"
在ilink32.cfg中加入PSDK的路径:
-L"D:/Program Files/Borland/BCC55/lib;D:/Program Files/Borland/BCC55/lib/PSDK"

十三,通过在源代码中设置将库链入工程
一直都是链入静态库,原来也可以链入动态库:
#pragma comment(lib,"psapi.lib")   //链入静态库
#pragma comment (linker,"defaultlib:psapi.dll") //链入动态库

十四,用ddk build驱动程序时现错误:error C2220: warning treated as error
原因在以下网页中有讨论:http://www.osronline.com/ShowThread.cfm?link=92376
不过解新决方案没有挑明,其实只要在MAKEFILE的语句!INCLUDE $(NTMAKEENV)/makefile.def之前放置以下语句就OK了:
BUILD_ALLOW_ALL_WARNINGS=1

十五,软件发行与升级
1,什么时候该以绿色软件方式发行?什么时候因该制作安装包?
当你发行的文件的数量大于1个的时候,或许你就该考虑做个安装包了(除非是这多个文件其实是可以单独运行或使用)。因为当你通过为用户提供压缩包进行升级时,会遇到意想不到的情况(比如:用户解压文件时不知道要解压到什么位置,用户会想解压到安装目录会不会把原有文件里的数据文件覆盖了?甚至用户可能把你的绿色软件目录拷贝了很多份,然后他会不知道要把下下来的文件替换哪个目录里的文件?)。
2,用户主动通过IE下载升级包还是程序中集成在线升级的功能?
我觉得应该是在程序中集成在线升级功能,首先这样对用户很方便,其次可以避免用户在下载过程中遇到很多问题(比如:他装了flashget,他未必会精于此道,特别是你使用固定的下载地址时,flashget之类的东西会说:该网址存在于正在下载表列中。鬼才知道还会遇到什么下载工具)。

十六,mysqldump输出的中文乱码
导出结果直接在控制台上输出可能是因为控制台使用的默认字符集不是中文的(先执行chcp 936改为中文),如果此时输出还是乱码,试试在导出命令中指定--default-character-set=<字符集>项,这个字符集应该是你创建数据库时指定的,我的是--default-character-set=latin1。
参考:http://smiling.iblog.com/post/10/320118

十七,emacs编辑c源文件时,显示的中文都是/0000之类的东西。
因为源代码里有繁体字,ntemacs默认设置了按GB2312显示,无法显示繁体字,结果也不按GB2312进行显示了。在源代码的第一行加上: //-*- coding: gbk -*-
现在行了。
参考:http://bbs.chinaunix.net/viewthread.php?action=printable&tid=546293

十八,遭遇宏定义冲突
书上常说,慎用宏,因为宏定义容易引起冲突,调试起来非常麻烦,这不终于让我遇到了:
系统头文件arpa/telnet.h中定义了#define IP  244     /* interrupt process--permanently */,然后项目的头文件里定义了int IP,结果编译出错(unnamed fields of type other than struct or union are not allowed
),动用GOOGLE甚至找出了是GCC3.1 的一个BUG,还好我用的是GCC3.2,否则估计现在本人正在升级GCC。现在只是在int IP之前来一句#undef IP,于是整个世界都清静了。

十九,用tar制作安装包的陷井
原来是用/bin/tar -rf app.tar /etc/init.d/app这种方式将一些启动脚本打包的,后来我觉得这样的话脚本不利于版本控制,于是建了个打包目录,里面的目录结构和要安装到的目标目录一样(里面也有etc/init.d目录用于放置脚本),这样所有东西都可以放到SVN中,而且调试安装包也一目录了然,制作安装包就很直观了:
将打包目录用svn export导到临时目录,将编译出的程序拷贝到临时目录的相应位置,用tar -zcvf 将临时目录打包成安装包。拿安装包到虚拟机中一测运行OK,但重启虚拟机后发现虚拟机的文件系统被损坏了,原因是linux中/etc/init.d是一个链接,而制作的安装包中是一个真正的目录,问题查出来了,更正就好办了,安装包中的目录改成/etc/init.d链接到的真正目录就行了。

二十,mysql命令行下导入.sql文件的两种方式
       1,mysql -uroot  <  file.sql
       2,mysql  -uroot  -e "source  d:/file.sql"

二十一,用snprintf累加字符串的不可移植性
这项工作通常是用strncat完成,不过用strncat的话还是要随时跟踪dest缓冲区的当前长度,或临时使用strlen求得,于是同事介绍了他常用的手法snprintf(dest, dest_buf_len, "%s%s", dest,  src),我一开始担心性能问题,不过他解释说看汇编知道会进行优化,不用担心。后来实际使用时发现,这是不可移植的,只是在vc上可以,在gcc和bcc55上测试时发现上面的snprintf(dest, dest_buf_len, "%s%s", dest,  src)===strncpy(dest,  src, dest_buf_len),这导致dest的原始值部分丢失。

二十二,./configure 脚本不断循环执行
是因为系统的时间设置不对,比源代码文件中的创建日期还要早,解决办法就是将系统日期改为当前日期。

二十三,windows下用sc命令创建服务总不成功
注意sc create  后的参数形式,sc create  binPath= c:/xxx.exe .......
其中,binPath=后是要接一个空格的,其它参数也类似。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值