<?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>i’m so full of ideas &#187; linux</title>
	<atom:link href="http://www.platinumball.net/blog/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.platinumball.net/blog</link>
	<description>blog</description>
	<lastBuildDate>Wed, 26 May 2010 17:16:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>printf() sucks</title>
		<link>http://www.platinumball.net/blog/2009/06/23/printf-sucks/</link>
		<comments>http://www.platinumball.net/blog/2009/06/23/printf-sucks/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 19:44:51 +0000</pubDate>
		<dc:creator>allen</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.platinumball.net/blog/?p=196</guid>
		<description><![CDATA[I am a big fan of printf()-style debugging.  It helps you get an overview of a problem that traditional debuggers are not so good at.  So it&#8217;s a bit unexpected that I do not like printf() itself.
Why printf() sucks
printf() is optimized for a weird corner case that you almost never need.  You&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>I am a big fan of printf()-style debugging.  It helps you get an overview of a problem that traditional debuggers are not so good at.  So it&#8217;s a bit unexpected that I do not like printf() itself.<br />
<h3>Why printf() sucks</h3>
<p>printf() is optimized for a weird corner case that you almost never need.  You&#8217;ll no doubt recognize this as standard usage:
<pre>  printf("Hello, World!\n")</pre>
<p>Notice that newline character at the end. It&#8217;s a pain to type. As best as I can tell, it exists so you can do this:
<pre>
<div class="codesnip-container" >
<div class="c codesnip" style="font-family:monospace;"><a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;Starting long-running operation ...&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">// long-running operation goes here</span>
<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot; finished.<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
</pre>
<p>&#8230; which causes the output from <i>both</i> printf() calls to be printed on the same line. Swell. How many times have you needed to do that? I first started programming in C in the late eighties, and my lifetime total so far is <i>zero</i>. I typed thousands of unnecessary newline characters before I finally wised up and wrote a replacement.<br />
<h3>Format strings are error-prone</h3>
<p>The most likely problem you&#8217;ll have with printf() and functions like it is a mismatch between the format string and the variables presented to it. For example:
<pre>  printf("Two strings: %s %s\n", "text");</pre>
<p>The format string calls for two strings to be printed, but you&#8217;ve only provided one. The call to printf() might work fine, crash, or print weird results, depending on what happens to be lying around on the stack. If your compiler is GCC &#8212; and it probably is, if you&#8217;re programming for any UNIX variant, including Mac OS X &#8212; there is a good workaround. Here&#8217;s my definition for echo(), my printf() replacement:
<pre>  void echo(const char* tfmt, ...) __attribute__((format(printf, 1, 2)));</pre>
<p>That weird <tt>__attribute__</tt> business is a GCC-ism that means &#8220;this function works like printf(), and here&#8217;s the argument numbers to use for the format string and the variable args, respectively.&#8221;</p>
<p>This feature doesn&#8217;t work unless you specifically enable the proper GCC warning.  If you&#8217;re using makefiles or the command line, pass <tt>-Wformat</tt> to the compiler. If you&#8217;re using Xcode, bring up the project information window. In the &#8220;Build&#8221; tab, there&#8217;s a section called &#8220;GCC 4.0 &#8211; Warnings.&#8221; The warning you want is labeled &#8220;Typecheck Calls to printf/scanf,&#8221; which should be enabled. Once you do that, then when you write code like this:
<pre>  echo("bad format: %s %s", "text");</pre>
<p>The compiler will give you this warning:
<pre>  warning: too few arguments for format</pre>
<p>&#8230; which saves you from the undefined behavior your program was about to be subjected to.</p>
<p>(C++ introduced <tt>cout</tt>, which is a printf() replacement. It handily works around the format string issue discussed here. I&#8217;ve always felt that <tt>cout</tt> introduces more problems than it solves, so I personally avoid it.)<br />
<h3>Functions you can use</h3>
<p>The sample code that follows includes three functions you might want to use in your own programs.</p>
<p><b><tt>echo()</tt></b> &#8212; works exactly the same as printf(), except it doesn&#8217;t require a newline at the end of its format string.</p>
<p><b><tt>sfmt()</tt></b> &#8212; works exactly the same as echo(), except it puts the formatted contents into a std::string object, rather than printing to stdout.</p>
<p><b><tt>fmtArg()</tt></b> &#8212; useful if you want to build your own printf()-like function similar to echo() or sfmt(). Have a look at how echo() uses it, which should be enough for you to get started.<br />
<h3>Example code</h3>
<p>First the header file, printf_sucks.h:
<pre>
<div class="codesnip-container" >
<div class="cpp codesnip" style="font-family:monospace;"><span class="co1">// printf_sucks.h -- printf() alternative</span>
<span class="co1">// by allen brunson &nbsp;june 18 2009</span>

<span class="co2">#ifndef PRINTF_SUCKS_H</span>
<span class="co2">#define PRINTF_SUCKS_H</span>

<span class="co1">// sfmt() and support functions</span>

std<span class="sy4">::</span><span class="me2">string</span> fmtArg<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> tfmt, <span class="kw4">va_list</span> args<span class="br0">&#41;</span><span class="sy4">;</span>
std<span class="sy4">::</span><span class="me2">string</span> fmtArgLarge<span class="br0">&#40;</span>int32_t byteCount, <span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> tfmt, <span class="kw4">va_list</span> args<span class="br0">&#41;</span><span class="sy4">;</span>
std<span class="sy4">::</span><span class="me2">string</span> sfmt<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> tfmt, ...<span class="br0">&#41;</span> __attribute__<span class="br0">&#40;</span><span class="br0">&#40;</span>format<span class="br0">&#40;</span><span class="kw3">printf</span>, 1, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co1">// echo(), a better printf()</span>

<span class="kw4">void</span> echo<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> tfmt, ...<span class="br0">&#41;</span> __attribute__<span class="br0">&#40;</span><span class="br0">&#40;</span>format<span class="br0">&#40;</span><span class="kw3">printf</span>, 1, 2<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>

<span class="co2">#endif &nbsp;// PRINTF_SUCKS_H</span></div>
</div>
</pre>
<p>Now the source file, printf_sucks.cpp:
<pre>
<div class="codesnip-container" >
<div class="cpp codesnip" style="font-family:monospace;"><span class="co1">// printf_sucks.cpp -- printf() alternative</span>
<span class="co1">// by allen brunson &nbsp;june 18 2009</span>

<span class="co2">#include &lt;assert.h&gt;</span>
<span class="co2">#include &lt;stdio.h&gt;</span>
<span class="co2">#include &lt;stdint.h&gt;</span>
<span class="co2">#include &lt;stdlib.h&gt;</span>
<span class="co2">#include &lt;string&gt;</span>
<span class="co2">#include &quot;printf_sucks.h&quot;</span>

<span class="kw4">void</span> echo<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> tfmt, ...<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">va_list</span> &nbsp; &nbsp; &nbsp;args <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; std<span class="sy4">::</span><span class="me2">string</span> &nbsp;text<span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw3">va_start</span><span class="br0">&#40;</span>args, tfmt<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; text <span class="sy1">=</span> fmtArg<span class="br0">&#40;</span>tfmt, args<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw3">va_end</span><span class="br0">&#40;</span>args<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw3">puts</span><span class="br0">&#40;</span>text.<span class="me1">c_str</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span>

std<span class="sy4">::</span><span class="me2">string</span> fmtArg<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> tfmt, <span class="kw4">va_list</span> args<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">static</span> <span class="kw4">const</span> int32_t &nbsp;kBufferSize <span class="sy1">=</span> 2 <span class="sy2">*</span> <span class="nu0">1024</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="co1">// the extra four bytes are to guard against buffer overruns</span>
&nbsp; &nbsp; <span class="kw4">char</span> &nbsp; &nbsp; cbuf<span class="br0">&#91;</span>kBufferSize <span class="sy2">+</span> 4<span class="br0">&#93;</span><span class="sy4">;</span>
&nbsp; &nbsp; int32_t &nbsp;size <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>

&nbsp; &nbsp; <span class="kw3">assert</span><span class="br0">&#40;</span>tfmt <span class="sy3">&amp;&amp;</span> tfmt<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>

&nbsp; &nbsp; size <span class="sy1">=</span> vsnprintf<span class="br0">&#40;</span>cbuf, kBufferSize, tfmt, args<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>size <span class="sy1">&lt;</span> kBufferSize<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> std<span class="sy4">::</span><span class="me2">string</span><span class="br0">&#40;</span>cbuf<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; <span class="kw1">else</span>
&nbsp; &nbsp; <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> fmtArgLarge<span class="br0">&#40;</span>size, tfmt, args<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="br0">&#125;</span>
<span class="br0">&#125;</span>

<span class="co1">// called when fmtArg() didn't have a big enough buffer</span>

std<span class="sy4">::</span><span class="me2">string</span> fmtArgLarge<span class="br0">&#40;</span>int32_t byteCount, <span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> tfmt, <span class="kw4">va_list</span> args<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">char</span><span class="sy2">*</span> &nbsp; &nbsp; &nbsp; &nbsp;cbuf <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; int32_t &nbsp; &nbsp; &nbsp;clen <span class="sy1">=</span> byteCount <span class="sy2">+</span> <span class="nu0">10</span><span class="sy4">;</span>
&nbsp; &nbsp; int32_t &nbsp; &nbsp; &nbsp;size <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
&nbsp; &nbsp; std<span class="sy4">::</span><span class="me2">string</span> &nbsp;text<span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; cbuf <span class="sy1">=</span> <span class="kw2">static_cast</span><span class="sy1">&lt;</span><span class="kw4">char</span><span class="sy2">*</span><span class="sy1">&gt;</span><span class="br0">&#40;</span><span class="kw3">malloc</span><span class="br0">&#40;</span>clen <span class="sy2">+</span> 4<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy3">!</span>cbuf<span class="br0">&#41;</span> <span class="kw1">return</span> <span class="st0">&quot;&quot;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; size <span class="sy1">=</span> vsnprintf<span class="br0">&#40;</span>cbuf, clen, tfmt, args<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw3">assert</span><span class="br0">&#40;</span>size <span class="sy1">&lt;</span> clen<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; text.<span class="me1">assign</span><span class="br0">&#40;</span>cbuf<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw3">free</span><span class="br0">&#40;</span>cbuf<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; cbuf <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">return</span> text<span class="sy4">;</span>
<span class="br0">&#125;</span>

<span class="kw4">int</span> main<span class="br0">&#40;</span><span class="kw4">int</span> argc, <span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">**</span> argv<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; echo<span class="br0">&#40;</span><span class="st0">&quot;hello from echo: %s %d&quot;</span>, <span class="st0">&quot;text&quot;</span>, 2<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span>
<span class="br0">&#125;</span>

<span class="co1">// works like echo(), but puts the formatted contents into a std::string</span>

std<span class="sy4">::</span><span class="me2">string</span> sfmt<span class="br0">&#40;</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> tfmt, ...<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">va_list</span> &nbsp; &nbsp; &nbsp;args <span class="sy1">=</span> <span class="kw2">NULL</span><span class="sy4">;</span>
&nbsp; &nbsp; std<span class="sy4">::</span><span class="me2">string</span> &nbsp;text<span class="sy4">;</span>

&nbsp; &nbsp; <span class="kw3">assert</span><span class="br0">&#40;</span>tfmt <span class="sy3">&amp;&amp;</span> tfmt<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy4">;</span>

&nbsp; &nbsp; <span class="kw3">va_start</span><span class="br0">&#40;</span>args, tfmt<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; text <span class="sy1">=</span> fmtArg<span class="br0">&#40;</span>tfmt, args<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw3">va_end</span><span class="br0">&#40;</span>args<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; 
&nbsp; &nbsp; <span class="kw1">return</span> text<span class="sy4">;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.platinumball.net/blog/2009/06/23/printf-sucks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux: app memory usage</title>
		<link>http://www.platinumball.net/blog/2009/05/10/linux-app-memory-usage/</link>
		<comments>http://www.platinumball.net/blog/2009/05/10/linux-app-memory-usage/#comments</comments>
		<pubDate>Sun, 10 May 2009 23:39:04 +0000</pubDate>
		<dc:creator>allen</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.platinumball.net/blog/?p=174</guid>
		<description><![CDATA[Once upon a time, I wrote a Linux app in C++ that used the database access libs from a well-known corporate database vendor. The app was very important to the employer I wrote it for. It had to run 24 hours a day, seven days a week. Unfortunately, the database access libs leaked like a [...]]]></description>
			<content:encoded><![CDATA[<p>Once upon a time, I wrote a Linux app in C++ that used the database access libs from a well-known corporate database vendor. The app was very important to the employer I wrote it for. It had to run 24 hours a day, seven days a week. Unfortunately, the database access libs leaked like a screen door on a submarine. I did not have the source code for them and the vendor was not responsive to my pleas.</p>
<p>So I set up the app so it could restart itself every few hours, in order to clear its leaks. The app ran inside a script, and when it exited with a certain return value, the script would know to restart it immediately. This worked pretty well for a couple of months. Then I discovered that certain usage patterns would cause the app to completely exhaust its heap in as little as 30 minutes. It crashed, taking a lot of important data down with it.</p>
<p>My next try was a tad more sophisticated. I figured out how to determine how much memory the app was using currently, and it would restart itself when its heap size had grown to about 1.5GB. Now it didn&#8217;t matter how long it took for the program to exhaust its heap, it would always restart itself long before that happened.</p>
<p>I had planned to show you source code for getting a Linux app&#8217;s resident set size. Seems like a good complement to my earlier blog entry which had code to do the same thing for Apple&#8217;s platforms. But it requires a <i>lot</i> of code, due to boring details like file access, string manipulation, and so on. So I&#8217;ll just describe the algorithm, and let you implement it yourself, if you&#8217;re interested.</p>
<p>Getting a program&#8217;s resident set size on Linux involves querying the <tt>/proc</tt> pseudo-filesystem. First you must create a pretend &#8220;filename&#8221; that looks like this:</p>
<p> &nbsp; &nbsp; <tt>/proc/(pid)/statm</tt></p>
<p>where <tt>(pid)</tt> is the pid of your program, which you can get with the posix function <tt>getpid()</tt>, converted to a textual representation. Open the &#8220;file&#8221; with whatever file manipulation APIs you normally use. <tt>fopen()</tt> is a good choice. Read the contents of the pseudo-file with <tt>fread()</tt>, then close it with <tt>fclose()</tt>. You should end up with a line of text that looks like this:</p>
<p> &nbsp; &nbsp; <tt>38546 48861 1677 104 0 36313 0</tt></p>
<p>This is a list of various memory statistics about your program. The only one we&#8217;re interested in is the second number, 48861 in this example. This is your app&#8217;s resident set size, in pages. I&#8217;d prefer to have that value in bytes, so you can multiply the number of pages by the memory page size, which you can retrieve by calling <tt>getpagesize()</tt>. That&#8217;s it, now you&#8217;ve got a more-or-less accurate count of the number of bytes your Linux program is currently using.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.platinumball.net/blog/2009/05/10/linux-app-memory-usage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
