<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kxn's eXercise Notes &#187; Coding</title>
	<atom:link href="http://blog.kangkang.org/index.php/archives/category/tech/code/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.kangkang.org</link>
	<description>Knowledge Sharing.</description>
	<lastBuildDate>Sat, 29 Oct 2011 14:43:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>测试一下coolcode</title>
		<link>http://blog.kangkang.org/index.php/archives/93</link>
		<comments>http://blog.kangkang.org/index.php/archives/93#comments</comments>
		<pubDate>Sun, 02 Apr 2006 03:31:34 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/index.php/archives/93</guid>
		<description><![CDATA[#include &#60;stdio.h&#62;&#160; int main(int argc, char*argv[])&#160; { &#160; &#160; printf(&#34;Hello World!\n&#34;); &#160; &#160; return&#160;0; ... ]]></description>
			<content:encoded><![CDATA[<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-prepro">#include </span><span style="color: #8b0000;">&lt;</span><span style="color: Red;">stdio.h</span><span style="color: #8b0000;">&gt;</span><span class="hl-prepro">&nbsp;</span></li>
<li><span class="hl-types">int</span><span style="color: Gray;"> </span><span style="color: Blue;">main</span><span style="color: Olive;">(</span><span class="hl-types">int</span><span style="color: Gray;"> </span><span style="color: Blue;">argc</span><span style="color: Gray;">, </span><span class="hl-types">char</span><span style="color: Gray;">*</span><span style="color: Blue;">argv</span><span style="color: Olive;">[])</span><span style="color: Gray;">&nbsp; </span></li>
<li><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">printf</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">Hello World!</span><span style="color: Navy;">\</span><span style="color: Red;">n</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Maroon;">0</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/93/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>不要使用 cp 替换正在使用中的Linux 动态库</title>
		<link>http://blog.kangkang.org/index.php/archives/49</link>
		<comments>http://blog.kangkang.org/index.php/archives/49#comments</comments>
		<pubDate>Wed, 21 Dec 2005 03:20:40 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/2005/12/21/49/</guid>
		<description><![CDATA[记得以前如果一个.so被 load 了，应该和程序本身一样，不能覆盖啊，强行覆盖也不会覆盖原来的inode，而是创建新的inode并替换当前目录里面的inode,　原来打开的文件还是正确的。 但是最近发现... ]]></description>
			<content:encoded><![CDATA[<p>记得以前如果一个.so被 load 了，应该和程序本身一样，不能覆盖啊，强行覆盖也不会覆盖原来的inode，而是创建新的inode并替换当前目录里面的inode,　原来打开的文件还是正确的。</p>
<p>但是最近发现在 Linux i386 上面 load .so 以后覆盖 .so ，没有任何提示，正在运行的程序退出时侯则通常都会 segfault. 　和 sparc 很像了。</p>
<p>难道我记错了吗？</p>
<p>用 strace 看了一下，cp 打开目标文件的时侯，都是在 open 加 O_WRONLY|O_TRUNC|O_LARGEFILE 参数，但是打开正在使用的程序时，就会返回 ETXTBSY, 动态库直接成功。</p>
<p>怀疑 ld-linux.so 在处理 .so 时侯是不是有什么问题，于是 strace 了一下动态库的 load 过程, 发现就是 open O_RDONLY 以后mmap 加 MAP_DENYWRITE 参数，但是 man  了一下 mmap, man page 说这个 MAP_DENYWRITE 参数现在已经被忽略了，原因是会造成 denial of service （我不是很明白这个为啥会造成 DoS），看起来就是这个原因了，mmap 这样并不能阻挡其他程序改写 .so 文件。</p>
<p>但是为啥主程序就可以呢？还是得看 kernel 代码。发现 kernel 内部在加载主程序的时侯，是用的 do_mmap 函数来 mmap 文件的(binfmt_elf.c)，参数也有 MAP_DENYWRITE，因为是 kernel 内部函数，所以这个 MAP_DENYWRITE 实际是有效的，在 do_mmap_pg_off 函数(mmap.c)里面也确实可以看到对 MAP_DENYWRITE 参数的处理。</p>
<p>结论就是，Linux ，至少是现在的 Linux 下面无法像 Windows 一样，保护正在使用的 .so 文件，因此开发过程中如果要更新代码，请不要使用 cp 这么粗暴原始的替换方式，还是用 install 来做吧</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/49/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>mod_extract_forwarded for lighttpd</title>
		<link>http://blog.kangkang.org/index.php/archives/44</link>
		<comments>http://blog.kangkang.org/index.php/archives/44#comments</comments>
		<pubDate>Mon, 19 Dec 2005 10:57:03 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/2005/12/19/44/</guid>
		<description><![CDATA[今天花了一点时间，用 lighttpd 的 mod_skeleton.c 划拉了一个 mod_extforward.c 出来，功能类似 Apache 上面的 mod_extract_forwarded.c ，都是用来从 X-Forwarded-For 里面截取出来对方真实 IP 用，特别适合在 squid ... ]]></description>
			<content:encoded><![CDATA[<p>今天花了一点时间，用 lighttpd 的 mod_skeleton.c 划拉了一个 mod_extforward.c 出来，功能类似 Apache 上面的 mod_extract_forwarded.c ，都是用来从 X-Forwarded-For 里面截取出来对方真实 IP 用，特别适合在 squid 后面的机器用，或者有人像我一样，爱好用 mod_proxy 穿来穿去的。不过这个 mod 功能弱很多就是了。</p>
<p>使用方法很简单 , 编译出来这个 module 并复制到 lighttpd 的 lib 目录里面。</p>
<p>在 lighttpd.conf&nbsp; 的 server.modules 里面加上 mod_extforward</p>
<p>配置类似下面这样</p>
<p>extforward.forwarder = (&quot;10.10.10.1&quot; =&gt; &quot;trust&quot; , &quot;192.168.1.2&quot; =&gt; &quot;trust&quot; )</p>
<p>会自动跳过所有 trusted IP . </p>
<p>另外 由于 lighttpd 本身 plugin 结构的局限，加载 mod_extforward 需要在所有模块之后，否则其他都可以正常工作，但是 access log&nbsp; 打出来的对方地址还是 proxy 的。此外还有局限就是，$HTTP[&quot;REMOTEIP&quot;] 的变量不会被 mod_extforward 影响，这个没有办法，对这个的判断先于所有的&nbsp; plugin 加载。</p>
<p>&nbsp;<a target="_self" href="http://kangkang.org/wordpress/uploads/mod_extforward.c" title="代码下载">下载地址</a> </p>
<p>  Update:  修正了和条件语句冲突的情况。 </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/44/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>用 swig 给脚本语言做 wrapper</title>
		<link>http://blog.kangkang.org/index.php/archives/35</link>
		<comments>http://blog.kangkang.org/index.php/archives/35#comments</comments>
		<pubDate>Mon, 12 Dec 2005 14:45:06 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/?p=35</guid>
		<description><![CDATA[　　工程里面有时候需要将某些C或者C++编写的模块封装成脚本语言的扩展，以便在脚本语言里面调用，这个工作通常很枯燥，会写出来很多重复代码，人一向都是会偷懒的动物，因此就诞生了... ]]></description>
			<content:encoded><![CDATA[<p>　　工程里面有时候需要将某些C或者C++编写的模块封装成脚本语言的扩展，以便在脚本语言里面调用，这个工作通常很枯燥，会写出来很多重复代码，人一向都是会偷懒的动物，因此就诞生了一些工具来帮助人们做这件事情，其中比较有名的就是 swig, 此外还有 boost::python 等，不过我觉得还是 swig 最好，因为他可以同时支持很多种脚本语言。<br />　　<a title="Simplified Wrapper and Interface Generator" target="_blank" href="http://www.swig.org/">SWIG</a> 是一种接口编译器，专门用来连接 C/C++ 程序和脚本语言的，它可以直接处理 C/C++ 头文件里面的声明，生成包装代码。和原有代码编译链接以后，生成多种脚本语言的扩展，可以加载进脚本语言解释器中使用。经过不少年的发展，他已经对C/C++语言支持得非常好了，甚至包括对模版的支持。swig 生成的代码基本都是可以直接用的，不需要再手动填空。他支持的脚本语言更是非常之多，还包括一些编译类型的伪码语言比如 Java。我的Fedora Core 4 系统带的 swig 1.3.24 支持这些脚本语言：ALLEGROL，CHICKEN，C#，GUILE，Java，Modula3，Mzscheme，Ocaml，Perl，PHP，Pike，Python，Ruby，Lisp，Tcl，XML(???这个怎么都有)。很多都没有听说过，不过常用的Perl/PHP/Python都是支持的。<br />　　swig 接受的输入是类似 C 的头文件一样的一种声明文件，支持很多以 % 开头的宏。同时他可以识别C/C++语言的声明，从而对应生成包装代码，常见的数据结构都可以建立对应关系，例如 int &lt;-&gt; int, char * &lt;=&gt; string 等等。下面是一个例子：</p>
<p>　　fileio.i<br />%module fileio<br />　　%{<br />　　/* 这里放的是后面声明所需要的其他 header ，以及一些私有声明之类，会被 swig 原封抄到生成的代码里面去*/<br />　　#include &lt;stdio.h&gt;<br />　　%}<br />　　/* 这后面写需要生成包装代码的方法和对象声明，这个例子是C的，因此只有简单的函数声明，虽然 stdio.h 里面声明了很多函数和数据类型，但是我们想要包装的只有 fopen 和 fclose 两个函数 */</p>
<p>　　FILE *fopen(const char *filename, char *mode);<br />　　int fclose(FILE *fp);<br />这就是一个简单的 swig 输入文件, %module 是给这个扩展起名字，将作为这个扩展在脚本语言中的名字，如果在python里面，使用时候就要import fileio。</p>
<p>　　用 swig 处理 fileio.i 会得到一个 .c 或者 .cxx 文件，取决于 swig 是否加了 -c++ 参数。如果用 c++ 方式处理，那么 swig 生成代码会有所不同，比如分配内存会用　new 来作，但总的来说，区别不大。</p>
<p>　　[root@kangkang.org ~] swig -python -o fileio_wrap.c fileio.i</p>
<p>　　然后<br />　　[root@kangkang.org ~] gcc -shared -o _fileio.so -I/usr/include/python2.4 fileio_wrap.c</p>
<p>　　本例里面因为我们没有任何现有代码，封装的是libc里面已经有的 fopen 和 fclose ，因此只要单独编译包装代码 fileio_wrap.c 就可以了，如果是封装已有工程的代码，就需要将已有工程代码一起编译链接成动态库。</p>
<p>　　在执行 swig 的时候，swig 除了生成 fileio_wrap.c 包装代码之外，还会负责生成脚本语言端需要的声明代码，本例中它会生成 fileio.py，负责声明和加载 _fileio.so ，在 python 运行环境里面，只要 import fileio ，就可以自动载入 _fileio.so 。然后就可以使用 fileio.fopen 和 fileio.fclose 了。</p>
<p>　　这只是一个简单的例子，实际 swig 的功能远比这个例子来得强大，需要进一步了解的，可以读他的<a title="SWIG-1.3 Development Documentation" target="_blank" href="http://www.swig.org/Doc1.3/Contents.html#Contents">说明文档</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/35/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解决 mysql 中文乱码问题</title>
		<link>http://blog.kangkang.org/index.php/archives/33</link>
		<comments>http://blog.kangkang.org/index.php/archives/33#comments</comments>
		<pubDate>Mon, 12 Dec 2005 05:31:57 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/?p=33</guid>
		<description><![CDATA[老问题了，有很多解决办法，不过最简单的还是 在 /etc/my.cnf 里面的client 段加上 init_connect=&#8221;set names &#8216;gbk&#8217;&#8221; 更具体的可以参考 http://ria.richtechmedia.com/?p=313 这个链接，说得蛮清楚... ]]></description>
			<content:encoded><![CDATA[<p>老问题了，有很多解决办法，不过最简单的还是</p>
<p>在 /etc/my.cnf 里面的client 段加上</p>
<p>init_connect=&#8221;set names &#8216;gbk&#8217;&#8221;</p>
<p>更具体的可以参考 <a href="http://ria.richtechmedia.com/?p=313">http://ria.richtechmedia.com/?p=313</a> 这个链接，说得蛮清楚的。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/33/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[历史备份]解决智能狂拼3输入i,u,v崩溃的bug</title>
		<link>http://blog.kangkang.org/index.php/archives/22</link>
		<comments>http://blog.kangkang.org/index.php/archives/22#comments</comments>
		<pubDate>Fri, 09 Dec 2005 14:09:38 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/2005/12/09/22/</guid>
		<description><![CDATA[这个已经做完好久了，现在贴出来作为历史备份吧。 智能狂拼 3 是一个很不错的输入法，虽然是一种整句输入法，单词输入能力一样很棒，响应速度比 MSPY2003 更是好了无数倍。官方出了一个 30... ]]></description>
			<content:encoded><![CDATA[<p>这个已经做完好久了，现在贴出来作为历史备份吧。</p>
<p>智能狂拼 3  是一个很不错的输入法，虽然是一种整句输入法，单词输入能力一样很棒，响应速度比 MSPY2003 更是好了无数倍。官方出了一个 30M 的版本可以免费使用，实在非常厚道。</p>
<p>但是他有一个很恶心的 bug,  就是在某些程序里面经常崩溃，fterm 之类挂接了默认 SEH 的还好，MSN 之类就是用着用着就没掉了，实在不能忍，等了好久也不见补丁出来，只好自己动手搞之</p>
<p>用 ollydbg 启动 fterm , 在 fterm 里面用狂拼输入几下，就崩溃了，ollydbg 报告写入到一个地址不行</p>
<blockquote><p>07CEB8AF   C603 00          MOV BYTE PTR DS:[EBX],0 </p></blockquote>
<p>在 07CEB8AF 地方说不能写入到 EBX 指向的地方, ollydbg 里面显示这个 EBX 指向的位置居然是Unicode的 Windows\WinSxs 字串。这个是怎么弄出来的呢？先看看怎么才能跑到这里吧。</p>
<p>用 IDA  反编译 CSMPYEng.DLL （崩溃时候ollydbg停在这个 dll 里面），找到对应代码, IDA 标明代码引用的功能实在很棒，一下就看出来代码可能的流程了，如下，最后一行就是崩溃代码：</p>
<blockquote><p>.text:1000B881 loc_1000B881:                           ; CODE XREF: sub_1000B7E0+7Dj<br />
.text:1000B881                 lea     eax, [esp+2Ch+var_10+1]<br />
.text:1000B885                 lea     ebx, [esp+2Ch+var_10+1]<br />
.text:1000B889                 push    eax<br />
.text:1000B88A                 call    sub_100177B7<br />
.text:1000B88F                 add     esp, 4<br />
.text:1000B892                 test    eax, eax<br />
.text:1000B894                 jnz     short loc_1000B8A4<br />
.text:1000B896<br />
.text:1000B896 loc_1000B896:                           ; CODE XREF: sub_1000B7E0+C2j<br />
.text:1000B896                 inc     ebx<br />
.text:1000B897                 push    ebx<br />
.text:1000B898                 call    sub_100177B7<br />
.text:1000B89D                 add     esp, 4<br />
.text:1000B8A0                 test    eax, eax<br />
.text:1000B8A2                 jz      short loc_1000B896<br />
.text:1000B8A4<br />
.text:1000B8A4 loc_1000B8A4:                           ; CODE XREF: sub_1000B7E0+B4j<br />
.text:1000B8A4                 mov     cl, [ebx]<br />
.text:1000B8A6                 lea     edx, [esp+2Ch+var_10]<br />
.text:1000B8AA                 push    edx<br />
.text:1000B8AB                 mov     byte ptr [esp+30h+arg_8], cl<br />
.text:1000B8AF                 mov     byte ptr [ebx], 0</p></blockquote>
<p>这段代码并不难读，很清楚的看到这是一个循环，ebx  是某 char 指针 p，循环里面调用 call    sub_100177B7 ，如果返回值是 0 , 则 p++ , 否则出来对 *p 进行一些操作。那么循环进入时候 p 是什么值呢？用 ollydbg 在 100b896 断点，随便按一个键让代码执行到断点，发现指向的就是我刚输入的字母。</p>
<p>现在问题就比较清楚了，多半是这个 sub_100177b7 在某些情况下面处理不正确，返回了0, 让 p++ 没完没了的跑下去，直到什么时候再次返回 1 , 这时候 p 都不知道跑到什么地方去了，这不崩就怪了。</p>
<p>之后的跟踪工作就不提了，总的来说很简单，发现问题在单独输入 i,u,v 的时候,　对于i/u/v字母之后的 null byte, 　该函数并没有判断，也返回 0, 导致指针越界很远。修正工作也比较简单，将 sub_100177b7 的入口 patch 跳转到别处，判断一下输入，如果是 null byte, 直接返回 1, 否则转原来入口。这个 dll 的函数是按照 16 字节对齐的，因此里面有很多空间可以塞二进制代码。。</p>
<p>这样智能狂拼3就可以正常使用了。</p>
<p>补记：我在水木上面发表这个补丁之后两天，官方就推出了修正补丁，真是 !@#$%^ 。不过也好，这里就不放修改之后的补丁文件了，需要的可以直接到官方网站上面去下载。</p>
<p>适中版本 <a href="http://www.tiansuo.com.cn/upload/kuangpin/CSMPYEng.zip">http://www.tiansuo.com.cn/upload/kuangpin/CSMPYEng.zip</a></p>
<p>专业版本 <a href="http://www.tiansuo.com.cn/upload/kuangpin/CSPPYEng.zip">http://www.tiansuo.com.cn/upload/kuangpin/CSPPYEng.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/22/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ACE 的土鳖 bug  不能设置线程栈大小</title>
		<link>http://blog.kangkang.org/index.php/archives/21</link>
		<comments>http://blog.kangkang.org/index.php/archives/21#comments</comments>
		<pubDate>Fri, 09 Dec 2005 13:28:23 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/2005/12/09/21/</guid>
		<description><![CDATA[　　发现用 ACE 写的多线程程序随便就占用了上百兆内存，查看 /proc/ /maps 发现有很多 10M 大的内存段，用 gdb attach 上去，p 一下 $esp 可以确定那些 10M 的内存段就是线程栈。这怎么可以，我用不... ]]></description>
			<content:encoded><![CDATA[<p>　　发现用 ACE 写的多线程程序随便就占用了上百兆内存，查看 /proc/
<pid>/maps 发现有很多 10M 大的内存段，用 gdb attach 上去，p 一下 $esp 可以确定那些 10M 的内存段就是线程栈。这怎么可以，我用不到这多堆栈的。于是按照 ACE 的文档设定了线程栈大小，结果发现还是没有效果 @_@</p>
<p>　　读了一下 ACE 的代码，发现原来是 ACE 的一个 bug,   ACE 里面创建线程最后是通过 ACE_OS::thr_create 函数来创建的，该函数里面关于 stack size 的处理代码如下：<br />
OS_NS_Thread.cpp:2288</p>
<blockquote><p>#   if defined (ACE_HAS_PTHREAD_SETSTACK)<br />
  if ((stacksize != 0) &#038;&#038; (stack != 0))<br />
#   else<br />
  if (stacksize != 0)<br />
#   endif /* ACE_HAS_PTHREAD_SETSTACK */<br />
    {<br />
      size_t size = stacksize;</p>
<p>#   if defined (PTHREAD_STACK_MIN)<br />
      if (size < ACE_static_cast (size_t, PTHREAD_STACK_MIN))<br />
        size = PTHREAD_STACK_MIN;<br />
#   endif /* PTHREAD_STACK_MIN */</p>
<p>#   if !defined (ACE_LACKS_THREAD_STACK_SIZE)      // JCEJ 12/17/96<br />
#     if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)<br />
      if (::pthread_attr_setstacksize (&#038;attr, size) != 0)<br />
#     else<br />
#       if defined (ACE_HAS_PTHREAD_SETSTACK)<br />
        if (ACE_ADAPT_RETVAL(pthread_attr_setstack (&#038;attr, stack, size), result) == -1)<br />
#       else<br />
        if (ACE_ADAPT_RETVAL(pthread_attr_setstacksize (&#038;attr, size), result) == -1)<br />
#       endif /* ACE_HAS_PTHREAD_SETSTACK */<br />
#     endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */<br />
          {<br />
#     if defined (ACE_HAS_PTHREADS_DRAFT4)<br />
            ::pthread_attr_delete (&#038;attr);<br />
#     else /* ACE_HAS_PTHREADS_DRAFT4 */<br />
            ::pthread_attr_destroy (&#038;attr);<br />
#     endif /* ACE_HAS_PTHREADS_DRAFT4 */<br />
            return -1;<br />
          }<br />
#   else<br />
      ACE_UNUSED_ARG (size);<br />
#   endif /* !ACE_LACKS_THREAD_STACK_SIZE */<br />
    }</p></blockquote>
<p>在 linux 下面编译时候，ACE_HAS_PTHREAD_SETSTACK　会被定义，于是设置线程栈参数会通过 ::pthread_attr_setstack 来设置，如果我并不想指定 stack 的地址，只设置默认 stack 的大小，ACE 代码也会通过 ::pthread_attr_setstack , 但是这个函数如果不指定 stack 地址的话，就忽略了 stacksize 。</p>
<p>最后用了比较垃圾的解决方案，在这段代码前面 #undef 掉 ACE_HAS_PTHREAD_SETSTACK　，这样设置就会通过 ::pthread_attr_setstacksize 来作，于是就有效了。。</p>
</pid>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/21/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TCP_DEFER_ACCEPT for Linux vs  accept filter for FreeBSD,  tux 还是玩不起来</title>
		<link>http://blog.kangkang.org/index.php/archives/20</link>
		<comments>http://blog.kangkang.org/index.php/archives/20#comments</comments>
		<pubDate>Fri, 09 Dec 2005 06:50:29 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/2005/12/09/20/</guid>
		<description><![CDATA[Linux 提供的一个特殊 setsockopt ,　在 accept 的 socket 上面，只有当实际收到了数据，才唤醒正在 accept 的进程，可以减少一些无聊的上下文切换。代码如下 val = 5; setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER... ]]></description>
			<content:encoded><![CDATA[<p>Linux 提供的一个特殊 setsockopt ,　在 accept 的 socket 上面，只有当实际收到了数据，才唤醒正在 accept 的进程，可以减少一些无聊的上下文切换。代码如下</p>
<blockquote><p>
  val = 5;<br />
     setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER_ACCEPT, &#038;val, sizeof(val)) ;</p></blockquote>
<p>里面  val 的单位是秒，</p>
<p><strong>注意如果打开这个功能，kernel  在 val 秒之内还没有收到数据，不会继续唤醒进程，而是直接丢弃连接。</strong></p>
<p>FreeBSD 有一个accept filter 的机制，不过看起来更牛一点,  可以注册自己的  handler 来处理连接。系统还提供了默认的 http filter, 接到完整的  http 请求了，再唤醒 accept 进程。</p>
<p>Linux 下面如果需要有东西可以内核态管理HTTP协议连接，那就是 tux 了。方汉是 tux 的爱好者。满街弄的都是 tux, 不过这个东西看起来非常需要人品，我跑了两次都造成了很多 oops 。还是算了。。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/20/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MSVCR80.DLL 里面的黑手&amp; fick Microsoft</title>
		<link>http://blog.kangkang.org/index.php/archives/18</link>
		<comments>http://blog.kangkang.org/index.php/archives/18#comments</comments>
		<pubDate>Tue, 06 Dec 2005 05:40:43 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/2005/12/06/18/</guid>
		<description><![CDATA[继续昨天关于 VC8 manifest 的话题 今天试验了一下果然不行。2000 之类不支持 winsxs 的系统都可以跑，xp 和 2k3 下面，都说没有正常设置，如果手动删掉 exe 里面的 manifest 的话，则是出个 assert, 说... ]]></description>
			<content:encoded><![CDATA[<p>继续昨天关于 VC8 manifest 的话题</p>
<p>今天试验了一下果然不行。2000 之类不支持 winsxs 的系统都可以跑，xp 和 2k3 下面，都说没有正常设置，如果手动删掉 exe 里面的 manifest 的话，则是出个 assert, 说用不正常的方式 load dll</p>
<p>google 了一下，找到了某德国牛人的文章</p>
<p>http://blog.kalmbachnet.de/</p>
<p>Using the VC 2005 shared CRT/MFC (DLL) without a manifest is not supported!<br />
If you build your app with VC2005 and you accidently have disabled the embedding of the manifest file (or deleted the separate appname.exe.manifest file), you will get an error on XP and later!</p>
<p>This has to do with the checking for a valid manifest of the EXE inside the CRT/MFC DLLs “DllEntry” (via a call to _check_manifest). If the OS supports manifests (or better Side-By-Side assemblies/DLLs) the CRTs´ DLL forces the check of the EXEs´ manifest. If there is no (valid) manifest, then the DLL refuses to load (returns 0) and therefor the EXE cannot be started. It might display the following error message (or similar):<br />
R6034<br />
An application has made an attempt to load the C runtime library incorrectly.<br />
Please contact the application’s support team for more information.</p>
<p>But in the following cases the manifest checking inside the CRT-DLL is not done:</p>
<p>Pre-fusion OS (FindActCtxSectionStringW not found in kernel32.dll)<br />
Loaded by instrumented-mscoree.dll (mscoree.dll and pgort80.dll is already loaded)<br />
The path returned with GetModuleFileNameW of the DLL is longer than 8000 characters<br />
The path to the DLL, returned by GetLongPathName is longer than 8000 characters </p>
<p>Microsoft 太变态了。faint, 于是按照该牛人的说法，注释掉 crt src 里面的 _check_manifest  调用， build 出来一个 msvcr80.dll , 和删掉 manifest 的 exe 配合使用就可以在任何系统上面使用了。 </p>
<p>再次 fick microsoft.  </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/18/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>从gcc静态链接开始的讨论，学了好几手</title>
		<link>http://blog.kangkang.org/index.php/archives/17</link>
		<comments>http://blog.kangkang.org/index.php/archives/17#comments</comments>
		<pubDate>Tue, 06 Dec 2005 03:01:59 +0000</pubDate>
		<dc:creator>kxn</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tech Notes]]></category>

		<guid isPermaLink="false">http://kangkang.org/wordpress/2005/12/06/17/</guid>
		<description><![CDATA[昨天夜里某bbs上进行了一场关于gcc链接库的讨论，结果最后转移到了 Windows 下面 VC8 msvcr80.dll 的话题。。 事情的起因是这样的： 我想对某程序静态链接 libstdc++ ，但是动态链接　libc, 　因为这... ]]></description>
			<content:encoded><![CDATA[<p>昨天夜里某bbs上进行了一场关于gcc链接库的讨论，结果最后转移到了 Windows 下面 VC8 msvcr80.dll 的话题。。</p>
<p>事情的起因是这样的：</p>
<p>我想对某程序静态链接 libstdc++ ，但是动态链接　libc, 　因为这个程序用到了 dlopen ,  而 dlopen 是无法静态链接的。于是我问如何在 configure.in 里面找到 libstdc++.a 的具体路径，好加在 LDADD 里面</p>
<p>首先是westline师弟给出的解决方案 gcc -print-file-name=libstdc++.a , man 了一下，原来 gcc 还提供了一坨类似的函数，用来把他知道的都告诉你。</p>
<p>接下来话题就变成了为啥需要静态链接 libstdc++ 了，我其实就是想避免 libstdc++.so.5 和 libstdc++.so.6 的问题<br />
但是这时侯伟大的 kirbyzhou 爷现身了　</p>
<blockquote><p>发信人: kirbyzhou (世界太小 梦想太大), 信区:<br />
标  题: Re: 问个土问题<br />
发信站:  (Mon Dec  5 23:36:11 2005), 转信</p>
<p>主要是c++需要知道class的实现细节内容，主要是指对象的大小。<br />
不然C++的.so接口定下来也不是什么难事。</p>
<p>【 在 COMMAN (　) 的大作中提到: 】<br />
: 【 在 Kittyboy (Oyahoe) 的大作中提到: 】<br />
: : &#8230;&#8230;<br />
: : configure的时候定位出libstdc++.a的路径应该是可以的，makefile里面有那个路径，<br />
就是configure出来那个gcc的lib吧。。<br />
: : 不过静态libstdc++并且动态libc这个要求也特别了一点。。<br />
: 这个是想尽量减少依赖性呀，FC2 上面是 libstdc++.so.5 , FC3 上面就是 libstdc++.s<br />
o.6 了，太变态了，libc 倒是从 redhat ?.? 的时候开始已经是 libc.so.6 了。RH 9 开<br />
始里面的名称也都是 GLIBC2.3 了</p></blockquote>
<p>接下来大家开始讨论 Windows 下面把　MSVCR71.DLL  的符号都给 forward 到 MSVCRT.DLL ，以减少程序依赖性的问题。</p>
<p>kirby 爷还是一如既往的拍砖。</p>
<blockquote><p>发信人: kirbyzhou (世界太小 梦想太大), 信区:<br />
标  题: Re: 问个土问题<br />
发信站:  (Tue Dec  6 00:11:24 2005), 转信</p>
<p>【 在 boost (我是一棵无聊) 的大作中提到: 】<br />
: 什么意思？缺的那些symbol？还是说名字一样过去也不去？<br />
1.缺symbol，比如一些检查stack的内部小函数。<br />
2.bootstrap不一样</p>
<p>: 【 在 COMMAN (　) 的大作中提到: 】<br />
: : 但是 MSVCRT.dll 基本可以肯定不能支持 MSVCR71 的那些函数吧。我严重怀疑 forwar<br />
d 过去了也是一调用就崩。</p></blockquote>
<blockquote><p>发信人: kirbyzhou (世界太小 梦想太大), 信区:<br />
标  题: Re: 问个土问题<br />
发信站:  (Tue Dec  6 00:35:30 2005), 转信</p>
<p>1.exception/type_info及其子类的size不兼容问题<br />
2.swprintf以及一系列和wchar_t*有关的东西<br />
3.__set_buffer_overrun_handler等一系列<br />
【 在 COMMAN (　) 的大作中提到: 】<br />
: admire 爷，看来您已经研究过缺 symbol 的函数名了，给个列表吧。<br />
: 【 在 kirbyzhou (世界太小 梦想太大) 的大作中提到: 】<br />
: : 1.缺symbol，比如一些检查stack的内部小函数。<br />
: : 2.bootstrap不一样</p></blockquote>
<p>然后下来开始关于 manifest 的讨论。起因是大家开始讨论 VC8 的 msvcr80.dll 的安装问题，kirby 说这个一定要带 manifest, 否则根本不能用。我觉得不是这样的，不过我还没有做试验证明</p>
<blockquote><p>发信人: COMMAN (　), 信区:<br />
标  题: Re: 问个土问题<br />
发信站:  (Tue Dec  6 00:41:47 2005), 转信</p>
<p>嗯，manifest 是表明了你这个 dll 在什么样的 context 下面 load<br />
然后 xp 支持一组 activatectx 之类函数，程序可以调用设定要用什么 context.<br />
如果非常懒，可以给程序也写一个 manifest, 这样 xp 的 loader 会帮你做这个事情<br />
两者加一起就可以自动动态挂接编译者想要的 dll 版本了。不会造成 dll 版本冲突。<br />
assembly 同理。</p>
<p>所以我总觉得这个不是必须的，如果没有大不了 fallback 到 system32 下面去 load 嘛</p>
<p>【 在 boost (我是一棵无聊) 的大作中提到: 】<br />
: 我土鳖地问一句，manifest是不是就是包了一个依赖的crt dll的assembly名字，<br />
: 用来在winsxs目录下找dll？<br />
: 【 在 COMMAN (　) 的大作中提到: 】<br />
: : 可能是，我刷个牙回来还没有拍出来，不过我还是觉得manifest 不是必须的，跟 wins<br />
xs 下面那些冲突就冲突了，基本造成问题的可能性微乎其微，只要 microsoft 这个 dll<br />
的向下兼容性还能够保持就行。</p>
</blockquote>
<p>本来话题发展到这里，已经跑题很远了，但是 zeel 爷出现了，并且给出了这个话题开始的最标准答案<br />
为这个讨论划上了完美的句号。</p>
<blockquote><p>发信人: zeel (我爱我老婆), 信区:<br />
标  题: Re: 问个土问题<br />
发信站:  (Tue Dec  6 00:25:03 2005), 转信</p>
<p>发信人: Valentin Nechayev <netch @segfault.kiev.ua>, 信区: Unix<br />
标  题: Re: Linking with different static and dynamic library<br />
发信站: Dark side of coredump (Tue Mar 11 20:15:23 2003)<br />
转信站: SMTH!maily.cic.tsinghua.edu.cn!news.happynet.org!news.cn99.com!newsfeed<br />
出  处: news.lucky.net</p>
<p>>>> Kenji Chan wrote:</p>
<p>KC> Here I&#8217;ve got a &#8220;program&#8221; which links to two library lib_a and lib_b<br />
KC> when I use &#8211;static for g++, it links all library statically<br />
KC> But how can I do this:<br />
KC> program &#8211;> statically         lib_a.a<br />
KC>        also &#8211;> dynamically    lib_b.so<br />
KC> What command should I type?</p>
<p>If your system uses GNU ld, you may try following:</p>
<p>gcc -o $prog $objs -Wl,-Bstatic -l_a -Wl,-Bdynamic -l_b -Wl,-Bdynamic</p>
<p>last -Wl,-Bdynamic is here to provide mode for system default libraries<br />
(libc, etc.)</p>
<p>(If linker isn&#8217;t GNU ld, find details in linker manuals.)</netch></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.kangkang.org/index.php/archives/17/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

