<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkENQ309cSp7ImA9WhdaEko.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156</id><updated>2011-10-22T03:04:52.369-05:00</updated><category term="env improvement" /><category term="shop" /><category term="home improvement" /><category term="climbing" /><category term="travel" /><category term="atomics" /><category term="code" /><category term="woodturning" /><category term="git" /><category term="osx" /><category term="MPI" /><title>Dave Goodell's Blog</title><subtitle type="html">Random notes to myself and others about technology and other stuff.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://davegoodell.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/davegoodellblog" /><feedburner:info uri="davegoodellblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DkYHQXw_cSp7ImA9WhZRGEk.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-6032861140310400661</id><published>2011-04-15T00:05:00.001-05:00</published><updated>2011-04-15T00:08:50.249-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-15T00:08:50.249-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>Debugging Wily Stack Overflows in MPI Programs</title><content type="html">I recently was debugging a problem in MPICH2 with the new MPI-3 nonblocking collectives implementation that involved a stack overflow. &amp;nbsp;The code in question was usually blowing up with a &lt;code&gt;SIGABRT&lt;/code&gt; that came from a stack trace ending in &lt;code&gt;__stack_chk_fail&lt;/code&gt;. &amp;nbsp;This bug was particularly nasty because it was a &lt;a href="http://en.wikipedia.org/wiki/Unusual_software_bug#Heisenbug"&gt;Heisenbug&lt;/a&gt;: it kept changing the failure location and mode whenever I would insert debugging code in order to track it down (hence the aforementioned "usually").&lt;br /&gt;
&lt;br /&gt;
For reasons I will explain later, &lt;a href="http://davegoodell.blogspot.com/2009/07/fstack-protector-valgrind-stack-array.html"&gt;my usual trick&lt;/a&gt; for this sort of thing did not help. &amp;nbsp;Adding in those macros would cause the bug to vanish, or to reappear in a different function that had not been instrumented with &lt;code&gt;MPIU_SG_&lt;/code&gt; macros.&lt;br /&gt;
&lt;br /&gt;
Luckily, I ran across &lt;a href="http://www.outflux.net/blog/archives/2007/09/15/catching-stack-overflows-in-gdb-as-they-happen/"&gt;this very helpful blog post&lt;/a&gt; that eventually helped me track down the real problem. &amp;nbsp;My basic approach was the same as the one outlined there, but it needed modification due to the pain inherent in debugging a parallel MPI application. &amp;nbsp;This particular bug required running at least 4 processes in order to manifest itself, and it would only appear after several iterations within the test program. &amp;nbsp;So I used &lt;code&gt;mpiexec&lt;/code&gt; + &lt;code&gt;xterm&lt;/code&gt; + &lt;code&gt;gdb&lt;/code&gt; + a gdb script file to handle the job.&lt;br /&gt;
&lt;br /&gt;
First, here's an example stack trace of the failure (using valgrind to easily obtain stack traces):&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;%&amp;nbsp;mpiexec -l -n 4 valgrind -q ./icbarrier |&amp;amp; &lt;a href="http://davegoodell.blogspot.com/2011/01/sortlabeledoutput-script.html"&gt;sort_labeled_output&lt;/a&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;=====================================================================================&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;= &amp;nbsp; BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;= &amp;nbsp; EXIT CODE: 6&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;= &amp;nbsp; CLEANING UP REMAINING PROCESSES&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;= &amp;nbsp; YOU CAN IGNORE THE BELOW CLEANUP MESSAGES&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;=====================================================================================&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;APPLICATION TERMINATED WITH THE EXIT STRING: Abort trap (signal 6)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313==&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313== Process terminating with default action of signal 6 (SIGABRT)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313== &amp;nbsp; &amp;nbsp;at 0x10027D616: __kill (in /usr/lib/libSystem.B.dylib)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313== &amp;nbsp; &amp;nbsp;by 0x1003022CB: &lt;b&gt;__stack_chk_fail&lt;/b&gt; (in /usr/lib/libSystem.B.dylib)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313== &amp;nbsp; &amp;nbsp;by 0x10005D9D3: &lt;b&gt;MPIDI_CH3I_Progress&lt;/b&gt; (ch3_progress.c:539)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313== &amp;nbsp; &amp;nbsp;by 0x100109B0C: MPIR_Wait_impl (wait.c:67)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313== &amp;nbsp; &amp;nbsp;by 0x100109FFA: PMPI_Wait (wait.c:171)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313== &amp;nbsp; &amp;nbsp;by 0x100004506: MPI_Barrier (nbc_pmpi_adapter.c:24)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[1] ==47313== &amp;nbsp; &amp;nbsp;by 0x10000141D: main (icbarrier.c:37)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314==&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314== Process terminating with default action of signal 6 (SIGABRT)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314== &amp;nbsp; &amp;nbsp;at 0x10027D616: __kill (in /usr/lib/libSystem.B.dylib)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314== &amp;nbsp; &amp;nbsp;by 0x1003022CB: __stack_chk_fail (in /usr/lib/libSystem.B.dylib)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314== &amp;nbsp; &amp;nbsp;by 0x10005D9D3: MPIDI_CH3I_Progress (ch3_progress.c:539)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314== &amp;nbsp; &amp;nbsp;by 0x100109B0C: MPIR_Wait_impl (wait.c:67)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314== &amp;nbsp; &amp;nbsp;by 0x100109FFA: PMPI_Wait (wait.c:171)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314== &amp;nbsp; &amp;nbsp;by 0x100004506: MPI_Barrier (nbc_pmpi_adapter.c:24)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[2] ==47314== &amp;nbsp; &amp;nbsp;by 0x10000143B: main (icbarrier.c:45)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315==&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315== Process terminating with default action of signal 6 (SIGABRT)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315== &amp;nbsp; &amp;nbsp;at 0x10027D616: __kill (in /usr/lib/libSystem.B.dylib)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315== &amp;nbsp; &amp;nbsp;by 0x1003022CB: __stack_chk_fail (in /usr/lib/libSystem.B.dylib)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315== &amp;nbsp; &amp;nbsp;by 0x10005D9D3: MPIDI_CH3I_Progress (ch3_progress.c:539)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315== &amp;nbsp; &amp;nbsp;by 0x100109B0C: MPIR_Wait_impl (wait.c:67)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315== &amp;nbsp; &amp;nbsp;by 0x100109FFA: PMPI_Wait (wait.c:171)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315== &amp;nbsp; &amp;nbsp;by 0x100004506: MPI_Barrier (nbc_pmpi_adapter.c:24)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;[3] ==47315== &amp;nbsp; &amp;nbsp;by 0x10000143B: main (icbarrier.c:45)&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
So I took a quick gander at the assembly for &lt;code&gt;MPIDI_CH3I_Progress&lt;/code&gt; to find the canary value initialization and comparison code:&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;% objdump -d icbarrier &amp;gt; icbarrier.s&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;%&amp;nbsp;sed -n -e '/MPIDI_CH3I_Progress&amp;gt;:/,/^$/ p' icbarrier.s | head -n 15&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;000000010005c7f0 &amp;lt;_MPIDI_CH3I_Progress&amp;gt;:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c7f0: &amp;nbsp; 55 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;push &amp;nbsp; %rbp&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c7f1: &amp;nbsp; 48 89 e5 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mov &amp;nbsp; &amp;nbsp;%rsp,%rbp&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c7f4: &amp;nbsp; 41 57 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; push &amp;nbsp; %r15&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c7f6: &amp;nbsp; 41 56 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; push &amp;nbsp; %r14&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c7f8: &amp;nbsp; 41 55 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; push &amp;nbsp; %r13&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c7fa: &amp;nbsp; 41 54 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; push &amp;nbsp; %r12&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c7fc: &amp;nbsp; 53 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;push &amp;nbsp; %rbx&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c7fd: &amp;nbsp; 48 81 ec 08 02 00 00 &amp;nbsp; &amp;nbsp;sub &amp;nbsp; &amp;nbsp;$0x208,%rsp&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c804: &amp;nbsp; 48 89 bd 10 fe ff ff &amp;nbsp; &amp;nbsp;mov &amp;nbsp; &amp;nbsp;%rdi,-0x1f0(%rbp)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c80b: &amp;nbsp; 89 b5 0c fe ff ff &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp;%esi,-0x1f4(%rbp)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c811: &amp;nbsp; 48 8b 05 60 c8 10 00 &amp;nbsp; &amp;nbsp;mov &amp;nbsp; &amp;nbsp;0x10c860(%rip),%rax &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# 100169078 &amp;lt;_pvars+0x78&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c818: &amp;nbsp; 48 8b 10 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mov &amp;nbsp; &amp;nbsp;(%rax),%rdx&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; 10005c81b: &amp;nbsp; 48 89 55 c8 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp;%rdx,-0x38(%rbp)&lt;/b&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; 10005c81f: &amp;nbsp; 31 d2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; xor &amp;nbsp; &amp;nbsp;%edx,%edx&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
So in this code it looks like the offset is &lt;code&gt;-0x38&lt;/code&gt; rather than &lt;code&gt;-0x14&lt;/code&gt;. &amp;nbsp;Let's find the two addresses at which we will set our breakpoints:&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;%&amp;nbsp;sed -n -e '/MPIDI_CH3I_Progress&amp;gt;:/,/^$/ p' icbarrier.s | grep -- '-0x38(%rbp)'&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;10005c81b&lt;/b&gt;: &amp;nbsp; 48 89 55 c8 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp;%rdx,-0x38(%rbp)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;10005ce61&lt;/b&gt;: &amp;nbsp; 48 8b 55 c8 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp;-0x38(%rbp),%rdx&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
And now for our gdb script:&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;% cat gdb.script&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;break *0x10005c81b&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;break *0x10005ce61&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;commands 1&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;silent&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;set variable $cow = (unsigned long*)($rbp - 0x38)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;watch *$cow&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;continue&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;set variable $count = 3&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;commands 2&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;silent&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;delete $count&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;set variable $count = $count + 1&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;continue&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;run&lt;/code&gt;&lt;br /&gt;
&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;code&gt;%&amp;nbsp;mpiexec -n 4 xterm -e gdb -x gdb.script ./icbarrier&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
That command launches four xterm windows, each containing a single gdb instance that was running &lt;code&gt;icbarrier&lt;/code&gt; as the inferior. &amp;nbsp;Here's the resulting xterm+gdb screenshot for the process that hit the watchpoint first:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-g7_aRxJ74GU/TafKKWBmiTI/AAAAAAAAACQ/R9T2XpDQgcA/s1600/gdb_screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-g7_aRxJ74GU/TafKKWBmiTI/AAAAAAAAACQ/R9T2XpDQgcA/s1600/gdb_screenshot.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Unlike in many situations, this backtrace alone was not sufficient for me to figure out what the real bug was. &amp;nbsp;But, given that I changed some high level code (the nonblocking version of barrier, &lt;code&gt;MPIX_Ibarrier&lt;/code&gt;), I knew it was extremely unlikely that I had tickled some long-latent bug in the frequently used routine &lt;code&gt;MPIDI_CH3U_Request_unpack_uebuf&lt;/code&gt;. &amp;nbsp;So after a few "WTFs" and some further head scratching, I took a hard look at the upper level code (error checking and boring code omitted for clarity):&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;int MPIR_Ibarrier_inter(MPID_Comm *comm_ptr, MPID_Sched_t s)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;{&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;int mpi_errno = MPI_SUCCESS;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;int size, rank, root;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;int buf = 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/* do a barrier on the local intracommunicator */&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;mpi_errno = MPIR_Ibarrier_intra(comm_ptr-&amp;gt;local_comm, s);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;MPID_SCHED_BARRIER(s);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/* rank 0 on each group does an intercommunicator broadcast to the&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; remote group to indicate that all processes in the local group&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; have reached the barrier. We do a 1-byte bcast because a 0-byte&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; bcast will just return without doing anything. */&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/* first broadcast from left to right group, then from right to&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; left group */&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (comm_ptr-&amp;gt;is_low_group) {&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpi_errno = MPIR_Ibcast_inter(&amp;amp;buf, 1, MPI_BYTE, root, comm_ptr, s);&lt;/code&gt;&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;MPID_SCHED_BARRIER(s);&lt;/code&gt;&lt;/div&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* receive bcast from right */&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;root = 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpi_errno = MPIR_Ibcast_inter(&amp;amp;buf, 1, MPI_BYTE, root, comm_ptr, s);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else {&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* receive bcast from left */&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;root = 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpi_errno = MPIR_Ibcast_inter(&amp;amp;buf, 1, MPI_BYTE, root, comm_ptr, s);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;MPID_SCHED_BARRIER(s);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* bcast to left */&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;root = (rank == 0) ? MPI_ROOT : MPI_PROC_NULL;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;mpi_errno = MPIR_Ibcast_inter(&amp;amp;buf, 1, MPI_BYTE, root, comm_ptr, s);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;fn_exit:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return mpi_errno;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;fn_fail:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;goto fn_exit;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;}&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
This function is called, adding operations to a communication schedule, then an &lt;code&gt;MPI_Wait&lt;/code&gt; call is made later to actually force the bulk of the schedule to complete.&lt;br /&gt;
&lt;br /&gt;
Do you see the bug? &amp;nbsp;I'd be surprised if you did, since there are few people familiar with the style of MPICH2 code, and even fewer people who know how the NBC implementation works. &amp;nbsp;But if you do, give yourself a pat on the back, and then please send me bug reports and patches for my other bugs &amp;nbsp;:)&lt;br /&gt;
&lt;br /&gt;
Take a closer look at the buffer used for the intercomm broadcast. &amp;nbsp;It's a stack allocated variable, which worked great in the blocking version of this routine. &amp;nbsp;Unfortunately, this is a nonblocking barrier, so this routine exits before the ibcast is actually ever performed. &amp;nbsp;So now we've managed to schedule a broadcast to occur that will overwrite a location on the stack that no longer actually refers to &lt;code&gt;int buf;&lt;/code&gt;. &amp;nbsp;Instead, if we are unlucky it will refer to some random piece of a different function's stack frame. &amp;nbsp;In the backtraces above, this random piece was the &lt;code&gt;-fstack-protector&lt;/code&gt;/SSP canary memory. &amp;nbsp;The bug moved around when I would insert debugging variables because they would affect the specific location of the canary value in memory, sometimes yielding a corrupted parameter or local variable instead.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://trac.mcs.anl.gov/projects/mpich2/changeset/8400"&gt;Changing that buffer&lt;/a&gt; to be &lt;code&gt;malloc&lt;/code&gt;ed instead fixed the problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-6032861140310400661?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/g6Zz-vs_oi8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/6032861140310400661/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2011/04/debugging-wily-stack-overflows-in-mpi.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/6032861140310400661?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/6032861140310400661?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/g6Zz-vs_oi8/debugging-wily-stack-overflows-in-mpi.html" title="Debugging Wily Stack Overflows in MPI Programs" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-g7_aRxJ74GU/TafKKWBmiTI/AAAAAAAAACQ/R9T2XpDQgcA/s72-c/gdb_screenshot.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2011/04/debugging-wily-stack-overflows-in-mpi.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUDQHY9fip7ImA9WhZSGEU.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-5460828810145625551</id><published>2011-04-03T21:31:00.000-05:00</published><updated>2011-04-03T21:31:11.866-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-03T21:31:11.866-05:00</app:edited><title>Roku stands behind their product</title><content type="html">My older Roku player (&lt;a href="http://www.amazon.com/Roku-N1100-HD-Player/dp/B001PIBE8I"&gt;this model&lt;/a&gt;, N1000-B) died a couple of months ago. &amp;nbsp;The wireless NIC went out to lunch for some reason, showing 00:00:00:00:00:00 as its MAC address and totally unable to see any wireless networks, just &lt;a href="http://forums.roku.com/viewtopic.php?f=28&amp;amp;t=29830&amp;amp;sid=7daae75e06560f6d33fc6c86ed639bc0"&gt;as described here&lt;/a&gt;. &amp;nbsp;I was busy and lazy at the time, so we just switched over to watching Netflix streaming content on our Wii instead.&lt;br /&gt;
&lt;br /&gt;
Last Friday I finally got around to calling Roku about the issue and the technician that I got was very helpful. &amp;nbsp;He didn't give me the "reboot runaround"; he just asked me what troubleshooting steps I had taken, and ensured that my MAC address was showing all zeroes. &amp;nbsp;After a bit more discussion, he offered to replace the unit for free, even though it was nearly a past its warranty expiration. &amp;nbsp;They mailed the replacement unit (looks like it might be factory refurb?) via FedEx and 3 business days later the new unit was in my hands. &amp;nbsp;The new unit setup was painless (as expected), and a return shipping label was included so even the round-trip shipping was free.&lt;br /&gt;
&lt;br /&gt;
I was extremely pleased that Roku stood behind their product, even after it was out of warranty. &amp;nbsp;They did exactly the right thing to change my mind from "I'll never buy another one of these" to "I'd happily buy something from them again."&lt;br /&gt;
&lt;br /&gt;
(full disclosure: I have no affiliation with Roku, other than being a fairly satisfied customer)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-5460828810145625551?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/x_wsbsrlJ8M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/5460828810145625551/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2011/04/roku-stands-behind-their-product.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5460828810145625551?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5460828810145625551?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/x_wsbsrlJ8M/roku-stands-behind-their-product.html" title="Roku stands behind their product" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>1</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2011/04/roku-stands-behind-their-product.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8BSXg5eSp7ImA9Wx9aE0k.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-5994761905874192425</id><published>2011-03-05T10:50:00.000-06:00</published><updated>2011-03-05T10:50:58.621-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-05T10:50:58.621-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>m4_include and aclocal</title><content type="html">I ran into some surprising behavior a little while back while hacking on the MPICH2 build system, that I thought I should mention here.&amp;nbsp; But first, some background info is in order.&amp;nbsp; We have numerous subsystems that are currently configured (in the autoconf sense) by running an autoconf-generated configure script from various points in the top level configure.&amp;nbsp; Think &lt;code&gt;AC_CONFIG_SUBDIRS&lt;/code&gt;, but the subconfig happens at the place where the macro is used, rather than being deferred to &lt;code&gt;config.status&lt;/code&gt;-time.&amp;nbsp; There are some advantages to this scheme, but there are two fairly severe disadvantages:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The subconfigure scripts tend to re-test a whole bunch of information about the build environment (e.g., six repeated checks for "how to run the C preprocessor").&amp;nbsp; Not only is this wasteful in terms of time, but there is always unlikely possibility that two configure scripts will come to subtly different conclusions about the build environment, which could cause wacky bugs later in the build.&lt;/li&gt;
&lt;li&gt;There's no easy mechanism to utilize the results of subconfigure tests that should be global.&amp;nbsp; That is, if we add &lt;code&gt;-I/path/to/includes&lt;/code&gt; to &lt;code&gt;CPPFLAGS&lt;/code&gt; that should be used for all compilation, then this won't be seen in the top-level configure without some additional work.&amp;nbsp; We currently "pass" these values back via a "localdefs" file that is listed in the subconfigure's &lt;code&gt;AC_CONFIG_FILES&lt;/code&gt; and contains some &lt;code&gt;@FOO@&lt;/code&gt; substitutions that are either &lt;code&gt;AC_SUBST&lt;/code&gt;ed or "precious" (which implies &lt;code&gt;AC_SUBST&lt;/code&gt; for that var).&amp;nbsp; This stinks because it's a fairly manual process, and it's impenetrable to outsiders who are unfamiliar with our build system because the sourcing of "localdefs" is hidden inside a custom autoconf macro.&lt;/li&gt;
&lt;/ol&gt;So I'm taking a stab at converting these configure files to be configure.in fragments that are then &lt;code&gt;m4_include&lt;/code&gt;d.&amp;nbsp; This will cause those tests to be run in the same shell as the top-level configure and will only run the additional tests that are needed by the subsystem.&amp;nbsp; In the process of that conversion, I ran into some odd error messages from the autotools that are represented by the following example program.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Quick Quiz&lt;/i&gt;: The code in Listing A will successfully &lt;code&gt;autoreconf&lt;/code&gt; and &lt;code&gt;configure&lt;/code&gt;.&amp;nbsp; The code in Listing B will fail during &lt;code&gt;autoreconf&lt;/code&gt;'s invocation of &lt;code&gt;aclocal&lt;/code&gt;.&amp;nbsp; Why?&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;b&gt;Common code&lt;/b&gt;: &lt;br /&gt;
&lt;pre&gt;## contents of configure.in
AC_INIT([foo],[1.0])
AM_INIT_AUTOMAKE([-Wall -Werror foreign 1.11 subdir-objects])
LT_INIT([])
AC_PROG_CC
var="yes"
AM_CONDITIONAL([COND],[test "$var" = "yes"])
dnl this makes m4 bail, claiming that AM_COND_IF is undefined
m4_foreach([subsys_i],[[subconfigure]],[m4_include(subsys_i[.m4])])
AC_OUTPUT([Makefile])&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Listing A&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;## contents of subconfigure.m4
AC_PROG_GREP&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Listing B&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;## contents of subconfigure.m4
AM_COND_IF([COND],[echo COND is true],[echo COND is false])&lt;/pre&gt;&lt;hr /&gt;&lt;br /&gt;
Do you see the problem here?&amp;nbsp; I sure didn't, even after some moderate debugging.&amp;nbsp; Go ahead and think about it for a minute, I'll wait... &lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
Luckily, the nice folks on the autoconf list &lt;a href="http://thread.gmane.org/gmane.comp.sysutils.autoconf.general/13724/focus=13728"&gt;helped me understand what was going on here&lt;/a&gt;.&amp;nbsp; There are two things happening here:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Not all macros are created equal.&amp;nbsp; In my original world view, &lt;code&gt;AC_PROG_GREP&lt;/code&gt; and &lt;code&gt;AM_COND_IF&lt;/code&gt; are both just &lt;code&gt;AC_DEFUN&lt;/code&gt;ed m4 macros and should behave more or less identically.&amp;nbsp; However this assumption is totally false.&amp;nbsp; &lt;code&gt;AC_PROG_GREP&lt;/code&gt; is a macro that is built-in to autoconf, and therefore does not get distributed with your package via &lt;code&gt;aclocal.m4&lt;/code&gt;, while &lt;code&gt;AM_COND_IF&lt;/code&gt; comes with automake and is managed by aclocal, and must be placed into your package's &lt;code&gt;aclocal.m4&lt;/code&gt; in order to be properly expanded. &lt;/li&gt;
&lt;li&gt;It turns out that aclocal isn't as smart as I thought it was.&amp;nbsp; When it traces the m4 files looking for macro definitions that it must add to aclocal.m4, it doesn't perform real &lt;code&gt;m4_include&lt;/code&gt;s at that time.&amp;nbsp; Instead it uses some regex heuristics in order to determine what file is being included and then traces that file separately.&amp;nbsp; Since the name of the file that is being included is being computed via an m4 macro in the example above, aclocal gets rather confused and just doesn't trace the subconfigure.m4 file.&lt;/li&gt;
&lt;/ol&gt;The upshot of all of this is that I can't use m4 code to programmatically include subsystem m4 fragments.&amp;nbsp; They must either be hard-coded m4 file names or be autogenerated by some other non-autotools step, such as a quick shell script run before &lt;code&gt;autoreconf&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-5994761905874192425?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/QR_8jGQ0_y0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/5994761905874192425/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2011/03/m4include-and-aclocal.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5994761905874192425?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5994761905874192425?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/QR_8jGQ0_y0/m4include-and-aclocal.html" title="m4_include and aclocal" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2011/03/m4include-and-aclocal.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQCQXw8eSp7ImA9Wx9WF0Q.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-3855609456481918092</id><published>2011-01-21T22:46:00.002-06:00</published><updated>2011-01-23T08:36:00.271-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-23T08:36:00.271-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="travel" /><category scheme="http://www.blogger.com/atom/ns#" term="climbing" /><title>Midwest Ice Climbers Ice Festival, 2011</title><content type="html">&lt;a href="http://goodell.smugmug.com/Travel/Ice-Climbing-2011/15507532_ZrRFp#1161465500_T8Z6X"&gt;&lt;img src="http://goodell.smugmug.com/Travel/Ice-Climbing-2011/DSC0261edited-1/1161465500_T8Z6X-L.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Last weekend I got to try ice climbing out at the &lt;a href="http://www.theicepit.org/"&gt;Ice Pit&lt;/a&gt; near Green Bay, Wisconsin.&amp;nbsp; It was a very cool setup, sort of an outdoor ice climbing gym in an active quarry.&amp;nbsp; Normally you must be a member to climb there, but for the festival it was just $20 for the whole weekend.&amp;nbsp; I did the trip with five other guys, all rock climbers, three of which also work at the Lab.&lt;br /&gt;
&lt;br /&gt;
I found the climbing itself surprisingly difficult, despite my (at least modest) rock climbing abilities.&amp;nbsp; According to others that I spoke with at the festival, most of the routes that we were climbing were in the &lt;a href="http://en.wikipedia.org/wiki/Ice_climbing#Waterfall_ice_grading"&gt;WI3-WI4&lt;/a&gt; range, all about 100 feet high.&amp;nbsp; The hardest part was getting accustomed to the crampons and really trusting my feet.&amp;nbsp; When I didn't trust my feet enough, I would put too much weight on my hands which led to totally pumped out forearms after 100 feet of ice.&amp;nbsp; We were each able to get three climbs in each of the two days, which was enough to tire me out pretty effectively.&lt;br /&gt;
&lt;br /&gt;
There was a fair amount of demo gear to borrow from various vendors,  including boots, crampons, and ice tools.&amp;nbsp; However, we got in touch with  &lt;a href="http://downwindsports.com/mainSite/rentals/ice-climbing-gear/"&gt;Down Wind Sports&lt;/a&gt; (in Michigan's UP) via email before the festival and  arranged to rent gear from them on Friday evening instead.&amp;nbsp; That way we  were able to save a lot of time each morning and were certain that we  would have gear that fit.&amp;nbsp; Bill @ Down Wind Sports was extremely nice  and helpful, I'd do business with them again without hesitation.&amp;nbsp; For  $40/person we had boots and crampons for the whole weekend.&amp;nbsp; Ice tools  were easy to come by as demo gear, and someone in our party already had a  set as well.&lt;br /&gt;
&lt;br /&gt;
Overall it was a very enjoyable trip.&amp;nbsp; I might do a little easy ice climbing in the future as the opportunity presents itself, but for now I'm not planning on picking it up as a regular hobby.&amp;nbsp; I already have too many hobbies as it is, and this isn't the cheapest or most accessible hobby around.&amp;nbsp; A brand new set of top-rope ice equipment (boots, crampons, tools) adds up to $800-$1000, while a used set is probably half of that plus more time hunting for a decent deal.&amp;nbsp; And northern Illinois isn't exactly teeming with waterfall ice to climb. &lt;br /&gt;
&lt;br /&gt;
You can find a few more photos of the event &lt;a href="http://goodell.smugmug.com/Travel/Ice-Climbing-2011/15507532_ZrRFp#1161465500_T8Z6X"&gt;on my Smugmug page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-3855609456481918092?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/QUVeSBAQ6Kk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/3855609456481918092/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2011/01/midwest-ice-climbers-ice-festival-2011.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/3855609456481918092?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/3855609456481918092?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/QUVeSBAQ6Kk/midwest-ice-climbers-ice-festival-2011.html" title="Midwest Ice Climbers Ice Festival, 2011" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2011/01/midwest-ice-climbers-ice-festival-2011.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQAQHo8fCp7ImA9Wx9WFUU.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-8442695432960313967</id><published>2011-01-20T23:38:00.001-06:00</published><updated>2011-01-20T23:39:01.474-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-20T23:39:01.474-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="env improvement" /><category scheme="http://www.blogger.com/atom/ns#" term="MPI" /><title>sort_labeled_output script</title><content type="html">Quick MPICH2 tip: passing the "&lt;code&gt;-l&lt;/code&gt;" option to MPICH2's mpiexec (hydra) yields rank-labled output like so:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;% mpiexec -l -n 2 ./examples/cpi&lt;br /&gt;
[0] Process 0 of 2 is on g2-2.local&lt;br /&gt;
[1] Process 1 of 2 is on g2-2.local&lt;br /&gt;
[0] pi is approximately 3.1415926544231318, Error is 0.0000000008333387&lt;br /&gt;
[0] wall clock time = 0.000210&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
This is handy for figuring out which process is printing what without reaching in and modifying all of your printf statements to explicitly print the rank as well.&lt;br /&gt;
&lt;br /&gt;
For more complicated output, and especially multiline output that you would get from running valgrind, this interleaved output can be hard to follow.  Enter &lt;code&gt;sort_labeled_output&lt;/code&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;#!/bin/zsh&lt;br /&gt;
# assumes output that matches the following regex: /^\[\d+\] .*$/&lt;br /&gt;
exec sort --stable --key=1.2,1.0 -n&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The script just &lt;i&gt;stably&lt;/i&gt; sorts the output by rank prefix, which makes it much easier to read multiline output.&lt;br /&gt;
&lt;br /&gt;
Given that this is just a thin wrapper around GNU sort, I actually didn't build this script for a long time.  But it turns out that this is a task that I do all the time and reconstructing the sort arguments always distracts me a bit from the debugging task at hand.  So the script has been a big productivity win.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-8442695432960313967?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/yx7GC0P6o00" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/8442695432960313967/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2011/01/sortlabeledoutput-script.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8442695432960313967?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8442695432960313967?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/yx7GC0P6o00/sortlabeledoutput-script.html" title="sort_labeled_output script" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2011/01/sortlabeledoutput-script.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIARno-cCp7ImA9Wx9WFUU.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-4006791330665876700</id><published>2011-01-20T23:25:00.000-06:00</published><updated>2011-01-20T23:25:47.458-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-20T23:25:47.458-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="travel" /><category scheme="http://www.blogger.com/atom/ns#" term="climbing" /><title>Climbing in Agio Farango</title><content type="html">&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://goodell.smugmug.com/gallery/15424334_nR5Lb#1154688589_MJ8VT"&gt;&lt;img src="http://goodell.smugmug.com/Travel/Crete-Greece-2010/IMGP2832/1154688589_MJ8VT-XL-1.jpg" style="margin-left: auto; margin-right: auto;" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Dave following on "Το ονειρο και ο φοβος" (Google trans. "The dream and  the fear"), 5b (approx. 5.8+), in Agio Farango, Crete, Greece.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I had business on Crete, Greece and was fortunate enough to be able to stay an extra day for some sport climbing.&amp;nbsp; We were staying east of Heraklion, near Hersonissos, so Agio Farango, on the south side of the island seemed the best option for a day trip.&amp;nbsp; We picked up a &lt;a href="http://www.climb-europe.com/RockClimbingShop/Crete-north-to-south-guidebook.html"&gt;guide book online&lt;/a&gt; ahead of time, rented a car, and headed southwest about 100 km or so, probably 2.5 hours each way, to Kali Limenes.&lt;br /&gt;
&lt;br /&gt;
We took the approach from Kali Limenes, a hike from the east of the gorge a few hundred yards inland from the Mediterranean.&amp;nbsp; Despite online directions and directions in the guide book, it was extremely unclear where we should park and where the actual marked path (with blazes and cairns) started.&amp;nbsp; Below I've included a map based on my several-months-old recollection of the route and my interpretation of the satellite photos:&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="0" height="350" marginheight="0" marginwidth="0" scrolling="no" src="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;t=h&amp;amp;msa=0&amp;amp;msid=201449877294086662964.00049a538892ef18bf6ee&amp;amp;ll=34.929571,24.790092&amp;amp;spn=0.012315,0.025749&amp;amp;z=15&amp;amp;output=embed" width="600"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;small&gt;View &lt;a href="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;t=h&amp;amp;msa=0&amp;amp;msid=201449877294086662964.00049a538892ef18bf6ee&amp;amp;ll=34.929571,24.790092&amp;amp;spn=0.012315,0.025749&amp;amp;z=15&amp;amp;source=embed" style="color: blue; text-align: left;"&gt;Agio Farango approach from Kali Limenes&lt;/a&gt; in a larger map&lt;/small&gt;&lt;br /&gt;
&lt;br /&gt;
If I were to do it all again, I would probably try the alternative approach from Moni Odigitrias at the north end of the gorge, even though &lt;a href="http://www.climbincrete.com/english/climbing/iraklio/agiofarago/agiofarago-gorge-crete.php"&gt;this website advises the Kali Limenes route&lt;/a&gt;.&amp;nbsp; We burned up a bit of time just trying to figure out where the trail was.&lt;br /&gt;
&lt;br /&gt;
The climbs were fun, although I found the difficulty a bit stiff in some cases.&amp;nbsp; Also, many of the routes had sections of very sharp limestone rock, which was difficult to hold onto.&amp;nbsp; Good footwork was essential for such routes.&amp;nbsp; While most routes were well bolted, I also followed on my first trad route, an easy 4c (French scale, approx. 5.7 YDS, even though it felt easier than that) named Ξωτικο that started right on the beach and had a great view of the water and beach from the top.&lt;br /&gt;
&lt;br /&gt;
Goats are all over the area, especially down in the gorge itself, as well as soloing up on the cliffs above you.&amp;nbsp; They are amazing climbers, able to scale walls and routes that look difficult for us humans with little fear or difficulty.&amp;nbsp; However, watch out for other tourists and their dogs.&amp;nbsp; While I was top roping one of the routes someone's dog chased a goat between the rock and my belayer 30 feet below me, which was a rather unsettling experience. &lt;br /&gt;
&lt;br /&gt;
Overall, a great trip.&amp;nbsp; It's a pretty intense day trip from the Heraklion area, and the driving and trail finding can really eat into your climbing time.&amp;nbsp; If you have the time, I'd recommend bringing a tent and some food and staying overnight on or near the beach in order to fit more climbing into a more relaxed outing.&lt;br /&gt;
&lt;br /&gt;
More photos from the trip can be found &lt;a href="http://goodell.smugmug.com/Travel/Crete-Greece-2010/"&gt;here on Smugmug&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-4006791330665876700?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/s0tsaYir2Hs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/4006791330665876700/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2011/01/climbing-in-agio-farango.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/4006791330665876700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/4006791330665876700?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/s0tsaYir2Hs/climbing-in-agio-farango.html" title="Climbing in Agio Farango" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2011/01/climbing-in-agio-farango.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUENQ3o_fSp7ImA9Wx9WFUU.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-25154485007087471</id><published>2011-01-11T23:25:00.001-06:00</published><updated>2011-01-20T23:28:12.445-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-20T23:28:12.445-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="travel" /><category scheme="http://www.blogger.com/atom/ns#" term="climbing" /><title>reviving posting...</title><content type="html">I looked at my blog again today and it turns out that my last post was in August of last year.&amp;nbsp; That's around the time that the Fall travel season picked up, followed immediately by Thanksgiving and Christmas, so things have been pretty busy for me.&amp;nbsp; Here are the highlights from my period of radio silence:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;the annual Seattle trip for "Birthstravaganza," a joint birthday party for two of my old friends from college&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cmcwebsite.org/Render.asp?nID=3306&amp;amp;nSectionID=0"&gt;New-timers / Old Climbers event&lt;/a&gt; with the Chicago Mountaineering Club at &lt;a href="http://www.mountainproject.com/v/wisconsin/devils_lake/105729927"&gt;Devil's Lake, WI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.eurompi2010.org/"&gt;EuroMPI 2010&lt;/a&gt; in Stuttgart, Germany...&lt;/li&gt;
&lt;li&gt;... immediately followed by &lt;a href="http://www.cluster2010.org/"&gt;IEEE Cluster 2010&lt;/a&gt; in Crete, Greece&lt;/li&gt;
&lt;li&gt;one day of sport climbing in &lt;a href="http://davegoodell.blogspot.com/2011/01/climbing-in-agio-farango.html"&gt;Agio Farango, Crete, Greece&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Heather and I went to &lt;a href="http://goodell.smugmug.com/Travel/Spain/14694334_jPzN9#1097511205_UXdrG"&gt;Spain&lt;/a&gt; for two weeks on vacation in November&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sc10.supercomputing.org/"&gt;SC10&lt;/a&gt; in New Orleans, LA&lt;/li&gt;
&lt;li&gt;hosting Thanksgiving for my parents and siblings at our home for the first time&lt;/li&gt;
&lt;li&gt;I finished my long-overdue bookcase (no pics yet).&lt;/li&gt;
&lt;/ul&gt;In retrospect I had a ton to blog about but a lack of time and motivation.&amp;nbsp; I'll try to put up a few pics and details about some of these items in catch-up posts, but I'm not making any promises.&amp;nbsp; In the unlikely event that anyone wants details on any particular event, please post a comment to let me know.&lt;br /&gt;
&lt;br /&gt;
In forward-looking news, I'm &lt;a href="http://www.theicepit.org/onlinesite%5Cgroupinfo%5Ccurrentevents.asp"&gt;going ice climbing this weekend&lt;/a&gt; at &lt;a href="http://www.theicepit.org/"&gt;the Ice Pit&lt;/a&gt; in Green Bay, WI, which I'm really excited about.&amp;nbsp; I also was lucky enough to snag tickets to the Chicago Beer Society's &lt;a href="http://chibeer.org/2010/12/18/13th-annual-chicagoland-brewpub-microbrewery-shootout-sold-out/"&gt;Brewpub Shootout&lt;/a&gt;, which is an excellent event.&amp;nbsp; Lots of great beers that are brewed just for the event, in addition to some amazing food that is served.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-25154485007087471?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/MkTMUJZJLKM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/25154485007087471/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2011/01/reviving-posting.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/25154485007087471?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/25154485007087471?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/MkTMUJZJLKM/reviving-posting.html" title="reviving posting..." /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2011/01/reviving-posting.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAGSHw5fyp7ImA9Wx5TF00.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-2537912925754266207</id><published>2010-08-01T19:01:00.001-05:00</published><updated>2010-08-01T19:08:49.227-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-01T19:08:49.227-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="osx" /><title>disable animations in Skim to avoid using the MacBook Pro external (power hogging) GPU</title><content type="html">My work laptop is a 15" MacBook Pro from the current generation (first batch with Nehalems).  This laptop includes two GPUs: an integrated one from Intel and an external one from Nvidia.  The integrated unit has generally lower performance but generally lower power consumption as well.  The external unit has generally higher performance but generally higher power consumption.&lt;br /&gt;&lt;br /&gt;OS X has a pretty cool feature where it will seamlessly switch between the two cards based on current software performance requirements.  However, as with any automagical switching, the switching software sometimes makes a bad decision, or simply doesn't have enough information available to make a good decision.  So I use &lt;a href="http://codykrieger.com/gfxCardStatus/"&gt;gfxCardStatus&lt;/a&gt; to figure out which unit is currently in use.  It shows me which unit is in use, as well as which applications (or the external display) are forcing the Nvidia card to be used at any given time.  It also lets me force one unit or the other to be used instead of dynamically switching between the two.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://appletoolbox.com/2010/05/macbook-pro-mid-2010-graphics-switching-which-apps-trigger-how-to-monitor/"&gt;Here's a (trivially incomplete) list of applications&lt;/a&gt; that force external graphics usage.  Among them is Skim, &lt;a href="http://davegoodell.blogspot.com/2009/05/skimapp-for-large-pdfs.html"&gt;my favorite PDF reader&lt;/a&gt;.  Oddly, it only uses the higher-powered graphics after searching the document.  This annoyed me greatly because I tend to leave the app open for long periods of time, and I also tend to search fairly often.&lt;br /&gt;&lt;br /&gt;Luckily, a recent version of Skim added &lt;a href="http://sourceforge.net/apps/mediawiki/skim-app/index.php?title=Hidden_Preferences#Animations"&gt;a new hidden preference to disable animations&lt;/a&gt;.  This seems to eliminate the dependency on the external display, and thereby save my battery power.  Just type the following command into your terminal and restart Skim:&lt;br /&gt;&lt;pre&gt;defaults write -app Skim SKDisableAnimations -boolean true&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/176695309595372156-2537912925754266207?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/H-EmTf8oCcs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/2537912925754266207/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/08/disable-animations-in-skim-to-avoid.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/2537912925754266207?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/2537912925754266207?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/H-EmTf8oCcs/disable-animations-in-skim-to-avoid.html" title="disable animations in Skim to avoid using the MacBook Pro external (power hogging) GPU" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/08/disable-animations-in-skim-to-avoid.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIAQX4yeip7ImA9WxFWFUo.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-8171152099111878928</id><published>2010-06-03T09:11:00.010-05:00</published><updated>2010-06-03T09:49:00.092-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-03T09:49:00.092-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="env improvement" /><title>fix codetrunk diff/patch colors in Firefox</title><content type="html">At work I often use &lt;a href="http://www.codetrunk.com/"&gt;codetrunk.com&lt;/a&gt; to share patches for code review with other developers on my team.  I used to use &lt;a href="http://www.pastebin.com/"&gt;pastebin.com&lt;/a&gt;, but ever since it changed ownership a few months ago it has been far less useful.  They broke the major pastebin command line tools and the syntax highlighting for diff/patch types is very poor.&lt;br /&gt;&lt;br /&gt;The codetrunk site was simple enough that I quickly wrote up &lt;a href="http://github.com/goodell/pipe2pastebin"&gt;my own command line script&lt;/a&gt; for uploading content.&lt;br /&gt;&lt;br /&gt;Unfortunately though, the codetrunk highlighting for diff/patch files (the primary type that I use there) leaves something to be desired.  By default additions are blue and deletions are green, which is hard to read if you are familiar with the green/red highlighting used by git and other programs.  Fortunately, this is pretty easy to fix with some CSS in your Firefox &lt;code&gt;userContent.css&lt;/code&gt; file in your &lt;a href="http://www.gemal.dk/mozilla/profile.html"&gt;profile&lt;/a&gt;.  Just stick the snippet below into that file (&lt;u&gt;not&lt;/u&gt; your &lt;code&gt;userChrome.css&lt;/code&gt; file) and restart your browser.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@-moz-document domain(codetrunk.com) {&lt;br /&gt;  .syntaxhighlighter .diff.comments, .syntaxhighlighter .diff.comments a {&lt;br /&gt;      color: red !important;&lt;br /&gt;  }&lt;br /&gt;  .syntaxhighlighter .diff.string, .syntaxhighlighter .diff.string a {&lt;br /&gt;      color: green !important;&lt;br /&gt;  }&lt;br /&gt;}&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/176695309595372156-8171152099111878928?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/RTU1rWaH6rA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/8171152099111878928/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/06/fix-codetrunk-diffpatch-colors-in.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8171152099111878928?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8171152099111878928?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/RTU1rWaH6rA/fix-codetrunk-diffpatch-colors-in.html" title="fix codetrunk diff/patch colors in Firefox" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>4</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/06/fix-codetrunk-diffpatch-colors-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04MSXsyfyp7ImA9WxFWEEw.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-2513181416376962049</id><published>2010-05-27T22:39:00.009-05:00</published><updated>2010-05-27T23:13:08.597-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-27T23:13:08.597-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="env improvement" /><title>ltrace + pthreads</title><content type="html">I was recently debugging some threading issues in &lt;a href="http://www.mcs.anl.gov/research/projects/mpich2/"&gt;MPICH2&lt;/a&gt; and tried using &lt;a href="http://linux.die.net/man/1/ltrace"&gt;ltrace&lt;/a&gt; to tell me the return code from &lt;code&gt;pthread_mutex_lock&lt;/code&gt; and a few related functions.  Tools like &lt;code&gt;strace&lt;/code&gt;, &lt;code&gt;ltrace&lt;/code&gt;, and valgrind are essential for debugging MPI programs because you can't always strap a debugger on them, and even when you can it tends to be a heavyweight procedure.&lt;br /&gt;&lt;br /&gt;Unfortunately, when I did use &lt;code&gt;ltrace&lt;/code&gt; I got a bunch of output that looked like this:&lt;br /&gt;&lt;pre&gt;% mpiexec -n 1 ltrace ./examples/cpi |&amp;amp; grep pthread&lt;br /&gt;pthread_mutex_init(0x810543c, 0, 0xbfe8d6c8, 0x80c44a9, 0x80eb4ef) = 0&lt;br /&gt;pthread_mutex_init(0x810540c, 0, 0xbfe8d6c8, 0x80c44a9, 0x80eb4ef) = 0&lt;br /&gt;pthread_mutex_init(0x8105424, 0, 0xbfe8d6c8, 0x80c44a9, 0x80eb4ef) = 0&lt;br /&gt;pthread_self(0x8105424, 0, 0xbfe8d6c8, 0x80c44a9, 0x80eb4ef) = 0xb7da1ae0&lt;br /&gt;pthread_mutex_init(0x81052a0, 0, 0, 0, 0xbfe8d6f4) = 0&lt;br /&gt;pthread_mutex_lock(0x810540c, 0x80eb50d, 128, 0x80c44a9, 0x80eb4ef) = 0&lt;br /&gt;pthread_mutex_unlock(0x810540c, 0xbfe8d73c, 0, 0xbfe8d6b4, 0xbfe8d6bc) = 0&lt;br /&gt;pthread_mutex_destroy(0x810540c, 0, 0xbfe8d708, 0x80597bb, 0xb7eedff4) = 0&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Of course, that doesn't make any sense.  Everyone knows that &lt;code&gt;pthread_mutex_lock&lt;/code&gt; only takes one argument, and &lt;code&gt;pthread_self&lt;/code&gt; doesn't take any arguments.  After a few minutes of studying &lt;code&gt;/usr/include/pthread.h&lt;/code&gt; and &lt;code&gt;/etc/ltrace.conf&lt;/code&gt;, I whipped up this output instead:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;% mpiexec -n 1 ltrace ./examples/cpi |&amp;amp; grep pthread&lt;br /&gt;pthread_mutex_init(0x810543c, NULL)              = 0&lt;br /&gt;pthread_mutex_init(0x810540c, NULL)              = 0&lt;br /&gt;pthread_mutex_init(0x8105424, NULL)              = 0&lt;br /&gt;pthread_self()                                   = 3084118752&lt;br /&gt;pthread_mutex_init(0x81052a0, NULL)              = 0&lt;br /&gt;pthread_mutex_lock(0x810540c)                    = 0&lt;br /&gt;pthread_mutex_unlock(0x810540c)                  = 0&lt;br /&gt;pthread_mutex_destroy(0x810540c)                 = 0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The "secret" sauce goes in &lt;code&gt;~/.ltrace.conf&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;; pthread.h&lt;br /&gt;; - misc&lt;br /&gt;ulong pthread_self(void);&lt;br /&gt;int pthread_equal(ulong, ulong);&lt;br /&gt;int pthread_create(addr, addr, addr, addr);&lt;br /&gt;int pthread_join(ulong, addr);&lt;br /&gt;int pthread_exit(addr);&lt;br /&gt;&lt;br /&gt;; - mutex functions&lt;br /&gt;int pthread_mutex_init(addr, addr);&lt;br /&gt;int pthread_mutex_lock(addr);&lt;br /&gt;int pthread_mutex_trylock(addr);&lt;br /&gt;int pthread_mutex_unlock(addr);&lt;br /&gt;int pthread_mutex_destroy(addr);&lt;br /&gt;&lt;br /&gt;; - condition variable functions&lt;br /&gt;int pthread_cond_init(addr, addr);&lt;br /&gt;int pthread_cond_destroy(addr);&lt;br /&gt;int pthread_cond_signal(addr);&lt;br /&gt;int pthread_cond_broadcast(addr);&lt;br /&gt;int pthread_cond_wait(addr, addr);&lt;br /&gt;&lt;/pre&gt;The system that I was on was a 32-bit Linux box running Ubuntu Hardy.  For some reason, the &lt;code&gt;--library&lt;/code&gt; option didn't work (I still got output from all libraries), which is why I have the &lt;code&gt;grep&lt;/code&gt; bit above.  If you are sure you only care about a particular function, the &lt;code&gt;-e pthread_mutex_lock&lt;/code&gt; approach seemed to work OK.  You may have to adjust this configuration snippet a bit in order to match your platform.  In particular, the &lt;code&gt;ulong&lt;/code&gt; types might change on 64-bit (I haven't checked though).&lt;br /&gt;&lt;br /&gt;I'm not sure why pthreads wasn't supported out of the box by &lt;code&gt;ltrace&lt;/code&gt;.  In fact, given the limited range of supported types for &lt;code&gt;ltrace&lt;/code&gt;, I'm not sure why this can't be almost completely automated.  I think a few hours with &lt;a href="http://code.google.com/p/pycparser/"&gt;pycparser&lt;/a&gt; and a little python scripting and you could generate 90% of the &lt;code&gt;ltrace&lt;/code&gt; configuration.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-2513181416376962049?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/J0VEhmX-oAw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/2513181416376962049/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/05/ltrace-pthreads.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/2513181416376962049?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/2513181416376962049?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/J0VEhmX-oAw/ltrace-pthreads.html" title="ltrace + pthreads" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/05/ltrace-pthreads.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMNRn8zfyp7ImA9WxFWEEw.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-7750199709197090057</id><published>2010-05-27T21:47:00.004-05:00</published><updated>2010-05-27T22:31:37.187-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-27T22:31:37.187-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="shop" /><title>cyclone update</title><content type="html">I re-read &lt;a href="http://davegoodell.blogspot.com/2010/04/dust-collector-installation.html"&gt;my recent post&lt;/a&gt; on my new dust collector recently and realized that I only wrote down about half of what I had in mind.&lt;br /&gt;&lt;br /&gt;I only mentioned the Oneida system in comparison, but I should point out that I did look at a few other big names.  I have a Penn State mini lathe, that I am generally happy with (post a comment if you want to hear my full opinion on it).  So I did consider the &lt;a href="http://www.pennstateind.com/store/cyclone-dust-collectors.html"&gt;PSI cyclones&lt;/a&gt;, in particular because they had a very attractive price.  However, at the time they didn't have much in the way of technical detail.  Also, the inlet size was 7 inches, which always concerned me when planning a 6-inch system.  My understanding of air engineering is pretty weak, but a 7-inch pipe has 36% more area than a 6-inch pipe.  So I think there's some translation needed when interpreting the CFM vs. static pressure loss plot for a 6-inch system.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://jdstools.com/dustcollection.aspx"&gt;JDS machines&lt;/a&gt; seemed decent enough, but just too pricey for the same level of power.&lt;br /&gt;&lt;br /&gt;And finally, a status update:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the filter clean-out box has been constructed and installed&lt;br /&gt;&lt;/li&gt;&lt;li&gt;the filter stack is attached, reusing the gasket from one of the filters between the clean-out and the stack&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ducting is about half finished, including the transition from the cyclone to the main ceiling duct, and the vertical stack leading to the table saw&lt;/li&gt;&lt;li&gt;tool hoods still need to be constructed for all the tools (table saw, lathe, sander, drill press, plus a floor sweep)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Also, if you want a Clearvue cyclone of your own, you are too late (for now).  &lt;a href="http://www.clearvuecyclones.com/"&gt;The website&lt;/a&gt; currently has an announcement that they are trying to sell the business so that the main owner can retire.  They've ceased sales for the time being.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-7750199709197090057?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/vbDmV7g0DSE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/7750199709197090057/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/05/cyclone-update.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/7750199709197090057?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/7750199709197090057?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/vbDmV7g0DSE/cyclone-update.html" title="cyclone update" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/05/cyclone-update.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMNRn8zfyp7ImA9WxFWEEw.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-8570048372043264753</id><published>2010-04-25T21:44:00.003-05:00</published><updated>2010-05-27T22:31:37.187-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-27T22:31:37.187-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="shop" /><title>dust collector installation</title><content type="html">The past couple of months have been pretty busy because we've been putting together papers for the Fall conference season.  However, little by little I've been working on installing a new CV1800 &lt;a href="http://www.clearvuecyclones.com/"&gt;cyclone dust collector&lt;/a&gt; in my garage shop (pardon the noisy iPhone photo):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://goodell.smugmug.com/Other/SmugShots/-/837365711_uAheU-L.jpg"&gt;&lt;img style="cursor: pointer; width: 450px; height: 600px;" src="http://goodell.smugmug.com/Other/SmugShots/-/837365711_uAheU-L.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Powering this thing is a &lt;span style="font-style: italic;"&gt;serious&lt;/span&gt; 5 HP, US made, &lt;a href="http://www.electricmotorwarehouse.com/120554.htm"&gt;Leeson motor&lt;/a&gt;.  It also has &lt;span style="font-style: italic;"&gt;two&lt;/span&gt; large 9L300BL &lt;a href="http://www.wynnenv.com/cartridge_filters.htm"&gt;pleated cartridge filters&lt;/a&gt; from Wynn Environmental (approx. 3' tall x 1' diameter each).  The goal with this purchase is to have a dust collector that I basically can't outgrow at the hobbyist level.  I was having lots of trouble with wood dust, taking lots of the fun out of my hobby and worrying me about the long-term health issues.&lt;br /&gt;&lt;br /&gt;Once again, I have to thank my father-in-law for some help with the planning and assembly on this project.  He came over one Sunday and we assembled the bulk of the cyclone itself and roughed-in the electrical conduit feeding the cyclone.  During a second (shorter) visit later on, we hung 3 10-foot pieces of 6-inch diameter SDR-35 sewer pipe for use as ducting.&lt;br /&gt;&lt;br /&gt;Current status:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;electrical - &lt;span style="font-style: italic;"&gt;done&lt;/span&gt;&lt;/li&gt;&lt;li&gt;mounting bracket - &lt;span style="font-style: italic;"&gt;built and attached to wall&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;motor and impeller - &lt;span style="font-style: italic;"&gt;mounted&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;main cyclone body, blower housing, and transition - &lt;span style="font-style: italic;"&gt;assembled, hung, and leveled&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;trash can - &lt;span style="font-style: italic;"&gt;lid attached to cyclone, weather stripping under lid&lt;/span&gt;&lt;/li&gt;&lt;li&gt;filter stack - &lt;span style="font-style: italic;"&gt;assembled but not attached to cyclone&lt;/span&gt;&lt;/li&gt;&lt;li&gt;filter clean-out box - &lt;span style="font-style: italic;"&gt;to be built&lt;/span&gt;&lt;/li&gt;&lt;li&gt;ducting - &lt;span style="font-style: italic;"&gt;WIP&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;Today I ran my first actual power-on test.  I could only run it for a brief time (&lt; 30 s) because w/o any ducting or filters attached the motor will draw very high current and runs some risk of burning up.  It was much louder than I thought it would be, although it should be quieter with ducting and filters attached.  I'm only planning on running it when I would normally wear ear protection anyway, so this shouldn't be too big of a deal.  But if it's too loud for neighbors or others inside my house, I might need to look at some sort of muffling setup.&lt;br /&gt;&lt;br /&gt;I went with the Clearvue instead of some of the other options out there after much research and deliberation.  I went with it because I felt like it would deliver the best performance for a reasonable price and actually had the largest amount of trustworthy technical information available on the web.  The system is setup to work with 6" pipe throughout the system, simplifying design and purchasing decisions.  The Oneida product looked a little easier to assemble and very polished, but the website is short on details in some cases and more expensive for a roughly equivalent amount of power.  Also, &lt;a href="http://www.oneida-air.com/oneida_advantages/competitor_comparison_1.php"&gt;this comparison page&lt;/a&gt; was &lt;span style="font-style: italic;"&gt;way&lt;/span&gt; too aggressive and painted an inaccurate picture of the Clearvue.  Distorted information like that makes them look desperate, rather than letting a supposedly superior product stand for itself.  Also, the CV06 patent dispute makes them look like bullies, although I am not familiar with any specifics of the case.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;(FWIW, I've never seen an Oneida system in person, and I have no relationship with either company other than my sole purchase from Clearvue.  This is just my personal opinion as a consumer in the market for this kind of product.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The kit nature of the Clearvue meant a little bit more work, but it's been a fun project so far.  I need to wrap it up soon though so that my garage can return to normalcy and I can get to work on actual woodworking projects.  I also am planning on building an ambient air filtration device using a spare attic fan, some 1/2" plywood, and some other (rectangular) filters from Wynn Environmental.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-8570048372043264753?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/xU21uw3bmFg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/8570048372043264753/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/04/dust-collector-installation.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8570048372043264753?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8570048372043264753?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/xU21uw3bmFg/dust-collector-installation.html" title="dust collector installation" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/04/dust-collector-installation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQDQnY5eCp7ImA9WxFSFUs.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-60685268582352586</id><published>2010-04-18T00:01:00.003-05:00</published><updated>2010-04-18T00:26:13.820-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-18T00:26:13.820-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="travel" /><title>Midnight Plane to Georgia</title><content type="html">Well, not really midnight at all.  But I am packing for my ~11:45am flight to Georgia at around midnight tonight.  On Friday I found out that my co-authors on our &lt;a href="http://hal.inria.fr/docs/00/45/25/57/PDF/CAC10.pdf"&gt;paper&lt;/a&gt; at &lt;a href="http://www.ccs3.lanl.gov/cac2010/"&gt;CAC&lt;/a&gt; are stranded in Europe by the &lt;a href="http://www.reuters.com/article/idUSTRE63E1TM20100418"&gt;Icelandic volcanic ash&lt;/a&gt;.  I was not originally planning on attending and &lt;a href="http://runtime.bordeaux.inria.fr/smoreaud/"&gt;Stéphanie&lt;/a&gt; was going to present the paper.  But without anyone to present, I booked a flight on Friday and will be at CAC to present the paper instead.&lt;br /&gt;&lt;br /&gt;The next few days are going to be pretty busy, between travel, presentation, and finishing up papers for the &lt;a href="http://www.eurompi2010.org/call-for-papers/"&gt;EuroMPI deadline&lt;/a&gt; on Tuesday morning.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2795/4523834894_e18b4b51a0.jpg"&gt;&lt;img style="cursor: pointer; width: 500px; height: 389px;" src="http://farm3.static.flickr.com/2795/4523834894_e18b4b51a0.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;(photo from NASA Goddard via &lt;/span&gt;&lt;a style="font-style: italic;" href="http://www.flickr.com/photos/gsfc/4523834894/"&gt;Flickr&lt;/a&gt;&lt;span style="font-style: italic;"&gt;)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-60685268582352586?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/-XSmpInrZuw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/60685268582352586/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/04/midnight-plane-to-georgia.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/60685268582352586?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/60685268582352586?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/-XSmpInrZuw/midnight-plane-to-georgia.html" title="Midnight Plane to Georgia" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm3.static.flickr.com/2795/4523834894_e18b4b51a0_t.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/04/midnight-plane-to-georgia.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYARHs9fyp7ImA9WxBQEUo.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-4240928959409337518</id><published>2010-01-10T17:32:00.007-06:00</published><updated>2010-01-10T18:35:45.567-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-10T18:35:45.567-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="home improvement" /><title>Electrical Master Plan Phase 4 - Complete! (or the demise of mega-circuit)</title><content type="html">Today my father-in-law came over to help me with my &lt;a href="http://davegoodell.blogspot.com/2009/04/new-electrical-panel.html"&gt;electrical master plan&lt;/a&gt; and we had an extremely productive day.  We finally managed to break up the circuit known as "mega-circuit" into 4 total pieces:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The rear exterior outlets and garden shed (including motion sensor light).&lt;/li&gt;&lt;li&gt;The freezer receptacle in the northwest corner of the kitchen.&lt;/li&gt;&lt;li&gt;The front exterior lights.&lt;/li&gt;&lt;li&gt;The remainder of mega-circuit, which includes all of the living room, one kitchen receptacle on the west wall, one kitchen light fixture (over the table), and the front hall lights.&lt;/li&gt;&lt;/ul&gt;This circuit was problematic for three reasons:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It covered a broad area of the house, both spatially and logically.  Exterior lights and interior light should rarely affect each other, and a problem in the back yard shouldn't shut down the front hall light.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;There are one or more subtle and infrequent issues somewhere on this circuit that were causing the breaker to trip occasionally.  We currently suspect an issue somewhere in the exterior of the house (probably the front coach lamp line), but it's difficult to say for sure where it is.&lt;/li&gt;&lt;li&gt;The chest freezer was on this circuit.  The aforementioned problem typically happened when we were on vacation, jeopardizing all the frozen food in our freezer.&lt;/li&gt;&lt;/ol&gt;We ran a 14/3 wire in the crawlspace from the breaker box to the northwest corner of the house and used that to power the freezer receptacle and the back yard lights/receptacles.  It required some minor rewiring in the freezer receptacle and in one of the junction boxes of the crawlspace lights, but that was pretty easy.  The worst part about that was actually pulling and stapling the wire all the way across the house because working in the crawlspace is hard on your knees and back.  We lucked out that there was already a 14/2 wire running up from the crawlspace so that we didn't have to fish anything up to the box.&lt;br /&gt;&lt;br /&gt;The front exterior lighting required a different trick.  The garage interior lights (four fixtures) were three-way switched at the front and back of the garage.  The exterior lights all run into the box in the front of the garage as well, but are fed from a switched line (on mega-circuit) coming from elsewhere in the house.  This setup let us move the front exterior lights from mega-circuit to the garage light circuit by converting the garage light to a two-way switch, converting one of the travelers to a hot conductor, and then feeding that out to the remote switch before coming back to the exterior lights at the front of the garage.  This was awesome because we didn't have to pull any new wire to make it happen, it just required reworking a few of the connections in the three boxes.  Hopefully this is the last time (for a while anyway) that I'll need to mess around in the box by the front door, which is flimsy plastic and very crowded with a mix of 14AWG and 12AWG conductors.&lt;br /&gt;&lt;br /&gt;Phase 3 should hopefully be done in the next few weeks.  We have all the pipe, boxes, and receptacles for augmenting the electrical situation in the garage itself.  I even have a &lt;a href="http://www.leevalley.com/wood/page.aspx?c=1&amp;amp;p=44590&amp;amp;cat=1,43456,43465"&gt;radiant quartz heater from Lee Valley&lt;/a&gt; that we are going to install to take the edge off of the frigid Illinois winters.  Phase 2 (splitting and replacing the tandem breakers) will get done whenever I get around to it, so maybe never ;)&lt;br /&gt;&lt;br /&gt;It also sets me up for a new phase, phase 5, which is to add a circuit to support a new dust collector that I hope to buy and install this year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-4240928959409337518?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/vzjgDfGTQ0w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/4240928959409337518/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/01/electrical-master-plan-phase-4-complete.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/4240928959409337518?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/4240928959409337518?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/vzjgDfGTQ0w/electrical-master-plan-phase-4-complete.html" title="Electrical Master Plan Phase 4 - Complete! (or the demise of mega-circuit)" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/01/electrical-master-plan-phase-4-complete.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MAQXk6cSp7ImA9WxBRFk8.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-3445015724311968756</id><published>2010-01-03T17:16:00.003-06:00</published><updated>2010-01-04T11:17:20.719-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-04T11:17:20.719-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="woodturning" /><title>Santa's workshop 2009</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://goodell.smugmug.com/Hobbies/woodturning/DSC0140/756583718_sJ7SN-L.jpg"&gt;&lt;img style="cursor: pointer; width: 800px; height: 532px;" src="http://goodell.smugmug.com/Hobbies/woodturning/DSC0140/756583718_sJ7SN-L.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For Xmas 2008, I received a &lt;a href="http://www.pennstateind.com/store/TCLPRO.html"&gt;midi-lathe&lt;/a&gt;.  So for Xmas 2009 I used it to make several of my gifts to others.  In the photo above you can see two pens in Honduran rosewood and some mystery wood (from &lt;a href="http://www.woodcraft.com/Product/2001964/1752/Ball-Point-Pen-Kit--Classic-American--Woodcraft-Gold-Finish.aspx"&gt;the Woodcraft Classic American kit&lt;/a&gt;), a 4-in-1 screwdriver in maple (from &lt;a href="http://www.rockler.com/product.cfm?page=16413"&gt;the Rockler kit&lt;/a&gt;), a two screwdriver set in cocobolo, and a 6-inch pepper mill in walnut (from a &lt;a href="http://www.woodcraft.com/Product/2001159/2290/Pepper-Grinder-Kit--6.aspx"&gt;Woodcraft kit&lt;/a&gt;).  I also made a matching salt shaker for the walnut pepper mill, a 4-inch pepper mill and salt shaker combo in jobillo, and a pair of chrome wine stoppers in maple and European pear (from &lt;a href="http://www.woodcraft.com/Product/2004773/7590/Chrome-Bottle-Stopper.aspx"&gt;this Woodcraft kit&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;The screwdriver set is unique because it is probably the only &lt;a href="http://en.wikipedia.org/wiki/Cocobolo"&gt;cocobolo&lt;/a&gt; project I'll ever turn.  Many people experience varying levels of allergic reaction to the wood dust from cocobolo, and I'm no exception.  Luckily my allergies only result in a mild skin rash that fades after a day, but I don't need to take any risks for a hobby like this.  Plus allergic reactions like that usually increase in severity with repeated exposure.&lt;br /&gt;&lt;br /&gt;The shanks on the two screwdrivers are &lt;a href="http://www.leevalley.com/wood/page.aspx?c=2&amp;amp;p=32282&amp;amp;cat=1,43411,43417"&gt;6-inch screwdriver bits from Lee Valley&lt;/a&gt;.  For some reason, they only sell Phillips-head and square-head bits in that length, so the slotted end in the photo is actually the back end of a square drive bit that has been ground down on the bench grinder.  The copper ferrules come from a single 3/4" copper pipe coupling that I cut in half.  To clean up the rough-sawn edges and polish up the outside of the ferrules, I made a mandrel that fits in my scroll chuck.  I don't have a photo of it handy right now, so I'll just try to describe it.  It has a tenon whose diameter tapers from slightly smaller than the inner diameter of the ferrule to slightly larger at the headstock.  I cut an "X" in the end of the tenon with a handsaw, then tapped the rough ferrule on the tenon with a mallet, and wedged the tenon tight by hammering in a small Phillips head bit at the center of the "X".  Then I turned the edge smooth with a round nose scraper and sanded the outside of the ferrule with various grits of sandpaper to clean up the finish.&lt;br /&gt;&lt;br /&gt;Additional photos can be found &lt;a href="http://goodell.smugmug.com/Hobbies/woodturning/10387673_CeXfa#756583718_sJ7SN"&gt;on our smugmug page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If anyone wants more details on how I turned any of these items, please let me know in the comments.  I'm happy to elaborate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-3445015724311968756?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/ipHv1ISfZPA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/3445015724311968756/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/01/santas-workshop-2009.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/3445015724311968756?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/3445015724311968756?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/ipHv1ISfZPA/santas-workshop-2009.html" title="Santa's workshop 2009" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/01/santas-workshop-2009.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIESXw4eCp7ImA9WxBRFUs.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-5867224874026556213</id><published>2010-01-03T16:51:00.003-06:00</published><updated>2010-01-03T17:15:08.230-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-03T17:15:08.230-06:00</app:edited><title>Samsung DLP and the "white dots" issue</title><content type="html">When Heather and I got married back in October 2006, some of our friends gave us a very generous wedding gift: a Samsung 46-inch DLP high-definition television.  We use it pretty much every day that we are at home (it's even on in the background while I write this post).  Unfortunately, early October the TV started having a problem.  It developed a small white dot in the upper left hand part of the screen.  Then a second dot, and a third, and so on.  Over the course of the following two months the TV screen developed dots on a substantial fraction of the screen, as you can see from the picture below:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://goodell.smugmug.com/Other/random-photos/DSC0118/756620742_6k8pu-M.jpg"&gt;&lt;img style="cursor: pointer; width: 600px; height: 399px;" src="http://goodell.smugmug.com/Other/random-photos/DSC0118/756620742_6k8pu-M.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Googling turned up &lt;a href="http://www.avsforum.com/avs-vb/showthread.php?t=1107926"&gt;this forum thread&lt;/a&gt;, which basically said that this was not an uncommon issue with Samsung DLPs of this era.  Unfortunately, back in early October the latest update on the issue from Samsung was that this was a "normal" dead pixel issue, not any particular manufacturing defect, and that we would need to pay a repair shop to fix our out-of-warranty TV.  A call to Samsung's support line yielded the same story.  The forum thread suggested replacing the DLP chip yourself for about $150-200, and a few hours of figuring out how to actually perform the surgery on the TV.  I nearly went down this road in late October, but that time of year is the travel season for me.  So I punted until the end of November when all of my travel was finished.&lt;br /&gt;&lt;br /&gt;Well, come late November it turns out that Samsung came around and initiated a recall program for their DLP TVs with this issue.  &lt;a href="http://forums.cnet.com/5208-13973_102-0.html?messageID=3165821#3165821"&gt;A different forum&lt;/a&gt; explained the procedure, which was really simple.  Basically just call Samsung and tell them that you are having these symptoms, and they will send out a technician from a nearby authorized service center to replace the DLP chip at your house.&lt;br /&gt;&lt;br /&gt;So I called Samsung, told them my problem, and they said that someone would get in touch with me within a couple of days.  The ASC called me the next day to schedule an appointment.  We had to wait 4 or 5 days for them to get the part in, but otherwise it was painless.  The technician showed up at our house on time and replaced the part in about 30 minutes.  I watched for part of the time while he disassembled/reassembled the TV and I was glad that he was there to do it.  I'm pretty sure that I could have done it, but it would have been pretty nerve wracking and would have taken me a few hours at a minimum.&lt;br /&gt;&lt;br /&gt;Overall, I have to applaud Samsung for owning up to the problem and fixing it at no cost to us.  They could have been a little faster and proactive (I nearly replaced the part myself), but the eventual outcome was exactly what it should have been.  If things had gone differently, I might have sworn off Samsung products forever instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-5867224874026556213?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/YII66xxewIU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/5867224874026556213/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2010/01/samsung-dlp-and-white-dots-issue.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5867224874026556213?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5867224874026556213?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/YII66xxewIU/samsung-dlp-and-white-dots-issue.html" title="Samsung DLP and the &quot;white dots&quot; issue" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2010/01/samsung-dlp-and-white-dots-issue.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MBRn44cSp7ImA9WxBRFk8.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-5305248252754148132</id><published>2010-01-03T00:44:00.000-06:00</published><updated>2010-01-04T11:17:37.039-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-04T11:17:37.039-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MPI" /><title>MPI_C_BOOL officially 1 byte in external32 representation</title><content type="html">A very minor announcement, the errata ticket for the size of MPI_C_BOOL in the external32 representation has been passed:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://svn.mpi-forum.org/trac/mpi-forum-web/ticket/171"&gt;https://svn.mpi-forum.org/trac/mpi-forum-web/ticket/171&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-5305248252754148132?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/NlAEtxH7jAk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/5305248252754148132/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/12/mpicbool-officially-1-byte-in.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5305248252754148132?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5305248252754148132?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/NlAEtxH7jAk/mpicbool-officially-1-byte-in.html" title="MPI_C_BOOL officially 1 byte in external32 representation" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/12/mpicbool-officially-1-byte-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8ERnY_fCp7ImA9WxNREUo.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-8649906968328457451</id><published>2009-09-04T14:52:00.007-05:00</published><updated>2009-09-05T13:20:07.844-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-05T13:20:07.844-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MPI" /><title>MPI-2.2 Is Now Official</title><content type="html">Earlier today (~11am GMT+3) the MPI Forum ratified the final PDF of the MPI Standard Version 2.2.  Other than a "No" vote from NEC the vote was unanimous in favor of accepting it.  &lt;a href="http://davegoodell.blogspot.com/2009/08/off-to-helsinki.html"&gt;As I mentioned before&lt;/a&gt; this version of the MPI Standard contains many clarifications and corrections as well as several new features.  The Change-Log (Annex B) contains a concise list of the relevant functionality changes.&lt;br /&gt;&lt;br /&gt;Bill Gropp (the MPI-2.2 chair) is currently out of internet range, so the official document isn't yet posted on &lt;a href="http://www.mpi-forum.org/docs/"&gt;the normal MPI Documents website&lt;/a&gt;.  In the mean time I've posted an &lt;a href="http://www.mcs.anl.gov/%7Egoodell/mpi22-report-unofficial.pdf"&gt;unofficial version here&lt;/a&gt; that you can download.  I imagine that the official document should be up by Monday.&lt;br /&gt;&lt;br /&gt;(&lt;span style="font-weight: bold;"&gt;Update (2009-09-05):&lt;/span&gt; The official MPI-2.2 document &lt;a href="http://www.mpi-forum.org/docs/mpi-2.2/mpi22-report.pdf"&gt;has been posted&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;MPICH2 should support these new clarifications and features in a release before the end of October (possibly sooner).  All but one of them (&lt;a href="https://svn.mpi-forum.org/trac/mpi-forum-web/ticket/33"&gt;ticket #33&lt;/a&gt;, the &lt;code&gt;MPI_Dist_graph_*&lt;/code&gt; functions) are implemented already on the SVN trunk if you are so inclined to play with MPI-2.2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-8649906968328457451?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/FRWIsmjgfDA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/8649906968328457451/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/09/mpi-22-is-now-official.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8649906968328457451?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8649906968328457451?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/FRWIsmjgfDA/mpi-22-is-now-official.html" title="MPI-2.2 Is Now Official" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/09/mpi-22-is-now-official.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkAHQ3kzeCp7ImA9WxNSFkU.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-5268837979059228646</id><published>2009-08-30T20:42:00.010-05:00</published><updated>2009-08-30T21:12:12.780-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-30T21:12:12.780-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="travel" /><category scheme="http://www.blogger.com/atom/ns#" term="MPI" /><title>Off To Helsinki</title><content type="html">Tomorrow I'm headed to Helsinki, Finland for a couple of weeks to attend the next MPI Forum meeting and &lt;a href="http://www.csc.fi/english/pages/pvmmpi09/welcome"&gt;EuroPVM/MPI 2009&lt;/a&gt;.  Although I'm unsure how productive the Forum meeting will be because many participants cannot attend this particular meeting, it should be a noteworthy meeting.  Barring any unforeseen problems we should ratify the new version of the MPI Standard, MPI-2.2.  This version of the document corrects many problems with the 2.1 Standard and adds several new features.  I could list them all here but Torsten has done a pretty good job of it already, &lt;a href="http://www.unixer.de/blog/index.php/2009/07/30/the-mpi-standard-mpi-22-is-fixed-now/"&gt;so I'll send you over to his post on the matter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Most of my MPI Forum work since the 2.1 effort ended has been on &lt;a href="https://svn.mpi-forum.org/trac/mpi-forum-web/ticket/18"&gt;ticket #18&lt;/a&gt;, which adds predefined named MPI datatypes for many C99 types like &lt;code&gt;int32_t&lt;/code&gt;, &lt;code&gt;_Bool&lt;/code&gt;, and &lt;code&gt;double _Complex&lt;/code&gt;. The lesson to be learned from this ticket is to always separate sufficiently separable changes, even if they are very related.  There were several points at which this ticket was nearly derailed and postponed until MPI-3.0.  The voting process used by the MPI Forum has only a single path by which tickets can make it into the Standard but many ways they can be removed from consideration.  Everything is fine with the ticket now, but if I had separated it into the three logically distinct changes that it makes (fixed-width integers, C99 complex types, and MPI_Aint/Offset types) there would have been a better chance of getting something rather than nothing in for MPI-2.2.&lt;br /&gt;&lt;br /&gt;My understanding is that Rolf will be printing up hardbound copies of the MPI-2.2 standard for purchase at SC09, much like &lt;a href="http://www.amazon.com/MPI-Message-Passing-Interface-Standard-Version/dp/B001VL99CW"&gt;he did with the MPI-2.1 standard&lt;/a&gt;.  It makes for a handy reference when debating standardization issues or implementing the Standard, so I'm planning on buying a copy.  It's also one of the few dead-tree publications to actually have my name in it somewhere, so that doesn't hurt either ;)&lt;br /&gt;&lt;br /&gt;EuroPVM/MPI 2009 should also be enjoyable, since it is a good opportunity to get together with others in the fairly small world of MPI implementation development.  I have a paper there (together with several other authors) entitled "MPI on a Million Processors" that explores scalability issues inherent in the MPI Standard.  I'll post a copy online somewhere after the conference.&lt;br /&gt;&lt;br /&gt;If I feel especially motivated I might post some updates and photos from the trip here.  We'll see how busy I am at the conferences and how bad the jet lag hits me...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-5268837979059228646?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/jxIz_TfuPsA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/5268837979059228646/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/08/off-to-helsinki.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5268837979059228646?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5268837979059228646?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/jxIz_TfuPsA/off-to-helsinki.html" title="Off To Helsinki" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/08/off-to-helsinki.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcAR3k8cCp7ImA9WxJUF0U.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-8938536698303484280</id><published>2009-07-15T07:45:00.012-05:00</published><updated>2009-07-16T17:24:06.778-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-16T17:24:06.778-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><title>-fstack-protector + valgrind ==&gt; stack array overflow debugging?</title><content type="html">&lt;h3&gt;stack array overflow background&lt;/h3&gt;&lt;br /&gt;I've recently been playing with valgrind to help find/debug stack overflow bugs in MPICH2.  That is, places where someone made a programming mistake and scribbled past the end of an array that lives on the stack, such as in &lt;a href="https://trac.mcs.anl.gov/projects/mpich2/ticket/719"&gt;this MPICH2 ticket&lt;/a&gt; (and &lt;a href="https://trac.mcs.anl.gov/projects/mpich2/changeset/4966"&gt;associated fix&lt;/a&gt;).  I'm not really concerned about finding malicious buffer-overflow attacks in this post, more just the general program bugs from stack array overflows.&lt;br /&gt;&lt;br /&gt;Of course, valgrind won't normally detect these sorts of errors, because whenever the stack pointer is moved down (that is, the stack grows) everything between the old SP position and the new SP position is marked as addressable.  This is entirely reasonable, since this memory is actually addressable and it means that valgrind works on code that doesn't perfectly follow a particular calling convention, such as that generated by an experimental/broken compiler or from hand-written assembly.&lt;br /&gt;&lt;br /&gt;In case you don't feel like trying to grok the changes I referenced above, here's a simple program that has a similar problem that should illustrate what's going on.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;1 static int foo(void)&lt;br /&gt;2 {&lt;br /&gt;3     int a = 1;&lt;br /&gt;4     char b[32];&lt;br /&gt;5&lt;br /&gt;6     printf("before memset\n");&lt;br /&gt;7     memset(b, 0, 64); /* stomps the stack */&lt;br /&gt;8     printf("after memset\n");&lt;br /&gt;9&lt;br /&gt;10     return 0;&lt;br /&gt;11 }&lt;br /&gt;12&lt;br /&gt;13 int main(int argc, char **argv)&lt;br /&gt;14 {&lt;br /&gt;15     int x;&lt;br /&gt;16&lt;br /&gt;17     printf("before foo()\n");&lt;br /&gt;18     x = foo();&lt;br /&gt;19     printf("after foo()\n");&lt;br /&gt;20     return 0;&lt;br /&gt;21 }&lt;br /&gt;22&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Line 7 is the line that causes the badness here.  Most of you at home know why immediately, but I'll write it out just in case so that the main topic of this post is clear to everyone.  When main() calls foo(), the stack ends up looking like this (as of line 5).  Earlier lines in the diagram are higher addresses (the stack grows down on most architectures and operating systems).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;- last address in caller's stack frame&lt;br /&gt;- any arguments in reverse order (none in the case of foo)&lt;br /&gt;- return address                       &lt;-- frame pointer register (EBP) points here&lt;br /&gt;- old frame pointer value&lt;br /&gt;- storage for "int a" (4 bytes)&lt;br /&gt;- storage for "char b[32]" (32 bytes)  &lt;-- ESP points here&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is an x86 cdecl calling-convention view of the world, but besides possibly the frame pointer and the int size, things will basically look this way on most systems.  The important thing to observe here is that the storage for b actually has a lower address than both the storage for a and the storage for the return address for the function.  The problem with our sample code is that the memset operation on line 7 sets all of b to zero (expected), but keeps on going and clobbers the values for a, old frame pointer, the return address, and probably part of the caller's stack frame.&lt;br /&gt;&lt;br /&gt;When the RET instruction at line 10 is executed, the processor will pop the return address off of the stack and jump there.  In our case, that value isn't correct anymore, it's 0 instead and will result in a general protection fault.  And of course, if we had logic in foo() that depended on the value of a making sense then we might have had some other very strange behavior manifest instead.  And the worst part is that valgrind won't catch this for you.  You'll get the crash just the same as if you had run int outside of valgrind.  In a large-ish code base this can be tricky to track down sometimes, and having a tool catch the problem for you would be really handy.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;enter the MPICH2 Stack Guard macros&lt;/h3&gt;&lt;br /&gt;So, I've implemented some macros that can help catch this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define MPIU_SG_GUARD_VALUE_ (0xdeadbeef)&lt;br /&gt;#define MPIU_SG_FIRST_DECL int MPIU_SG_upper_guard = MPIU_SG_GUARD_VALUE_&lt;br /&gt;#define MPIU_SG_LAST_DECL \&lt;br /&gt;    int MPIU_SG_upper_guard_blk_handle; \&lt;br /&gt;    do { \&lt;br /&gt;        MPIU_SG_upper_guard_blk_handle = VALGRIND_CREATE_BLOCK(&amp;MPIU_SG_upper_guard, sizeof(MPIU_SG_upper_guard), "stack guard variable"); \&lt;br /&gt;        VALGRIND_MAKE_MEM_NOACCESS(&amp;MPIU_SG_upper_guard, sizeof(MPIU_SG_upper_guard)); \&lt;br /&gt;    } while (0)&lt;br /&gt;#define MPIU_SG_AT_RETURN() \&lt;br /&gt;    do { \&lt;br /&gt;        VALGRIND_MAKE_MEM_DEFINED(&amp;MPIU_SG_upper_guard, sizeof(MPIU_SG_upper_guard)); \&lt;br /&gt;        VALGRIND_DISCARD(MPIU_SG_upper_guard_blk_handle); \&lt;br /&gt;        MPIU_Assert(MPIU_SG_upper_guard == MPIU_SG_GUARD_VALUE_); \&lt;br /&gt;    } while (0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And here's an updated version of our foo() function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  1 static int foo(void)&lt;br /&gt;  2 {&lt;br /&gt;  3     MPIU_SG_FIRST_DECL;&lt;br /&gt;  4     int a = 1;&lt;br /&gt;  5     char b[32];&lt;br /&gt;  6     MPIU_SG_LAST_DECL;&lt;br /&gt;  7 &lt;br /&gt;  8     printf("before memset\n");&lt;br /&gt;  9     memset(b, 0, 64); /* stomps the stack */&lt;br /&gt; 10     printf("after memset\n");&lt;br /&gt; 11    &lt;br /&gt; 12     MPIU_SG_AT_RETURN();&lt;br /&gt; 13     return 0;&lt;br /&gt; 14 }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If someone overflows the b array by a sufficient amount, they will end up scribbling over the guard variable.  The various &lt;code&gt;VALGRIND_&lt;/code&gt; macros tell valgrind that the guard variable shouldn't be touched during the main body of the function.  Furthermore, we check the value via the &lt;code&gt;MPIU_Assert&lt;/code&gt; to see if it has been scribbled over by some bad code in the function so that we get failures even when we aren't running under valgrind.  So running this updated code under valgrind will give you a warning message indicating the line where the bad access occurred, rather than having to try to work backwards from the GPF that you get at return time or from any wonky behavior that was predicated on a corrupted value of &lt;code&gt;a&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;% valgrind -q ./foo&lt;br /&gt;before foo()&lt;br /&gt;before memset&lt;br /&gt;==49581== Invalid write of size 4&lt;br /&gt;==49581==    at 0x1E2B: foo (foo.c:36)&lt;br /&gt;==49581==    by 0x1F68: main (foo.c:48)&lt;br /&gt;==49581==  Address 0xbfffedd4 is 0 bytes inside a stack guard variable of size 4 client-defined&lt;br /&gt;==49581==    at 0x1DB2: foo (foo.c:33)&lt;br /&gt;==49581==    by 0x1F68: main (foo.c:48)&lt;br /&gt;after memset&lt;br /&gt;Assertion failed: (MPIU_SG_upper_guard == (0xdeadbeef)), function foo, file foo.c, line 39.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This technique is a little too ugly and cumbersome for blanket use in the code base.  However if you are poking around with a debugger or &lt;code&gt;printf()&lt;/code&gt; and you see memory corruption that valgrind can't seem to find, you might be able to insert these macros into any suspicious functions and find your bug rather quickly.  It also will only flag an error when the array access overflows far enough to clobber the guard.  In our example valgrind won't flag an overflow of 4 bytes or less because it will corrupt &lt;code&gt;a&lt;/code&gt; but not the guard variable.  Intermediate guards can help with this if you have strong suspicions about a particular function, but it takes a slightly unwieldy tool and makes it even more cumbersome.&lt;br /&gt;&lt;br /&gt;I can't possibly be the first person to do this, but I haven't seen it anywhere else yet to cite as another example of this.  Please add links in the comments if you know of of something/someone else that does this.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;stack smashing protection&lt;/h3&gt;&lt;br /&gt;Various techniques have been developed over the years to protect against malicious buffer-overflow attacks, which are very similar to this type of bug.  One of them is the &lt;a href="http://en.wikipedia.org/wiki/Stack_protection#GCC_Stack-Smashing_Protector_.28ProPolice.29"&gt;Stack Smashing Protector for GCC&lt;/a&gt; (the &lt;code&gt;-fstack-protector&lt;/code&gt; option).  This technique basically involves a modification to the compiler to insert a guard variable similar to the one above on any function that allocates an array on the stack.  Then prior to any return from the function the guard value is checked to ensure that it hasn't been modified.  This prevents malicious code from overwriting the return address and hijacking execution on function return, which is the standard approach for a buffer-overflow attack.&lt;br /&gt;&lt;br /&gt;All you have to do to get this protection from a modern version of GCC is to compile with &lt;code&gt;-fstack-protector&lt;/code&gt;.  I believe that there is a slight performance penalty associated with enabling this feature, but it's probably a good trade-off for network-facing software.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;valgrind and -fstack-protector: two great flavors that could taste better together&lt;/h3&gt;&lt;br /&gt;Of course, everything earlier was just setup for the main point of this post.  In my mind these two techniques are begging to be combined in some way.  I'm not familiar enough yet with the details of the &lt;code&gt;-fstack-protector&lt;/code&gt; implementation to know how technically feasible/difficult this is.  I know that the exact mechanics of the guard depend heavily on OS support and the architecture's capabilities.  For example, the availability of thread-local-storage (TLS) changes the implementation.  On top of that, I'm not familiar enough with any of the debugging symbol information (like &lt;a href="http://en.wikipedia.org/wiki/DWARF"&gt;DWARF&lt;/a&gt;) to know how suitable it is for annotating information about the guard variable.  Maybe this would be a good opportunity to play with LLVM a bit more, since I have used that a little in the past.&lt;br /&gt;&lt;br /&gt;Anyway, if someone (maybe me) could work out the technical issues, this could be a really handy tool for debugging in some situations.  If you suspected stack corruption issues at all, you would just need to recompile with &lt;code&gt;-fstack-protector&lt;/code&gt; (if not already so-compiled) and maybe the currently-non-existent &lt;code&gt;-fstack-protector-annotate-for-valgrind&lt;/code&gt; and then run valgrind to help locate your bug.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Updated (2009-06-16):&lt;/b&gt;&lt;br /&gt;There's a relevant GCC feature that I just learned about called &lt;a href="http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html"&gt;_FORTIFY_SOURCE&lt;/a&gt;.  I haven't had the time yet to check whether or not this would have caught our actual MPICH2 bug (I don't think it would have, unfortunately), but it definitely catches the error in the sample code above.  As written, the it catches at compile time even, which is far better than waiting until you experience a bug to run valgrind on it, although the sample code is admittedly trivial.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-8938536698303484280?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/Lo8q1IDu0ic" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/8938536698303484280/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/07/fstack-protector-valgrind-stack-array.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8938536698303484280?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/8938536698303484280?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/Lo8q1IDu0ic/fstack-protector-valgrind-stack-array.html" title="-fstack-protector + valgrind ==&gt; stack array overflow debugging?" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/07/fstack-protector-valgrind-stack-array.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQGR3k6eSp7ImA9WxJVEk8.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-2477519829726685908</id><published>2009-06-28T16:26:00.011-05:00</published><updated>2009-06-28T17:15:26.711-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-28T17:15:26.711-05:00</app:edited><title>handy "git log" options and the nowrap script</title><content type="html">I recently settled on two sets of options to "git log" that I greatly prefer over the defaults.  The first is &lt;code&gt;--pretty=tformat:"%C(yellow)%h%Creset %Cblue%aN%Creset %Cred%d%Creset %s"&lt;/code&gt;.  This is basically an improved version of &lt;code&gt;--pretty=oneline&lt;/code&gt; that gives output that looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://goodell-content.s3.amazonaws.com/images/blog/new_git_log_tformat.png" /&gt;&lt;br /&gt;&lt;br /&gt;I won't go into the details of that format string, the &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-log.html"&gt;git-log(1)&lt;/a&gt; manpage ought to be sufficient to pick it apart.  If something seems confusing about it, contact me and I can explain it further.  You can put that in your &lt;code&gt;~/.gitconfig&lt;/code&gt; file as &lt;code&gt;format.pretty=tformat:"..."&lt;/code&gt; to make git log use that style by default.&lt;br /&gt;&lt;br /&gt;That, combined with another cool feature of git makes for the other git-log style that I find myself using often.  &lt;code&gt;git log --graph --decorate --abbrev-commit --all --pretty="tformat:.../oneline"&lt;/code&gt; is the other cool command.  It looks like this:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://goodell-content.s3.amazonaws.com/images/blog/git_graph_screenshot.png" /&gt;&lt;br /&gt;&lt;br /&gt;It provides a pretty good approximation of the commit trees that programs like GitX and gitk show you, only on the command line instead.  Obviously the &lt;code&gt;--pretty&lt;/code&gt; part above can be whatever you want, although I usually prefer either "&lt;code&gt;oneline&lt;/code&gt;" or the custom tformat string mentioned earlier.  I also alias it in my &lt;code&gt;.gitconfig&lt;/code&gt; to "&lt;code&gt;git graph&lt;/code&gt;", so that I don't have to type all that in.&lt;br /&gt;&lt;br /&gt;Since I work almost exclusively with git-svn repositories where the short subject with a long message style of commit messages isn't the standard practice, both of these single line formats can be hard to read.  Many of the commit subjects from SVN will wrap, even in a fairly wide (230 character) terminal.  To work around this problem, especially when viewing graph output, I've written a small perl script that will truncate output at the width of the window (or any other specified width).  I know that you are thinking "why not just use &lt;code&gt;cut -c1-$COLUMNS&lt;/code&gt;?" but that won't work very well with output that has color escape sequences in it.  The program is called "&lt;code&gt;nowrap&lt;/code&gt;" and is available &lt;a href="http://github.com/goodell/nowrap/tree/master"&gt;here on github&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;By comparison, here's pretty much the same git graph command as before but with wrapping disabled:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://goodell-content.s3.amazonaws.com/images/blog/nowrap_comparison.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-2477519829726685908?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/HJZYiFdKKg0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/2477519829726685908/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/06/handy-git-log-options-and-nowrap-script.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/2477519829726685908?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/2477519829726685908?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/HJZYiFdKKg0/handy-git-log-options-and-nowrap-script.html" title="handy &quot;git log&quot; options and the nowrap script" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/06/handy-git-log-options-and-nowrap-script.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEBSHs-eyp7ImA9WxFWEEw.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-4946970546187501513</id><published>2009-05-26T21:54:00.011-05:00</published><updated>2010-05-27T22:34:19.553-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-27T22:34:19.553-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="osx" /><title>otx: Objective-C disassembly</title><content type="html">Let's say that you have a closed-source &lt;a href="http://en.wikipedia.org/wiki/Objective-C"&gt;Objective-C&lt;/a&gt; program on your Mac that needs a minor modification.  Maybe the company is delayed in sending you the license file that you purchased, or the company went out of business and there's no way that the code will ever get fixed.&lt;br /&gt;&lt;br /&gt;I'm not very sophisticated at this sort of thing, but I've twiddled a few bits here and there in the past.  Usually simple stuff like replacing a set of instructions with no-ops or altering a constant in a move or arithmetic instruction.  However, it was always in regular C programs, so the standard GNU binutils like &lt;code&gt;nm&lt;/code&gt; and &lt;code&gt;objdump&lt;/code&gt;, together with &lt;code&gt;xxd&lt;/code&gt;, have been sufficient to get an idea of what was going on in the program.  Unfortunately, these tools aren't sufficient by themselves for an Objective-C program.&lt;br /&gt;&lt;br /&gt;Here is an excerpt from the normal &lt;code&gt;objdump -d&lt;/code&gt; from the binary that lives inside of &lt;a href="http://gitx.frim.nl/"&gt;GitX&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;4018:       89 74 24 04             mov    %esi,0x4(%esp)&lt;br /&gt;401c:       89 04 24                mov    %eax,(%esp)&lt;br /&gt;401f:       e8 88 21 02 00          call   261ac &lt;.objc_class_name_PBNSURLPathUserDefaultsTransfomer+0x3b0c&gt;&lt;br /&gt;4024:       83 c4 20                add    $0x20,%esp&lt;br /&gt;4027:       31 c0                   xor    %eax,%eax&lt;br /&gt;4029:       5b                      pop    %ebx&lt;br /&gt;402a:       5e                      pop    %esi&lt;br /&gt;402b:       c9                      leave&lt;br /&gt;402c:       c3                      ret&lt;br /&gt;402d:       55                      push   %ebp&lt;br /&gt;402e:       89 e5                   mov    %esp,%ebp&lt;br /&gt;4030:       83 ec 38                sub    $0x38,%esp&lt;br /&gt;4033:       89 5d f4                mov    %ebx,0xfffffff4(%ebp)&lt;br /&gt;4036:       89 75 f8                mov    %esi,0xfffffff8(%ebp)&lt;br /&gt;4039:       8b 75 10                mov    0x10(%ebp),%esi&lt;br /&gt;403c:       89 7d fc                mov    %edi,0xfffffffc(%ebp)&lt;br /&gt;403f:       8b 3d 30 1b 02 00       mov    0x21b30,%edi&lt;br /&gt;4045:       c7 44 24 10 00 00 00    movl   $0x0,0x10(%esp)&lt;br /&gt;&lt;/pre&gt;Here is the same range of bytes interpreted by &lt;a href="http://otx.osxninja.com/"&gt;otx&lt;/a&gt; (&lt;code&gt;otx -e &lt; /Applications/GitX.app/Contents/MacOS/GitX&lt;/code&gt;): &lt;pre&gt;  +100  00004018  89742404                movl        %esi,0x04(%esp)&lt;br /&gt;+104  0000401c  890424                  movl        %eax,(%esp)&lt;br /&gt;+107  0000401f  e888210200              calll       0x000261ac                    _objc_assign_strongCast&lt;br /&gt;+112  00004024  83c420                  addl        $0x20,%esp&lt;br /&gt;+115  00004027  31c0                    xorl        %eax,%eax&lt;br /&gt;+117  00004029  5b                      popl        %ebx&lt;br /&gt;+118  0000402a  5e                      popl        %esi&lt;br /&gt;+119  0000402b  c9                      leave&lt;br /&gt;+120  0000402c  c3                      ret&lt;br /&gt;&lt;br /&gt;+(BOOL)[PBGitRepository isBareRepository:]&lt;br /&gt;+0  0000402d  55                      pushl       %ebp&lt;br /&gt;+1  0000402e  89e5                    movl        %esp,%ebp&lt;br /&gt;+3  00004030  83ec38                  subl        $0x38,%esp&lt;br /&gt;+6  00004033  895df4                  movl        %ebx,0xf4(%ebp)&lt;br /&gt;+9  00004036  8975f8                  movl        %esi,0xf8(%ebp)&lt;br /&gt;+12  00004039  8b7510                  movl        0x10(%ebp),%esi&lt;br /&gt;+15  0000403c  897dfc                  movl        %edi,0xfc(%ebp)&lt;br /&gt;+18  0000403f  8b3d301b0200            movl        0x00021b30,%edi               PBEasyPipe&lt;br /&gt;+24  00004045  c744241000000000        movl        $0x00000000,0x10(%esp)&lt;br /&gt;&lt;/pre&gt;As you can see, it makes a big difference in terms of readability.  otx decodes the function names and boundaries from the text and decodes the function calls whenever possible.  The dynamic dispatch makes it tricky to read a raw disassembly otherwise.&lt;br /&gt;&lt;br /&gt;So you just take the byte offsets of the instructions you want to replace and write the appropriate opcodes in place of them with your hex editor.   You can write up a little bit of assembly and assemble it with &lt;code&gt;as&lt;/code&gt; and then disassemble that if you don't know the opcodes for the replacement instructions off the top of your head.   On x86/x86_64, &lt;code&gt;0x90&lt;/code&gt; is the opcode for nop, which is the most common instruction that I use as filler.  The filler is pretty important, since you can't easily change the byte offsets of any of the other instructions or else your jump locations and possibly your variable references will be wrong.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-4946970546187501513?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/3kNwwDkNUDw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/4946970546187501513/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/05/otx-objective-c-disassembly.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/4946970546187501513?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/4946970546187501513?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/3kNwwDkNUDw/otx-objective-c-disassembly.html" title="otx: Objective-C disassembly" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/05/otx-objective-c-disassembly.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04MQn04cCp7ImA9WxJRF00.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-5596303603186935854</id><published>2009-05-18T22:58:00.003-05:00</published><updated>2009-05-18T23:06:23.338-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-18T23:06:23.338-05:00</app:edited><title>minor tab sweep</title><content type="html">A little while back I posted about some &lt;a href="http://davegoodell.blogspot.com/2009/04/fixing-corrupted-git-svn-commit-data.html"&gt;SVN permissions problems&lt;/a&gt; that we had at work.  While cleaning up my many open tabs today &lt;a href="http://blogs.open.collab.net/svn/2007/03/authz_and_anon_.html"&gt;I came across this page&lt;/a&gt; that I read when trying to figure out what was going on.  It pretty well describes what we ran in to, which is yet another one of the many lousy SVN shortcomings.  We basically went with the fourth solution as our fix.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-5596303603186935854?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/31KsXUl8j1M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/5596303603186935854/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/05/minor-tab-sweep.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5596303603186935854?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/5596303603186935854?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/31KsXUl8j1M/minor-tab-sweep.html" title="minor tab sweep" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/05/minor-tab-sweep.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QCRHY9fyp7ImA9WxJRF00.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-2395007232629674334</id><published>2009-05-18T22:02:00.011-05:00</published><updated>2009-05-18T22:56:05.867-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-18T22:56:05.867-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="env improvement" /><title>helpful options for less</title><content type="html">"less" the unix command, that is.  The default behavior for less isn't quite as good as it could be.  I use a case insensitive search (actually '&lt;a href="http://vimdoc.sourceforge.net/htmldoc/options.html#%27smartcase%27"&gt;smartcase&lt;/a&gt;') in vim, but less is case sensitive by default.  You can pass "-i" on the command line or once less is started to get smartcase-like behavior in searches.  Or you can put that in the $LESS variable in your .zshenv.  My .zshenv has the following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;export LESS='-R -i --quit-if-one-screen'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;From the less(1) manpage:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;       -F or --quit-if-one-screen&lt;br /&gt;              Causes less to automatically exit if the entire file  can  be  dis-&lt;br /&gt;              played on the first screen.&lt;br /&gt;...&lt;br /&gt;       -i or --ignore-case&lt;br /&gt;              Causes  searches  to  ignore case; that is, uppercase and lowercase&lt;br /&gt;              are considered identical.  This option is ignored if any  uppercase&lt;br /&gt;              letters  appear in the search pattern; in other words, if a pattern&lt;br /&gt;              contains uppercase letters, then that search does not ignore  case.&lt;br /&gt;...&lt;br /&gt;       -R or --RAW-CONTROL-CHARS&lt;br /&gt;              Like  -r,  but  tries  to keep track of the screen appearance where&lt;br /&gt;              possible.  This works only if the input consists of normal text and&lt;br /&gt;              possibly some ANSI "color" escape sequences, which are sequences of&lt;br /&gt;              the form:&lt;br /&gt;&lt;br /&gt;                   ESC [ ... m&lt;br /&gt;&lt;br /&gt;              where the "..." is zero or more characters other than "m".  For the&lt;br /&gt;              purpose  of keeping track of screen appearance, all control charac-&lt;br /&gt;              ters and all ANSI color escape sequences are assumed  to  not  move&lt;br /&gt;              the cursor.  You can make less think that characters other than "m"&lt;br /&gt;              can end ANSI color escape  sequences  by  setting  the  environment&lt;br /&gt;              variable LESSANSIENDCHARS to the list of characters which can end a&lt;br /&gt;              color escape sequence.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The other two options are primarily git related.  The "-R" option is so that the wonderful colored output from various git commands gets displayed properly.  The "--quit-if-one-screen" option prevents bits of short output from commands like "git log -1" from interrupting the normal flow of work.  On some terminals you might need to pass "-X" in order to prevent the "--quit-if-one-screen" and the terminal's alternate screen from hiding any output that takes up less than one screen.&lt;br /&gt;&lt;br /&gt;Also, to echo Andrew, never use "more", there's absolutely no point on any system where "less" is available.  Seriously, just don't do it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-2395007232629674334?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/lR4XO2AgNcw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/2395007232629674334/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/05/helpful-options-for-less.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/2395007232629674334?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/2395007232629674334?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/lR4XO2AgNcw/helpful-options-for-less.html" title="helpful options for less" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/05/helpful-options-for-less.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MHSHg9fyp7ImA9WxJREUU.&quot;"><id>tag:blogger.com,1999:blog-176695309595372156.post-1707979972093545679</id><published>2009-05-12T22:02:00.002-05:00</published><updated>2009-05-12T22:30:39.667-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-12T22:30:39.667-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="atomics" /><title>Open Portable Atomics v1.0.0 released</title><content type="html">We just released the first official release of the &lt;a href="https://trac.mcs.anl.gov/projects/openpa/"&gt;OpenPA project&lt;/a&gt;, v1.0.0.  If you ever are thinking about writing inline assembly to perform atomic operations (compare-and-swap, fetch-and-increment, etc), then think about using OPA instead.  It provides a consistent interface to primitive atomic operations via C functions and macros across multiple compilers and architectures.  We have a solid range of platforms at this point, but we intend to add more in the future and we are always willing to accept contributions if you have a particular platform you would like to support.&lt;br /&gt;&lt;br /&gt;You can download &lt;a href="https://trac.mcs.anl.gov/projects/openpa/attachment/wiki/Downloads/openpa-1.0.0.tar.gz"&gt;openpa-1.0.0 here&lt;/a&gt; if you are interested in playing around with it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/176695309595372156-1707979972093545679?l=davegoodell.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/davegoodellblog/~4/frT6Mwz0PVg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://davegoodell.blogspot.com/feeds/1707979972093545679/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://davegoodell.blogspot.com/2009/05/open-portable-atomics-v100-released.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/1707979972093545679?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/176695309595372156/posts/default/1707979972093545679?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/davegoodellblog/~3/frT6Mwz0PVg/open-portable-atomics-v100-released.html" title="Open Portable Atomics v1.0.0 released" /><author><name>Dave Goodell</name><uri>http://www.blogger.com/profile/01864891805231272561</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_FlF8nsVoqaE/SuH53WTdJEI/AAAAAAAAABY/2kMqkb7JMPI/s1600-R/9b31042a7ef1e2233c3492736b4187a3.png" /></author><thr:total>2</thr:total><feedburner:origLink>http://davegoodell.blogspot.com/2009/05/open-portable-atomics-v100-released.html</feedburner:origLink></entry></feed>

