<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-15963214</id><updated>2011-04-21T19:49:28.373-07:00</updated><category term='scheme'/><category term='openssl'/><category term='vim'/><category term='ptrace'/><category term='assembly'/><category term='Linux'/><category term='haskell'/><category term='programming'/><category term='life'/><title type='text'>royalfern</title><subtitle type='html'>When we write programs that "learn", it turns out we do and they don't.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15963214.post-1039996077067450831</id><published>2009-04-02T05:41:00.000-07:00</published><updated>2009-04-02T05:56:38.398-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Write Yourself a Scheme - 1</title><content type='html'>Here are the solutions to ``&lt;a href="http://halogen.note.amherst.edu/%7Ejdtang/scheme_in_48/tutorial/overview.html"&gt;Write Yourself a Scheme in 48 Hours&lt;/a&gt;'', "First steps: Compiling and running".&lt;br /&gt;&lt;br /&gt;ex1.&lt;br /&gt;main &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt; args &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;&amp;lt;-&lt;/b&gt;&lt;/span&gt; getArgs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;putStrLn (&lt;span style="color: rgb(255, 64, 255);"&gt;&lt;b&gt;"Hello, "&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;++&lt;/b&gt;&lt;/span&gt; args &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;!!&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 64, 255);"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;++&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 64, 255);"&gt;&lt;b&gt;", "&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;++&lt;/b&gt;&lt;/span&gt; args &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;!!&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 64, 255);"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;ex2.&lt;br /&gt;main &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt; line &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;&amp;lt;-&lt;/b&gt;&lt;/span&gt; getLine&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;putStrLn(&lt;span style="color: rgb(255, 64, 255);"&gt;&lt;b&gt;"Hello, "&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;++&lt;/b&gt;&lt;/span&gt; line)&lt;br /&gt;&lt;br /&gt;ex3.&lt;br /&gt;str2int s &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt; read s &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;::&lt;/b&gt;&lt;/span&gt; Int&lt;br /&gt;str2flt s &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt; read s &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;::&lt;/b&gt;&lt;/span&gt; Float&lt;br /&gt;&lt;br /&gt;main &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;=&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt; args &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;&amp;lt;-&lt;/b&gt;&lt;/span&gt; getArgs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;putStrLn (show (str2int(args &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;!!&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 64, 255);"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;) &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;+&lt;/b&gt;&lt;/span&gt; str2int(args &lt;span style="color: rgb(255, 255, 0);"&gt;&lt;b&gt;!!&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(255, 64, 255);"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)))&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-1039996077067450831?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/1039996077067450831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=1039996077067450831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1039996077067450831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1039996077067450831'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2009/04/write-yourself-scheme-1.html' title='Write Yourself a Scheme - 1'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-4208582690644129690</id><published>2009-03-30T19:53:00.000-07:00</published><updated>2009-03-30T19:55:17.550-07:00</updated><title type='text'>metaSendsEscape</title><content type='html'>Occasionally we can found that the Bash key-binding such as M-f/M-b will not work in XTerm (this happened both in my laptop and desktop), to solve this problem, just press `Control' and left mouse and check the item `Meta Sends Escape' from the main options.&lt;br /&gt;&lt;br /&gt;To turn it on permanently, add the following line to configure file '/etc/X11/app-defaults/XTerm':&lt;br /&gt;&lt;br /&gt;*metaSendsEscape: true&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-4208582690644129690?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/4208582690644129690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=4208582690644129690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/4208582690644129690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/4208582690644129690'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2009/03/metasendsescape.html' title='metaSendsEscape'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-6786416381115849577</id><published>2009-03-11T05:37:00.000-07:00</published><updated>2009-03-11T05:55:28.641-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>g_thread_init</title><content type='html'>This afternoon I spent almost two hours hunting a memory leak reported by &lt;span style="font-style: italic;"&gt;valgrind&lt;/span&gt;. It said that there are 2034 bytes definitely lost in &lt;span style="font-style: italic;"&gt;g_hash_table_new_full(), &lt;/span&gt;but I am pretty sure that &lt;span style="font-style: italic;"&gt;g_hash_table_destroy()&lt;/span&gt; is invoked with each key been passed to &lt;span style="font-style: italic;"&gt;g_free()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The fix turned out to be a slight modification of call sequence to &lt;span style="font-style: italic;"&gt;g_thread_init()&lt;/span&gt;, from:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;create hash table&lt;/li&gt;&lt;li&gt;add hash entry&lt;/li&gt;&lt;li&gt;g_thread_init()&lt;/li&gt;&lt;li&gt;reclaim hash table&lt;/li&gt;&lt;/ol&gt;to:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;g_thread_init()&lt;/li&gt;&lt;li&gt;create hash table&lt;/li&gt;&lt;li&gt;add hash entry&lt;/li&gt;&lt;li&gt;reclaim hash table&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;then, the error memory leak error just vanished.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-6786416381115849577?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/6786416381115849577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=6786416381115849577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/6786416381115849577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/6786416381115849577'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2009/03/gthreadinit.html' title='g_thread_init'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-2065675801363334910</id><published>2009-02-23T07:12:00.000-08:00</published><updated>2009-02-23T07:18:30.897-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>debug-set!</title><content type='html'>If you wrote a scheme procedure which will recursive too much and exhaust  all you stack, guile will print a horrible error message like below:&lt;br /&gt;&lt;pre&gt;ERROR: Stack overflow&lt;/pre&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;You might fix your algorithm and make the procedure tail-recursive to get rid of the compliant, or either, for debugging purpose, increase the stack size:&lt;br /&gt;&lt;pre&gt;(debug-set! stack 200000)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-2065675801363334910?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/2065675801363334910/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=2065675801363334910' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/2065675801363334910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/2065675801363334910'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2009/02/debug-set.html' title='debug-set!'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-1560670692196204074</id><published>2009-02-18T20:59:00.000-08:00</published><updated>2009-02-18T21:21:59.384-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openssl'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>reconnect</title><content type='html'>Several days ago there was a bug reported that our XML-RPC client over SSL will compliant that "&lt;span style="font-style: italic;"&gt;no data is available"&lt;/span&gt; when trying to read the HTTP header from the server.  Since it is a P2-critical bug, I spent a lot of time debugging it immediately.&lt;br /&gt;&lt;br /&gt;GDB shows me that "&lt;span style="font-style: italic;"&gt;BIO_read()&lt;/span&gt;" returned zero when reading the HTTP header, and its manual said that:&lt;br /&gt;       A 0 or -1 return is not necessarily an indication of an error. In par-&lt;br /&gt;       ticular when the source/sink is non-blocking or of a certain type it&lt;br /&gt;       may merely be an indication that no data is currently available and&lt;br /&gt;       that the application should retry the operation later.&lt;br /&gt;&lt;br /&gt;But finally I can see that when we switching to HTTP from HTTPS, the client works just fine.  And later, we are confirmed that the SSL handling in the server side has a race condition and the connection would be shutdown by then.&lt;br /&gt;&lt;br /&gt;In order to make the client more robust, I worked our a patch to do reconnection.  The result is rather exciting -- I did thousands of XML-RPC calls over a persistent connection, and everything works perfectly.&lt;br /&gt;&lt;br /&gt;At last, I am glad to share that, in section 6.3 of "UNIX Network Programming Volume 1", the author described the conditions that a descriptor being &lt;span style="font-style: italic;"&gt;select()&lt;/span&gt; is ready for read:&lt;br /&gt;&lt;p class="docList"&gt;&lt;span style="font-weight: bold;"&gt;b.&lt;/span&gt; &lt;span style="font-style: italic;"&gt;The read half of the connection is closed (i.e., a TCP  connection that has received a FIN). A read operation on the socket will not  block and will return 0 (i.e., EOF).&lt;/span&gt;&lt;/p&gt;Actually our underlying socket is handled by &lt;span style="font-style: italic;"&gt;select()&lt;/span&gt; , and I checked that &lt;span style="font-style: italic;"&gt;BIO_get_close()&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;really returns 1 when the connection is closed by the server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-1560670692196204074?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/1560670692196204074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=1560670692196204074' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1560670692196204074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1560670692196204074'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2009/02/reconnect.html' title='reconnect'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-2323336209485706964</id><published>2009-02-09T06:59:00.000-08:00</published><updated>2009-02-09T07:01:46.473-08:00</updated><title type='text'>1234567890</title><content type='html'>$ date -d @1234567890&lt;br /&gt;Sat Feb 14 07:31:30 CST 2009&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-2323336209485706964?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/2323336209485706964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=2323336209485706964' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/2323336209485706964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/2323336209485706964'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2009/02/1234567890.html' title='1234567890'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-8239973294312054702</id><published>2008-12-08T06:24:00.000-08:00</published><updated>2008-12-08T07:05:18.494-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>autoconf</title><content type='html'>I submitted another &lt;a href="http://zhost.zonio.net/pipermail/libxr/2008-December/thread.html"&gt;patch&lt;/a&gt; to &lt;a href="http://oss.zonio.net/libxr.htm"&gt;libxr&lt;/a&gt; mailing list just now, it is used to fix the small bug in `configure.ac', so that libxr will generate a correct `xr-config.h' when a JSON run-time is found.&lt;br /&gt;&lt;br /&gt;I started to contribute to libxr since last Dec., and I consider it my first &lt;span style="font-style: italic;"&gt;real&lt;/span&gt; participation in OSS development.  Yes I've previous experiences writting test suites for openhpi, openipmi and openwsman, during my internship.  But frankly speaking, I had few feelings of joy then.&lt;br /&gt;&lt;br /&gt;I enjoyed the discussion in E-mail, and  I'd like to thank the author of libxr, who gave me a lot of helps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-8239973294312054702?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/8239973294312054702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=8239973294312054702' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/8239973294312054702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/8239973294312054702'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/12/autoconf.html' title='autoconf'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-7890641876033113139</id><published>2008-12-04T08:06:00.000-08:00</published><updated>2008-12-04T08:16:28.746-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openssl'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>timeout</title><content type='html'>Eventually I managed to add a timeout value in the server side code so that an idle connection will be shutdown [&lt;a href="http://zhost.zonio.net/pipermail/libxr/2008-December/000007.html"&gt;patch&lt;/a&gt;] within a given time.  The patch is much simpler than what's expected, and at the same time, I realized that I did NOT turn libxr back to non-blocking I/O, but non-buffering I/O.&lt;br /&gt;&lt;br /&gt;I solved another problem which blocked our development this afternoon.  It turned out to be SSL re-handshake problem -- as I guessed.  Adding a Squid proxy between our client and server application is not that transparent as we thought, it will request the server program to do SSL re-handshake.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-7890641876033113139?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/7890641876033113139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=7890641876033113139' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/7890641876033113139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/7890641876033113139'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/12/timeout.html' title='timeout'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-1765168520838403242</id><published>2008-12-03T06:46:00.001-08:00</published><updated>2008-12-03T06:51:36.328-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openssl'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>First git branch</title><content type='html'>I just created my first &lt;a href="http://git.or.cz/"&gt;git&lt;/a&gt; branch of &lt;a href="http://oss.zonio.net/libxr.htm"&gt;libxr &lt;/a&gt;with the command line:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;# git checkout -b non-blocking&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;# git commit -a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Of course, the first commit is a patch which turns libxr back to non-blocking I/O. The next step is to setup the time out value of waiting incoming HTTP header.&lt;br /&gt;&lt;br /&gt;BTW, I am also planning to spare sometime writing a document about libxr, with &lt;a href="http://scripts.sil.org/xetex"&gt;XeTeX&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-1765168520838403242?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/1765168520838403242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=1765168520838403242' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1765168520838403242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1765168520838403242'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/12/first-git-branch.html' title='First git branch'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-4320892319926020972</id><published>2008-12-02T07:17:00.000-08:00</published><updated>2008-12-02T07:42:53.488-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='openssl'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>P1 bug</title><content type='html'>These days I've been occupied by a P1 bug and, unfortunately, the fix is far from ready.&lt;br /&gt;&lt;br /&gt;The XML-RPC library we use has a thread pool with each thread serves incoming request, and the thread will not be ripped back to the pool until the client shuts down the connection.  The &lt;span style="font-weight: bold;"&gt;problem&lt;/span&gt; is, when the number of established connection prevails the number of worker threads, the following connection will be blocked.&lt;br /&gt;&lt;br /&gt;Since the library uses buffered I/O thus blocking, the first step I &lt;span style="font-weight: bold;"&gt;need to take&lt;/span&gt; is to change it back to non-blocking I/O style -- If a connection has been idle for a while, we might have a chance to shut it down.&lt;br /&gt;&lt;br /&gt;My brain now is jammed with confusion and I felt quit dizzy, as many newbies who are trying openssl programming.  Just too many stuff!&lt;br /&gt;&lt;ol&gt;&lt;li&gt;buffered I/O&lt;/li&gt;&lt;li&gt;chained BIO&lt;br /&gt;&lt;/li&gt;&lt;li&gt;blocking I/O&lt;/li&gt;&lt;li&gt;non-blocking I/O&lt;/li&gt;&lt;li&gt;BIO with select()&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-4320892319926020972?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/4320892319926020972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=4320892319926020972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/4320892319926020972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/4320892319926020972'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/12/p1-bug.html' title='P1 bug'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-5549863107184683358</id><published>2008-06-03T19:42:00.000-07:00</published><updated>2008-06-03T19:43:54.839-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>sysnotes</title><content type='html'>一直在寻找一个免费托管的软件仓库，昨天下午闲来无事，搜到了&lt;a href="http://sharesource.org/"&gt;sharesource&lt;/a&gt;，可以提供svn/hg访问。于是注册了一个项目 - &lt;a href="http://sharesource.org/project/sysnotes/"&gt;sysnotes&lt;/a&gt;，用来放置我的LaTeX笔记。今天上午过来已经便收到确认通知邮件。:)&lt;br /&gt;&lt;br /&gt;$ hg clone http://hg.sharesource.org/sysnotes&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-5549863107184683358?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/5549863107184683358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=5549863107184683358' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/5549863107184683358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/5549863107184683358'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/06/sysnotes.html' title='sysnotes'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-8989649763207345962</id><published>2008-06-03T07:53:00.001-07:00</published><updated>2008-06-03T07:56:00.509-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ptrace'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>code injection</title><content type='html'>有很多文章关于代码注入，主要过程是用ptrace系统调用attach一个进程，注入代码(shellcode)，然后再detach该进程使得被注入 的代码得以执行。通常注入的代码被存放于堆栈中，因为它的大小可以动态调整，并且这些``蛛丝马迹''执行后可以被后续过程调用擦除。然而现代CPU（如 Intel IA32)都包含了NX位，即可修改内存不可执行(writable xor executable)，这使得大部分注入到stack中的shellcode都无法运行，从而提高了系统的安全性。&lt;br /&gt;&lt;br /&gt;有许多方法可以绕过该限制，比如： return to libc。作为代码注入的示例，我们可以直接将代码注入到EIP指向的内存区域：&lt;br /&gt;       if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {&lt;br /&gt;               perror("ptrace failed");&lt;br /&gt;               exit(-1);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       waitpid(pid, NULL, 0);&lt;br /&gt;       printf("[1] - Process attached\n");&lt;br /&gt;&lt;br /&gt;       if (ptrace(PTRACE_GETREGS, pid, NULL, &amp;amp;regs)!=-1) {&lt;br /&gt;               printf("[2] - Extract register eip (0x%.8x)\n", regs.eip);&lt;br /&gt;&lt;br /&gt;               for (i=0; i&lt;injected_len;&gt;                        ptrace(PTRACE_POKEDATA, pid, regs.eip+i, *(int*)(injected_code+i));&lt;br /&gt;               printf("[3] - Code inserted\n");&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       ptrace(PTRACE_DETACH, pid, NULL, NULL);&lt;br /&gt;       printf("[4] - Running Code\n");&lt;br /&gt;其 中injected_code即为shellcode首地址，一般以汇编语言书写，如上例as风格汇编代码（当然一般是exece("/bin/sh", ["/bin/sh", NULL], NULL）。由于被注入进程的文本段被修改，这样该进程的行为被修改，这并不是一个好主意。这里仅仅是代码注入的一个简单示例罢了。&lt;br /&gt;&lt;br /&gt;INJECTED_LEN是被注入代码的字节长度，可以由size命令获得。&lt;/injected_len;&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-8989649763207345962?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/8989649763207345962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=8989649763207345962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/8989649763207345962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/8989649763207345962'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/06/code-injection_03.html' title='code injection'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-3937730806303541740</id><published>2008-06-03T06:33:00.000-07:00</published><updated>2008-06-03T06:34:06.731-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='assembly'/><title type='text'>汇编语言的艺术</title><content type='html'>Linux下使用汇编语言 有很多选择：内联汇编，as或者nasm/yasm，下面是使用 as的例子：&lt;br /&gt;   .text&lt;br /&gt;.globl _start&lt;br /&gt;_start:&lt;br /&gt;        jmp get_string&lt;br /&gt;print_string:&lt;br /&gt;        movl $4, %eax   /* __NR_write */&lt;br /&gt;        movl $1, %ebx&lt;br /&gt;        popl %ecx&lt;br /&gt;        movl $6, %edx&lt;br /&gt;        int $0x80&lt;br /&gt;&lt;br /&gt;        movl %eax, %ebx&lt;br /&gt;        movl $1, %eax   /* __NR_exit */&lt;br /&gt;        int $0x80&lt;br /&gt;&lt;br /&gt;get_string:&lt;br /&gt;        call print_string&lt;br /&gt;        .string "hello\n"&lt;br /&gt;&lt;br /&gt;这 段汇编使用了传统的int $0x80系统调用，这里最重要的窍门是怎样获取字符串的首地址(call/popl)。这个小技巧使得生成的代码是位置无关的(PIC - Position Independent Code)。这在code injection中注入shellcode非常普遍。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-3937730806303541740?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/3937730806303541740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=3937730806303541740' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/3937730806303541740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/3937730806303541740'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/06/blog-post.html' title='汇编语言的艺术'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-3979042211552572867</id><published>2008-05-27T06:32:00.000-07:00</published><updated>2008-05-27T07:15:16.000-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Vim tips for SVN</title><content type='html'>&lt;span style="font-weight: bold;"&gt;function! SVN_diff()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    let fn = expand('%:p')&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    vnew +setl\ ft=diff\ bt=nowrite&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    exe ":.!svn diff -r BASE " . fn&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    unlet fn&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;endfunction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;map ,v :call SVN_diff()&lt;cr&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Paste above code in your &lt;span style="font-style: italic; font-weight: bold;"&gt;~/.vimrc&lt;/span&gt;, then you can use `&lt;span style="font-weight: bold;"&gt;,v&lt;/span&gt;' to display a diff in a vertical-split window.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-3979042211552572867?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/3979042211552572867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=3979042211552572867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/3979042211552572867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/3979042211552572867'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/05/vim-tips-for-svn.html' title='Vim tips for SVN'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-4814957018666677732</id><published>2008-03-31T22:56:00.000-07:00</published><updated>2008-03-31T22:57:58.790-07:00</updated><title type='text'>volatile</title><content type='html'>[Original: ]&lt;a href="http://www.airs.com/blog/archives/154"&gt; http://www.airs.com/blog/archives/154&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The volatile qualifier in C/C++ is widely misunderstood. Because it is described so vaguely in language standards, many people interpret it as a do-what-I-mean qualifier.&lt;div class="postentry"&gt;  &lt;p&gt;What the standard says is that accesses to volatile objects must be evaluated strictly according to the abstract machine defined by the language standard; this means that if the C/C++ code reads the volatile object twice, then the machine code must do so as wel. The standard says that volatile objects must be stable at sequence points; this means, approximately, that in between statements all reads and writes of volatile objects must have been completed–the value may not be cached in a register. The standard makes clear that it is possible that the values of volatile objects may change in some unknown way between accesses.&lt;/p&gt;  &lt;p&gt;One relatively unimportant misunderstanding is due to the fact that the standard only talks about accesses to volatile objects. It does not talk about accesses via volatile qualified pointers. Some programmers believe that using a pointer-to-volatile should be handled as though it pointed to a volatile object. That is not guaranteed by the standard and is therefore not portable. However, this is relatively unimportant because gcc does in fact treat a pointer-to-volatile as though it pointed to a volatile object.&lt;/p&gt;  &lt;p&gt;A way to think about volatile is to observe that it was invented to support memory mapped hardware. Some hardware is controlled by accesses to specific memory addresses. For example, a serial controller often handles input by setting a bit in one memory location and making the new byte available in another memory location. The kernel code must observe that the bit is set, read the byte, and set another bit to tell the serial controller that the byte has been read (I’m skipping the interrupt which is also involved). These accesses should use volatile to make sure that they happen in the exact order written in the program.&lt;/p&gt;  &lt;p&gt;The standard also explicitly describes two other uses of volatile. One is for setjmp and is relatively uninteresting. The other is that a variable of type &lt;code&gt;volatile sig_atomic_t&lt;/code&gt; may be set in a signal handler and read by code outside the signal handler. In fact, just about all that a portable signal handler may do is set such a variable.&lt;/p&gt;  &lt;p&gt;For dealing with memory mapped hardware, volatile is exactly what you want. For most other types of code, including multi-threaded code, volatile does not help.&lt;/p&gt;  &lt;p&gt;Using volatile does not mean that the variable is accessed atomically; no locks are used. Using volatile does not mean that other cores in a multi-core system will see the memory accesses; no cache flushes are used. While volatile writes are guaranteed to occur in the program order for the core which is executing them, there is no guarantee that any other core will see the writes in the same order. Using volatile does not imply any sort of memory barrier; the processor can and will rearrange volatile memory accesses (this will not happen for address ranges used for memory mapped hardware, but it will for ordinary memory).&lt;/p&gt;  &lt;p&gt;Conversely, if you use the locking primitives which are part of any threading library, then you do not need to use volatile. The locking primitives will include the required memory barriers or cache flushes. They will include whatever special directives are needed to tell the compiler that memory must be stable.&lt;/p&gt;  &lt;p&gt;There is one case where volatile may be used for multi-threaded programming with some reliability.  You may use a single &lt;code&gt;volatile sig_atomic_t&lt;/code&gt; variable to communicate between threads, much as you may use such a variable to communicate between a signal handler and the main program. You should not use more than one such variable to communicate between any pair of threads, as there is no guarantee that the different threads will see the accesses in the same order.&lt;/p&gt;  &lt;p&gt;In summary, if you are using volatile for anything other than manipulating memory mapped hardware, or for very limited communication between threads, it is very likely that you are making a mistake. Think carefully about what volatile means and about what it does not mean. &lt;/p&gt;       &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-4814957018666677732?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/4814957018666677732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=4814957018666677732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/4814957018666677732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/4814957018666677732'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/03/volatile.html' title='volatile'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-1261007141826166781</id><published>2008-03-28T08:33:00.000-07:00</published><updated>2008-03-28T08:43:52.423-07:00</updated><title type='text'>CJKbookmarks with dvipdfm</title><content type='html'>Today I eventually managed to create a PDF file with Chinese bookmark.&lt;br /&gt; Suppose the LaTeX source file is foo.tex:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Insert the following code into preamble section:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;\usepackage[CJKbookmarks,dvipdfm,bookmarksnumbered=true,%&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;colorlinks=true,linkbordercolor={1 1 1},%&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;linkcolor=blue,citecolor=blue,urlcolor=blue]{hyperref}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The following command line create the PDF file.&lt;/li&gt;&lt;ol&gt;&lt;li&gt;latex foo.tex&lt;/li&gt;&lt;li&gt;gbk2uni foo.out&lt;/li&gt;&lt;li&gt;latex foo.tex&lt;/li&gt;&lt;li&gt;dvipdfm foo.dvi&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;The &lt;span style="font-weight: bold;"&gt;linkbordercolor&lt;/span&gt; option will change the color of link border to white other than the default red color.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-1261007141826166781?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/1261007141826166781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=1261007141826166781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1261007141826166781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1261007141826166781'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/03/cjkbookmarks-with-dvipdfm.html' title='CJKbookmarks with dvipdfm'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-7784609161207127037</id><published>2008-03-27T06:36:00.000-07:00</published><updated>2008-03-27T06:42:17.884-07:00</updated><title type='text'>A couple of Bash tips</title><content type='html'>&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Single instance&lt;/span&gt;&lt;br /&gt;# make use of bash `set -C'&lt;br /&gt;(set -C; : &gt; $lockfile) 2&gt;/dev/null&lt;br /&gt;if [ $? -ne 0 ]; then&lt;br /&gt;   &amp;nbsp; log_msg "$0 already running, exit"&lt;br /&gt;   &amp;nbsp; exit 0&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Daemonize script&lt;/span&gt;&lt;br /&gt;# `-d' option indicates to daemonize&lt;br /&gt;if [ x"$1" = "x-d" ]; then&lt;br /&gt;   &amp;nbsp; $0 2&gt;&amp;amp;1 &gt;/dev/null &amp;amp;&lt;br /&gt;   &amp;nbsp; exit 0&lt;br /&gt;fi&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-7784609161207127037?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/7784609161207127037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=7784609161207127037' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/7784609161207127037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/7784609161207127037'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/03/couple-of-bash-tips.html' title='A couple of Bash tips'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-568887671627622105</id><published>2008-03-11T00:41:00.000-07:00</published><updated>2008-03-11T00:45:49.831-07:00</updated><title type='text'>First GDB Script</title><content type='html'>Here I added my first GDB macro functions in the file $HOME/.gdbinit to dump the content of task array.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;define tasks&lt;/li&gt;&lt;li&gt;x/210u *((unsigned int*) tobj+1)&lt;/li&gt;&lt;li&gt;end&lt;/li&gt;&lt;li&gt;document tasks&lt;/li&gt;&lt;li&gt;Display content of tasks.&lt;/li&gt;&lt;li&gt;end&lt;/li&gt;&lt;/ol&gt;The array is of 210 machine words long and it's easy to use awk to format the output neatly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-568887671627622105?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/568887671627622105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=568887671627622105' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/568887671627622105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/568887671627622105'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/03/first-gdb-script.html' title='First GDB Script'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-5239947513330124477</id><published>2008-03-07T23:46:00.000-08:00</published><updated>2008-03-07T23:50:42.437-08:00</updated><title type='text'>symbol-file</title><content type='html'>Although still I do NOT know now to extract a symbol file from&lt;br /&gt;unstripped binary executable, but seems I got a solution. -_-&lt;br /&gt;&lt;br /&gt;% echo "int main(void) {return 0; }" &gt; foo.c&lt;br /&gt;% gcc -ggdb foo.c -o foo.gdb&lt;br /&gt;% gcc -s foo.c -o foo&lt;br /&gt;% gdb -q foo&lt;br /&gt;(no debugging symbols found)&lt;br /&gt;Using host libthread_db library "/lib/libthread_db.so.1".&lt;br /&gt;(gdb) b main&lt;br /&gt;Function "main" not defined.&lt;br /&gt;Make breakpoint pending on future shared library load? (y or [n]) n&lt;br /&gt;(gdb) symbol-file foo.gdb&lt;br /&gt;Reading symbols from /home/david/foo.gdb...done.&lt;br /&gt;(gdb) b main&lt;br /&gt;Breakpoint 1 at 0x8048352: file foo.c, line 1.&lt;br /&gt;(gdb) l&lt;br /&gt;1       int main(void) {return 0; }&lt;br /&gt;(gdb)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-5239947513330124477?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/5239947513330124477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=5239947513330124477' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/5239947513330124477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/5239947513330124477'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/03/symbol-file.html' title='symbol-file'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-6554909574837656730</id><published>2008-03-06T07:56:00.000-08:00</published><updated>2008-03-06T08:01:05.040-08:00</updated><title type='text'>How to Generate Symbol file?</title><content type='html'>I wonder how to generate symbol file from binary executable under GNU/Linux?&lt;br /&gt;&lt;br /&gt;I googled a lot and tried the following but with no luck. x-(&lt;br /&gt;&lt;ol&gt;&lt;li&gt;nm -n&lt;/li&gt;&lt;li&gt;objdump -h -S&lt;/li&gt;&lt;li&gt;objdump -t&lt;/li&gt;&lt;/ol&gt;GDB 'symbol-file' always complaint:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;can't read symbols: File format not recognized.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-6554909574837656730?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/6554909574837656730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=6554909574837656730' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/6554909574837656730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/6554909574837656730'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2008/03/how-to-generate-symbol-file.html' title='How to Generate Symbol file?'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-9042520133648067376</id><published>2007-09-05T20:27:00.001-07:00</published><updated>2007-09-05T20:29:03.981-07:00</updated><title type='text'>Assertions</title><content type='html'>[&lt;span style="font-weight: bold;"&gt;From&lt;/span&gt;] http://xmlrpc-c.sourceforge.net/doc/libxmlrpc.html&lt;br /&gt;&lt;br /&gt;The concept of assertions in code is widely misunderstood, because it is somewhat more abstract than C coders are used to.  An assertion is a statement in code that declares a certain fact to be true.  It doesn't make it true; it just declares that the coder knows it is true.  In a standard C library, the &lt;b&gt;assert()&lt;/b&gt; function performs this duty.  &lt;p&gt;But what does the statement cause the computer to &lt;em&gt;do&lt;/em&gt;?  If you're a high level coder, that's none of your business.  You write code to describe the solution to a computational problem, and how the computer manipulates itself to compute the solution is beyond your concern.  Your audience is the human reading your code.  &lt;/p&gt;&lt;p&gt;So the most basic function of an assertion is to help the reader read the code.  You assert that the value of variable &lt;b&gt;foo&lt;/b&gt; is not zero, and that helps the reader see that it won't cause a problem to divide by it.  &lt;/p&gt;&lt;p&gt;Another practical effect of an assertion could be that the compiler generates more efficient code with the additional information from your higher intelligence about how the program works.  But I've never seen any actual compiler capable of that.  &lt;/p&gt;&lt;p&gt;An assertion might also help the compiler to point out bugs in your program.  You assert that the value of &lt;b&gt;foo&lt;/b&gt; is zero, but you never initialized &lt;b&gt;foo&lt;/b&gt;, so you obviously didn't write the program you thought you did.  But I've never seen a compiler with that capability either.  &lt;/p&gt;&lt;p&gt;Finally, there is run time checking of the assertion.  This one is real.  At run time, the program checks that the condition asserted really is true.  If it isn't, which means the program is broken, it crashes itself.  The advantages of this are twofold: 1) this makes it easier to diagnose the bug; 2) it stops the broken program from going on to damage something.  &lt;/p&gt;&lt;p&gt;People often have trouble seeing the abstract meaning of an assertion and simply see it as a statement that tells the computer, "crash if X is not true." But in fact, it's quite the opposite: It says, "I assure you X &lt;em&gt;is&lt;/em&gt; true."  &lt;/p&gt;&lt;p&gt;People sometimes get the idea that assertion statements are for error checking.  That is definitely not what they are for.  If there is a possibility that X is false when the program is working as designed, you should not assert that X is true.  Instead, check the truth of X and if it's false, issue an error message or exit the program or return with a failure return code, or something like that.  &lt;/p&gt;&lt;p&gt;Incidentally, a common way you know something is true inside a subroutine is that you required as an entry condition to the subroutine that the caller make sure it is true.  A subroutine assumes that it's entry conditions are met, so if you set up the requirement that the caller pass only positive values for parameter X, you may legitimately assert inside the subroutine that X is positive.  In fact, that assertion is a good formal way to state that entry condition for the reader of the code.  &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-9042520133648067376?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/9042520133648067376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=9042520133648067376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/9042520133648067376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/9042520133648067376'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2007/09/assertions.html' title='Assertions'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-8696170950211913987</id><published>2007-05-24T22:20:00.000-07:00</published><updated>2007-05-24T22:51:41.860-07:00</updated><title type='text'>High-order Procedures</title><content type='html'>Most modern programming languages provide certain abilities to blur the traditional distinction between ``passive'' data and ``active'' process, one of the most well-known techniques might be so-called OOD, i.e., Object Oriented Design.  Languages such as Lisp in traditional way provide programmers the power to handle precedures as data, which pioneered a new programming flavor called Functional Programming, or, FP in short (Now some FP languages also implemented OO facilities).  Procedures that manipulate procedures are called higher-order procedures.&lt;br /&gt;&lt;br /&gt;Put aside the consideration of efficiency, we can implement some atomic operations such as &lt;span style="font-style: italic;"&gt;cons&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;car&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;cdr&lt;/span&gt; like following:&lt;br /&gt;&lt;br /&gt;(define (cons x y)&lt;br /&gt;&amp;nbsp;&amp;nbsp;(lambda (f) (f x y)))&lt;br /&gt;&lt;br /&gt;(define (car z)&lt;br /&gt;&amp;nbsp;&amp;nbsp;(z (lambda (p q) p)))&lt;br /&gt;&lt;br /&gt;(define (cdr z)&lt;br /&gt;&amp;nbsp;&amp;nbsp;(z (lambda (p q) q)))&lt;br /&gt;&lt;br /&gt;Here, &lt;span style="font-style: italic;"&gt;cons&lt;/span&gt; just returns a procedure which takes &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;y&lt;/span&gt; as parameters.  &lt;span style="font-style: italic;"&gt;car&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;cdr&lt;/span&gt; applies the procedure constructed above with parameter (a procedure) which returns the former and latter parameter, respectively.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-8696170950211913987?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/8696170950211913987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=8696170950211913987' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/8696170950211913987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/8696170950211913987'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2007/05/high-order-procedures.html' title='High-order Procedures'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-8389913084211995903</id><published>2007-05-14T09:10:00.000-07:00</published><updated>2007-05-14T09:35:17.493-07:00</updated><title type='text'>Generator</title><content type='html'>Languages like Python, Ruby provide a keyword `yield' to help build a generator. It's really convenient for programmers who hate C-style static local variables, which indicates not thread-safe. For example:&lt;br /&gt;&lt;br /&gt;def sequence(start):&lt;br /&gt;&amp;nbsp;&amp;nbsp;current = start&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while True:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield current&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;current = current + 1&lt;br /&gt;&lt;br /&gt;#Create a new sequence generator starting at 1&lt;br /&gt;generator_func = sequence(1)&lt;br /&gt;print generator_func.next()   #prints 1&lt;br /&gt;print generator_func.next()   #prints 2&lt;br /&gt;print generator_func.next()   #prints 3&lt;br /&gt;&lt;br /&gt;Languages support functional programming needn't craft a `yield' keyword (most of them support another more general mechanism named `continuation'). We can easily build a generator like above use Scheme:&lt;br /&gt;&lt;br /&gt;; helper procedure to construct a simple generator&lt;br /&gt;(define (make-iter start step)&lt;br /&gt;&amp;nbsp;&amp;nbsp;(lambda ()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(let ((old start))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(begin (set! start (+ start step))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;old))))&lt;br /&gt;&lt;br /&gt;; a generator which starts from 1 and steps 1 on each accumulation&lt;br /&gt;(define sequence (make-iter 1 1))&lt;br /&gt;&lt;br /&gt;(sequence) ; evaluates 1&lt;br /&gt;(sequence) ; evaluates 2&lt;br /&gt;(sequence) ; evaluates 3&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-8389913084211995903?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/8389913084211995903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=8389913084211995903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/8389913084211995903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/8389913084211995903'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2007/05/generator.html' title='Generator'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-925081559567260631</id><published>2007-05-13T22:07:00.000-07:00</published><updated>2007-05-13T23:31:50.376-07:00</updated><title type='text'>Fast Exponential</title><content type='html'>Generally, we can compute exponentials in a linear-recursive way.&lt;br /&gt;For example:  exp(b, n) = b * b * ...  * b       which requires n steps.&lt;br /&gt;&lt;br /&gt;But there is a faster approach which makes use of successive squaring, for instance,  to compute exp(b, 8):&lt;br /&gt;b^2 = b * b&lt;br /&gt;b^4 = b^2 * b^2&lt;br /&gt;b^8 = b^4 * b^4&lt;br /&gt;&lt;br /&gt;This method needs only 3 steps instead of 8, and works fine or exponents that are powers of 2. Of course we can expand this to general usage with the help of the following rules:&lt;br /&gt;b^n = (b^(n/2))^2        if n is even;&lt;br /&gt;b^n = b* (b^(n-1))        if n is odd.&lt;br /&gt;&lt;br /&gt;So, we can compute exp(b, n) with time complexity costs O(logn) rather than O(n).&lt;br /&gt;&lt;br /&gt;Inspired by this method, you can even find a cleverer algorithm to compute the Fibonacci numbers in a logarithmic number of steps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-925081559567260631?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/925081559567260631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=925081559567260631' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/925081559567260631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/925081559567260631'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2007/05/fast-exponential.html' title='Fast Exponential'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-5776029280842330335</id><published>2007-05-09T00:38:00.001-07:00</published><updated>2007-05-13T23:36:30.765-07:00</updated><title type='text'>Some Lessons</title><content type='html'>There are some important ideas in algorithm and program design:&lt;ol&gt;&lt;li&gt;There is more than one way to do it.&lt;br /&gt;Your first task is to find a correct algorithm. After that, strive for clarity,simplicity, efficiency, scalability and elegance. Good algorithms and programs are like poems of logic. They are a pleasure to read and maintain.&lt;/li&gt;&lt;li&gt;Be the computer.&lt;br /&gt;Grand Master Turing once dreamed that he was a machine. When he awoke he exclaimed: "I dono't know whether I am Turing dreaming that I am a machine, or a machine dreaming that I am Turing!"&lt;/li&gt;&lt;li&gt;Generality is good.&lt;/li&gt;&lt;li&gt;Don't reinvent the wheel.&lt;br /&gt;As you are learning to program, designing from scratch is great experience. Truly expertprogrammers, however, know when to borrow.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;-- 7.5.5 Some Lessons&lt;br /&gt;&lt;br /&gt;Science is organized knowledge. Wisdom is organized life.&lt;br /&gt;-- Immanuel Kant&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-5776029280842330335?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/5776029280842330335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=5776029280842330335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/5776029280842330335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/5776029280842330335'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2007/05/some-lessons.html' title='Some Lessons'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-1137798314068037243</id><published>2007-05-04T20:09:00.000-07:00</published><updated>2007-05-04T20:25:37.886-07:00</updated><title type='text'>What is Computer Science?</title><content type='html'>You might be suprised to learn that computer science is not the study of computers. A famous computer scientist named Edsgar Dijkstra once quipped that computers are to computer science what telescopes are to astronomy. The  computer is an important tool in computer science, but is is not itself the object of study. Since a computer can carry out any process that we we describe, the real question is &lt;span style="font-style: italic;"&gt;What process can be describe&lt;/span&gt;? Put another way, the fundamental question of computer science is simply &lt;span style="font-style: italic;"&gt;What can be computed&lt;/span&gt;? Computer scientists use numerous techniques of investigation to answer this question. The three main ones are &lt;span style="font-style: italic;"&gt;design&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;analysis&lt;/span&gt;, and &lt;span style="font-style: italic;"&gt;experimentation&lt;/span&gt;.&lt;br /&gt;-- Python Programming: An Introduction to Computer Science,  section 1.3&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-1137798314068037243?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/1137798314068037243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=1137798314068037243' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1137798314068037243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/1137798314068037243'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2007/05/what-is-computer-science.html' title='What is Computer Science?'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-3075169652749671576</id><published>2007-04-24T22:06:00.001-07:00</published><updated>2007-04-24T22:25:17.322-07:00</updated><title type='text'>Function v.s. Procedure</title><content type='html'>The contrast between function and procedure is a reflection of the&lt;br&gt;general distinction between describing properties of things and&lt;br&gt;describing how to do things, or, as it is sometimes referred to, the&lt;br&gt;distinction between &lt;b&gt;declarative&lt;/b&gt; knowledge and &lt;b&gt;imperative&lt;/b&gt;&lt;br&gt;knowledge. In mathematics we are usually concerned with declarative&lt;br&gt;(what is) descriptions, whereas in computer science we are usually&lt;br&gt;concerned with imperative (how to) descriptions.&lt;p&gt;-- SICP, 1.1.7  Example: Square Roots by Newton's Method&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-3075169652749671576?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/3075169652749671576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=3075169652749671576' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/3075169652749671576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/3075169652749671576'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2007/04/function-vs-prodecure.html' title='Function v.s. Procedure'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-44147424248231226</id><published>2007-04-22T07:37:00.000-07:00</published><updated>2007-04-24T22:37:54.070-07:00</updated><title type='text'>SICPing again</title><content type='html'>We are about to study the idea of a &lt;a name="%_idx_8"&gt;&lt;/a&gt;&lt;a name="%_idx_10"&gt;&lt;/a&gt;&lt;em&gt;&lt;span style="font-weight: bold;"&gt;computational&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;process&lt;/span&gt;&lt;/em&gt;. Computational processes are abstract beings that inhabit computers. As they evolve, processes manipulate other abstract things called &lt;a style="font-weight: bold;" name="%_idx_12"&gt;&lt;/a&gt;&lt;em style="font-weight: bold;"&gt;data&lt;/em&gt;.  The evolution of a process is directed by a pattern of rules called a &lt;a name="%_idx_14"&gt;&lt;/a&gt;&lt;em style="font-weight: bold;"&gt;program&lt;/em&gt;.  People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells.&lt;br /&gt;&lt;div style="text-align: left;"&gt;-- SICP, Chaper 1, Building Abstractions with Procedures&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-44147424248231226?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/44147424248231226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=44147424248231226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/44147424248231226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/44147424248231226'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2007/04/sicping-again.html' title='SICPing again'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-116044922570941484</id><published>2006-10-09T19:38:00.000-07:00</published><updated>2007-04-22T09:48:32.474-07:00</updated><title type='text'>Goodbye</title><content type='html'>&lt;span style="font-family: lucida grande;font-family:lucida grande;" &gt;After 15 months spent at Shanghai, now I need go back to Chengdu to finish my M.S. degree, eventually.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;It's interesting that my last post was named "New Start". It is exactly another &lt;span style="font-style: italic;"&gt;new start&lt;/span&gt; for me tonight. I am thirsty for the experience of staying at the train, and enjoying the different scenery on the way, just like the way of our life with specific characters each period.&lt;br /&gt;&lt;br /&gt;Maybe most of the time we can not choose what to do following our inclinations. Now I must go without any alternative. Still there is a good side, I have a dream, that the next year I can meet again with my friends here.&lt;br /&gt;&lt;br /&gt;Two suggestions to myself before leaving Shanghai:&lt;br /&gt;o Keep doing sports;&lt;br /&gt;o Regularize work and rest;&lt;br /&gt;&lt;br /&gt;Goodbye, guys. See you again next year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-116044922570941484?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/116044922570941484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=116044922570941484' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/116044922570941484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/116044922570941484'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2006/10/goodbye.html' title='Goodbye'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15963214.post-112539357992146481</id><published>2005-08-30T02:18:00.000-07:00</published><updated>2005-08-30T02:19:39.923-07:00</updated><title type='text'>New Start</title><content type='html'>Throw out the old spymac blog, now using this new one. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15963214-112539357992146481?l=royalfern.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://royalfern.blogspot.com/feeds/112539357992146481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15963214&amp;postID=112539357992146481' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/112539357992146481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15963214/posts/default/112539357992146481'/><link rel='alternate' type='text/html' href='http://royalfern.blogspot.com/2005/08/new-start.html' title='New Start'/><author><name>David Lee</name><uri>http://www.blogger.com/profile/02766467275887156604</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp0.blogger.com/_4hX2h5QcBGY/R8o9R_CFRuI/AAAAAAAAACk/BPrUHA5nBAM/S220/lambda.png'/></author><thr:total>3</thr:total></entry></feed>
