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

<channel>
	<title>Evan Teran's Blog</title>
	<atom:link href="http://blog.codef00.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.codef00.com</link>
	<description>Just some thoughts from a computer geek</description>
	<lastBuildDate>Mon, 09 Aug 2010 21:44:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>How not to handle a bug report</title>
		<link>http://blog.codef00.com/2010/03/13/how-not-to-handle-a-bug-report/</link>
		<comments>http://blog.codef00.com/2010/03/13/how-not-to-handle-a-bug-report/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 04:43:47 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=63</guid>
		<description><![CDATA[I recently submitted a bug report to Qt software, the results were less than impressive. One thing I&#8217;d like to make clear though is that Qt is an amazing library that I would recommend to any c++ software developer, I &#8230; <a href="http://blog.codef00.com/2010/03/13/how-not-to-handle-a-bug-report/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently submitted a bug report to <a href="http://qt.nokia.com/" target="_blank">Qt software</a>, the results were less than impressive. One thing I&#8217;d like to make clear though is that Qt is an amazing library that I would recommend to any c++ software developer, I truly mean that. It is well designed, well documented and generally works as advertised. On top of all of this, it is portable! It really just gets better and better. Which is why I found the handling of my bug report so&#8230; underwhelming.</p>
<p><span id="more-63"></span>It all started with a compiler warning. I like to compile my gcc projects with:</p>
<pre>-ansi -pedantic -W -Wall
</pre>
<p>and I like my projects to compile with <strong>no warnings</strong>. My personal feelings on this subject are that if you cannot find a way to reconcile the warning, then odds are you don&#8217;t understand what it is trying to warn you about. Anyway, on to the issue at hand. I added a macro call of <a href="http://doc.trolltech.com/4.6/qtglobal.html#QT_REQUIRE_VERSION" target="_self">QT_REQUIRE_VERSION</a> to the main function in one of my projects, the goal of course is to give a run-time error if the program is run with a version of Qt that is too old, simple enough. Unfortunately, this caused a warning in my project which I found entirely unacceptable.</p>
<pre>main.cpp: In function 'int main(int, char**)':
main.cpp:8: warning: format not a string literal and no format arguments</pre>
<p>I&#8217;m sure that many of you can relate to the horror I felt after seeing this in my usually clean build. First I checked, then double checked that the usage of the macro was the cause. Yup, commenting out the simple one liner use of the macro made it go away. Did I use it right? well  the call basically looks like this:</p>
<pre>QT_REQUIRE_VERSION(argc, argv, "4.0.2")
</pre>
<p>Not much room for error there, and the only string parameter is passing a string literal. So what&#8217;s going on here? I figured it&#8217;s a pretty minor issue so I&#8217;d be patient. After waiting a while for someone to notice this, I finally decided to <a href="http://bugreports.qt.nokia.com/browse/QTBUG-8547" target="_self">submit a bug</a>. Two or so weeks went by then I finally saw that my bug had be resolved as &#8220;invalid&#8221;. Fine, my gut reaction was to check if I had misused the macro, so I&#8217;ll check out what they had to say.</p>
<blockquote><p>I believe the warning is due to there being no semicolon after the call  to QT_REQUIRE_VERSION.  Note that the warning message specifies line 8 –  the line after the QT_REQUIRE_VERSION call.  The QT_REQUIRE_VERSION  macro, like most macros, does not end with a semi-colon, so you have to  use one after calling it.</p></blockquote>
<p>I was thrilled that it was such a simple fix. How could I have been so dumb as to miss a semi-colon. An amateur mistake! So I thanked the bug assignee, mentioned that the docs didn&#8217;t have a semicolon and went on my way. Of course this wouldn&#8217;t be much of a post if things were that simple&#8230;</p>
<p>As you may have guessed the proposed solution had nearly zero effect on the presence of the warning. I have to say &#8220;nearly&#8221; there because it did change the line number it occurred on to be the line of the macro, instead of the line after. But the warning still remains, mocking me.</p>
<p>Let&#8217;s revisit the response I got (i&#8217;m adding emphasis).</p>
<blockquote><p>I <strong>believe</strong> the warning is due to there being no semicolon after the call   to QT_REQUIRE_VERSION&#8230;</p></blockquote>
<p>Ahh, I see, so he just guessed! I think it&#8217;s time for a basic rule of bug handling to be established.</p>
<p><strong>1.</strong> Actually test the bug and then test the solution before any resolution is given!</p>
<p>This may sound simple, but clearly it didn&#8217;t happen here. He did not test the issue or its solution, he simply looked at my example code and made a wild guess. It would have taken him all of 1 minute to copy and paste my code into a test.cpp file and compile it with the flags I gave to see that the warning would remain.</p>
<p>I looked for way to re-open the bug, but could not, so I <a href="http://bugreports.qt.nokia.com/browse/QTBUG-8967" target="_self">submitted a second one</a>. This time I made it clear that this was a followup to the other bug report and that I had added the semicolon, which did not help. If you are wondering how clear I was, here&#8217;s a quote from my bug report:</p>
<blockquote><p><strong>Note: I&#8217;ve added a semicolon as recommended by the previous bugs  resolution.</strong> Which did change the warning&#8217;s line number to 7 from 8.  But the warning still stands.</p></blockquote>
<p>Later that day I saw on my phone an email from the Qt bug tracker saying the status had changed. Less than 24 hours, that&#8217;s great turn around time, maybe I was in luck. Nope, not this time, the same assignee still didn&#8217;t do a good job <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> . He assigned it to someone in documentation with the following comment (remember my bug report was about a compile time warning, the documentation was a side issue).</p>
<blockquote><p>The problem was a missing semi-colon after the macro call, but that what  the doc example leads you to do.</p>
<p>The example in the docs should be updated to have a semi-colon after  the macro call, otherwise following the example produces code that fails  to compile and the compiler error message is not very helpful.</p></blockquote>
<p>Great! I&#8217;m glad we could get the documentation squared away, but how about fixing the actual bug I reported!</p>
<p><strong>2.</strong> Read the actual contents of the bug report. Don&#8217;t just glaze over it and assume you know what I meant. Read it.</p>
<p>I don&#8217;t think it is too much to ask that the assignee of the bug actually read the bug report before drawing conclusions. This was a complete disregard for the reported issue. At this point I was annoyed, so I decided to look into the issue myself. Here&#8217;s the macro in question:</p>
<pre>#define QT_REQUIRE_VERSION(argc, argv, str) { QString s = QString::fromLatin1(str);\
QString sq = QString::fromLatin1(qVersion()); \
if ((sq.section(QChar::fromLatin1('.'),0,0).toInt()&lt;&lt;16)+\
(sq.section(QChar::fromLatin1('.'),1,1).toInt()&lt;&lt;8)+\
sq.section(QChar::fromLatin1('.'),2,2).toInt()&lt;(s.section(QChar::fromLatin1('.'),0,0).toInt()&lt;&lt;16)+\
(s.section(QChar::fromLatin1('.'),1,1).toInt()&lt;&lt;8)+\
s.section(QChar::fromLatin1('.'),2,2).toInt()) { \
if (!qApp){ \
    new QApplication(argc,argv); \
} \
QString s = QApplication::tr("Executable '%1' requires Qt "\
 "%2, found Qt %3.").arg(qAppName()).arg(QString::fromLatin1(\
str)).arg(QString::fromLatin1(qVersion())); QMessageBox::critical(0, QApplication::tr(\
"Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal(s.toLatin1().data()); }}
</pre>
<p>First thing to note is that the whole thing is wrapped in brackets, meaning that the semicolon isn&#8217;t strictly required and thus a complete non-issue. Sure there is the subtle issues involving things like this:</p>
<pre>if (&lt;condition&gt;) MACRO(a); else foo(a);
</pre>
<p>But this macro is meant to be used unconditionally as the first statement in the program, nothing major. Personally I&#8217;d recommend wrapping the macro in a do {/*&#8230;*/ } while(0), but that&#8217;s a different discussion. Anyway, did you catch the source of the warning? Took me a bit but the issue is the very last statement:</p>
<pre>qFatal(s.toLatin1().data());
</pre>
<p>Basically, they&#8217;ve constructed a QString, getting the equivalent c-string and passing that to qFatal, seems harmless enough. Let&#8217;s look at the definition for qFatal:</p>
<pre>Q_CORE_EXPORT void qFatal(const char *, ...) /* print fatal message and exit */
#if defined(Q_CC_GNU) &amp;&amp; !defined(__INSURE__)
    __attribute__ ((format (printf, 1, 2)))
#endif
;
</pre>
<p>Aha! qFatal is a printf style function, it even has the printf attribute when compiled with gcc. Which basically means we can expect that values passed will likely be given to something like vsprintf, followed by an abort call. This function is called qFatal after all. We all know that it is good security practice to always have the first parameter of a printf function be a string literal to prevent format string vulnerability (at least we all <strong>should</strong> know&#8230;), so the warning is well founded.</p>
<p>Out of curiousity, I tried something like this:</p>
<pre>QT_REQUIRE_VERSION(argc, argv, "4.7.0%n%n%n%n");
</pre>
<p>Boom! Segmentation fault (instead of the expected abort). That means that those %n&#8217;s are trampling memory, which is simply not good. Fortunately the odds of this macro being passed a value provided by a user is pretty much zero, so there is no practical vulnerability here, but it is still an issue, one which has a simple solution. If we simply change the last statment to look like this:</p>
<pre>qFatal("%s", s.toLatin1().data());
</pre>
<p>Then all of these issues go away. No warning, no format string crashes when you do naughty things, it just works correctly. I&#8217;ve added all of these details to my bug report, so far no response. I still love Trolltech and thank them for their wonderful product which I will continue to recommend to people and be a happy user of. But someone over there really just wasn&#8217;t doing their job well. Once I got frustrated enough to look, it took me all of 15 minutes to figure out exactly what was causing the warning and come up with a functional solution. Instead my report has been assigned to documentation where it will likely sit for days until someone realizes it doesn&#8217;t belong there. Wish me luck, I&#8217;ve got my fingers crossed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2010/03/13/how-not-to-handle-a-bug-report/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Flash accidentally subverts the privacy mode of newer browsers?</title>
		<link>http://blog.codef00.com/2010/02/16/flash-accidentally-subverts-the-privacy-mode-of-newer-browsers/</link>
		<comments>http://blog.codef00.com/2010/02/16/flash-accidentally-subverts-the-privacy-mode-of-newer-browsers/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 21:12:58 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=58</guid>
		<description><![CDATA[Pretty much all of the popular browsers now support a &#8220;private browsing&#8221; mode. The whole concept of this mode is to prevent any history of your browsing activities from being recorded. The problem is that there is nothing forcing browser &#8230; <a href="http://blog.codef00.com/2010/02/16/flash-accidentally-subverts-the-privacy-mode-of-newer-browsers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Pretty much all of the popular browsers now support a &#8220;private browsing&#8221; mode. The whole concept of this mode is to prevent any history of your browsing activities from being recorded. The problem is that there is nothing forcing browser extensions to respect this mode of operation.</p>
<p><span id="more-58"></span>I&#8217;ve recently discovered that Flash player&#8217;s settings system stores settings for every site which references flash player. This is a nice usability feature. It allows your flash related settings to work across browser sessions, even different browsers as long as you remain in the same account. But, the filing system itself is also a history of all flash enabled sites you&#8217;ve visited.</p>
<p>On my Linux box, I have the following directory:</p>
<pre>~/.macromedia/Flash_Player/macromedia.com/support/flashplayer/sys</pre>
<p>I also found a similar directory on my windows 7 box, so this is not just a Linux phenomenon. In this directory is a bunch of directories whose names are things like &#8220;#mail.google.com&#8221; and &#8220;#viddler.com&#8221;, each of which has a settings.sol file containing the flash settings for that particular domain. These get created and updated <strong>regardless of privacy mode and any history clearing</strong> you ask your browser to do.</p>
<p>Fortunately, these files are safe to delete (they&#8217;ll just get recreated if needed). If you go to:<a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager.html" target="_blank"> http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager.html</a>, there are settings there that allow you to manage the offline storage settings, but from my quick tests it seems that the folders are created even when you set the allowed storage to 0Kbs.</p>
<p>Obviously this doesn&#8217;t give a complete list of all sites that were visited, but lets face it, much of the questionable content on the internet is served by flash.</p>
<p>Yet another reason to use <a href="http://noscript.net/" target="_blank">noscript</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2010/02/16/flash-accidentally-subverts-the-privacy-mode-of-newer-browsers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How not to maintain an API</title>
		<link>http://blog.codef00.com/2009/11/04/how-not-to-maintain-an-api/</link>
		<comments>http://blog.codef00.com/2009/11/04/how-not-to-maintain-an-api/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 05:25:38 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=51</guid>
		<description><![CDATA[So I&#8217;ve been working on my graphing code for EDB.  I was eventually able create a Qt widget which natively  renders a graphviz graph layout. It actually works quite nicely, you can create an ordinary graphviz graph either in memory &#8230; <a href="http://blog.codef00.com/2009/11/04/how-not-to-maintain-an-api/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve been working on my graphing code for <a class="vt-p" href="http://www.codef00.com/projects.php#debugger" target="_blank">EDB</a>.  I was eventually able create a <a class="vt-p" href="http://qt.nokia.com/" target="_blank">Qt</a> widget which natively  renders a <a class="vt-p" href="http://www.graphviz.org/" target="_blank">graphviz</a> graph layout. It actually works quite nicely, you can create an ordinary graphviz graph either in memory or from a file like usual.  The code can simply create a &#8220;GraphWidget&#8221; and the code will display the graph perfectly (there are some constructs which it doesn&#8217;t support, but the basics are there) with nice things such as zooming and rotating.</p>
<p>All of this works great, except for the fact that graphviz decided to change some of the structures used to represent the layed out graph.</p>
<p><span id="more-51"></span>The most annoying issue I found is that the older versions of the graphviz headers did not have any defines for versioning. This means that there is no good way to detect at compile time which version you are trying to compile against. Later one was introduced, which means that you can coarsely determine if you are compiling against a version before or after that macro was introduced. But this isn&#8217;t really good enough given than there have been several changes over time before and after this macro was introduced.</p>
<p><strong>So rule #1: If you plan to change anything in your publicly installed headers, ever, have a version macro which is unique for each and every version of structures and API.</strong></p>
<p>Of course, the fun doesn&#8217;t stop there, otherwise I wouldn&#8217;t have a whole lot to write about here. In addition to that, they decided to make the version macro they did create resolve to a string! This is great and all for displaying the version to the user. But is not easily comparable at compile time at all. The most creative solution I can think of is to have a configure script which will emit run a program  which includes the header and outputs the version if available, then finally the configure script will parse the result and produce a compile time comparable macro. This is some of what the autotools scripts do to produce things like config.h. But is less than fun to deal with.</p>
<p><strong>Rule #2: Make the version macro numeric, and encode things in a way that x &gt;= y always means that x is newer.</strong></p>
<p>Something like this feels ideal.<br />
<code>#define VERSION 0x00010203 /* version 1.2.3 */</code><br />
Here I am suggesting to use a 32-bit constant for the version, dividing on byte boundaries for trivial decoding and ease of human readability.  There is no need to stick to the tradition versioning schemes either. Lately, I&#8217;ve been preferring using the year and release number like this:<br />
<code>#define VERSION 0x00200901 /* version 2009.1 */</code><br />
Both work equally well. But wait there is more nonsense! The graphviz people decided to use macros to access the members of the primary structures (node, edge, graph). This way they can change the implementation details of these structures but the code using these structures can remain the same. <strong>This was a good idea</strong>. Unfortunately, they didn&#8217;t do it for all of the structures. Only those three. But there are a whole bunch of structures representing text labels, coordinates and other fun stuff which didn&#8217;t use this system.</p>
<p><strong>Rule #3: Be consistent with your API.</strong></p>
<p>Finally, they used to have both floating point and non floating point versions of certain data members. At some point they decided to switch to only floating point. The problem is that some things changed type, but not the name. So if I wanted to store the value of one of these, I can&#8217;t conveniently. For example:<br />
<code>struct T { point *pos; };</code><br />
became<br />
<code>struct T { pointf *pos; };</code><br />
This makes code such as this unfortunately broken across versions.<br />
<code>point *p = x.pos;</code><br />
If I had a usable version macro, I could make the type depend on the version. Even worse some things changed names and types. For example:<br />
<code>ND_coord_i /* returns "struct point " */</code><br />
was replaced by:<br />
<code>ND_coord /* returns "struct pointf" */</code><br />
The former no longer exists. At least I can test for the existence of the ND_coord macros to figure out which to use, but the net result is messier code.</p>
<p><strong>Rule #4: Do everything possible to avoid changing datatypes of structure members and return types of functions. It makes storing the result ugly and convoluted.</strong></p>
<p>One could argue that not all of the structures and functions are part of there public API. After all, it is pretty rare that someone implements there own rendering engine for something as big, complex as graphviz. But these structures are in the headers that every distribution installs into /usr/include/graphviz/.</p>
<p><strong>Rule #5: If it is in a header which gets installed for the user, it is part of the API. If you have internal details you wish to hide use the <a class="vt-p" href="http://en.wikipedia.org/wiki/Opaque_pointer" target="_blank">PIMPL</a> pattern.</strong></p>
<p>So the end of the story is that I&#8217;ve got my Qt based graphing widget I sought after. But the deployment is less than fun. Because I distribute sources I need to test that it compiles on all sorts of distributions. All of this could have been so much simpler if they just planned ahead and had a version friendly API.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2009/11/04/how-not-to-maintain-an-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Fun with graphs</title>
		<link>http://blog.codef00.com/2009/04/22/fun-with-graphs/</link>
		<comments>http://blog.codef00.com/2009/04/22/fun-with-graphs/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 22:30:14 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=45</guid>
		<description><![CDATA[So I figured that I would post some of the progress with EDB. I&#8217;ve been very happy with the function analysis engine that I developed, but there is one thing that it completely ignores, basic block analysis. Of course in &#8230; <a href="http://blog.codef00.com/2009/04/22/fun-with-graphs/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I figured that I would post some of the progress with EDB. I&#8217;ve been very happy with the function analysis engine that I developed, but there is one thing that it completely ignores, basic block analysis. Of course in order to identify functions it does technically break things down into blocks, but this information is discarded when a whole function is identified.</p>
<p><span id="more-45"></span>The main reason for this is that I had no real practical way to display this information in a useful way to users. A list of blocks wouldn&#8217;t do, there would simply be to many for anyone to make sense of them. Some other tools have a nice solution though&#8230;graphs <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>So I figured that it&#8217;s time EDB got a graphing plugin of sorts. And that&#8217;s where my focus has been lately. Finally after playing with the <strong>awesome </strong><a href="http://doc.trolltech.com/4.5/qgraphicsview.html" target="_blank">QGraphicsView</a> API, I have some results that are worth noting.</p>
<p style="text-align: center;"><a href="http://blog.codef00.com/wp-content/uploads/2009/04/edb_graph1.png" target="_blank"><img class="aligncenter size-full wp-image-47" title="edb_graph1" src="http://blog.codef00.com/wp-content/uploads/2009/04/edb_graph1.png" alt="edb_graph1" width="407" height="265" /></a></p>
<p style="text-align: left;">As you can see, it is looking pretty nice. All of the nodes are draggable so if you don&#8217;t like how it is layed out, you can adjust it. Of course it isn&#8217;t quite ready yet, otherwise I would have just tossed it into EDB and bumped the version. There are two major things I need to figure out.</p>
<ol>
<li>How big do I make the whole scene? Right now I just go with &#8220;very big&#8221;, but eventually, I&#8217;ll have to figure this out based on the content. This is very dependant on issue #2 though&#8230;</li>
<li>I have no automatic layout engine. Currently in my test code, I&#8217;ve manually placed each node. This is likely to prove very difficult, but I&#8217;ll get there (Obviously if any graph experts out there want to help, feel free to email me <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ).</li>
</ol>
<p>Beyond that, I&#8217;m feeling pretty good about how it works.</p>
<p>You may be wondering why I didn&#8217;t just use <a href="http://www.graphviz.org/">GraphViz</a>. Well, to be honest, I looked into it. But there didn&#8217;t seem to be any nice and simple way to get the results into a Qt widget. As far as I can tell, the API revolves around programatically generating a .dot file, and sending that through one of the graphviz renderer&#8217;s. Then taking the output file and finally displaying it. I don&#8217;t like all the temporary files and the dependency on external programs. I&#8217;m not a fan of &#8220;front-ends&#8221; in general, otherwise EDB would just be another GDB front end.</p>
<p>Though if I could do a pure library solution, I could work with the temporary files. Obviously I could have missed something in graphviz, if so, let me know <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>I hope to have things nice and ready for release soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2009/04/22/fun-with-graphs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Micro-optimization is stupid</title>
		<link>http://blog.codef00.com/2009/02/11/micro-optimization-is-stupid/</link>
		<comments>http://blog.codef00.com/2009/02/11/micro-optimization-is-stupid/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 16:52:51 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=35</guid>
		<description><![CDATA[I tend to frequent the website stackoverflow.com. It&#8217;s a fantastic website. It allows knowlege to be shared in a unique way. The only problem is, some people have no idea what they are talking about. If there are enough people &#8230; <a href="http://blog.codef00.com/2009/02/11/micro-optimization-is-stupid/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I tend to frequent the website <a href="http://www.stackoverflow.com/" target="_blank">stackoverflow.com</a>. It&#8217;s a fantastic website. It allows knowlege to be shared in a unique way. The only problem is, some people have no idea what they are talking about. If there are enough people who agree with these misguided notions, well then these incorrect answers get up-votes. And the cycle of mis-information repeats. It isn&#8217;t too dissimilar from the various types of incorrect information regarding <a href="http://blog.codef00.com/2007/12/19/windows-on-x86-and-4gb-of-ram/">32-bit machines and 4GB of RAM</a>.</p>
<p><span id="more-35"></span>This isn&#8217;t a problem with stackoverflow.com, it&#8217;s a problem with people who claim things to be the case without actually testing if what they are saying is true. It happens time and time again.</p>
<p>You may be wondering why the title of this blog entry is &#8220;Micro-optimization is stupid&#8221; when I haven&#8217;t even mentioned that yet, well wait no more, here it is. Someone had asked a question which had a simple answer on SO. He was trying to insert a pointer to an object into a list which contained actual objects. I am guessing he is usually a java programmer (this isn&#8217;t an attack of java programmers, just that java&#8217;s syntax for creating references to objects looks very much like the broken c++ he was trying to use).</p>
<p>Someone took it upon themselves to not only give advice on how to correct this trivial error, but also gave some optimization advice for iterating over the list. He recomended something like this:<br />
<code><br />
    for(std::list&lt;Point&gt;::iterator it = l.begin(), end = l.end(); it != end; ++i) {<br />
        /* whatever */<br />
    }<br />
</code><br />
as apposed to this:<br />
<code><br />
    for(std::list&lt;Point&gt;::iterator it = l.begin(); it != l.end(); ++i) {<br />
        /* whatever */<br />
    }<br />
</code><br />
The reality is that there isn&#8217;t a huge amount of difference between the two. The goal of the posters code is to avoid std::list::end() from being called after every iteration of the loop. I felt compelled to point out to the poster that the optimization recomendation was misguided as any sane compiler will nicely optimize that loop so the std::list::end() is only called once. In addition to that std::list::end() is an O(1) operation as mandated by the standard, so even if it were called multiple times, it wouldn&#8217;t make a difference. You&#8217;re trading one memory fetch for another, no real difference.</p>
<p>Of course he argued, people who don&#8217;t know what they are talking about usually do <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> . He started claiming that since the compiler doesn&#8217;t know that the size is constant,  it has to recalculate the size each time, and that this extra function call would cause cache misses and such. See the problem here? There is enough techno-babble to sound convincing! But don&#8217;t worry folks, I was determined to demonstrate my point.</p>
<p>So I responded with a few corrections. Most importantly,  <code>size() != end()</code>, so even if it did need to recalculate <code>size()</code> each time, the size has nothing to do with it.  In addition, certainly if the loop only uses member functions which are const it certainly <strong>can</strong> know that the list hasn&#8217;t changed.  (he of course retorted that while the <code>end()</code>/<code>size()</code> function is const, it&#8217;s result is not, which is just silliness, since end() won&#8217;t change the list, if all other functions don&#8217;t change the list, well then end() will be the same next iteration!). Finally, I sent him a link to some code which looks like this:</p>
<p><code><br />
    // program 1<br />
    #include &lt;list&gt;<br />
    #include &lt;iostream&gt;</p>
<p>    int main() {<br />
        std::list&lt;int&gt; l1;</p>
<p>        l1.push_back(1);<br />
        l1.push_back(2);<br />
        l1.push_back(3);<br />
        l1.push_back(4);</p>
<p>        std::list&lt;int&gt;::iterator end = l1.end();<br />
        for(std::list&lt;int&gt;::iterator it = l1.begin(); it != end; ++it) {<br />
            printf("%d\n", *it);<br />
        }<br />
    }<br />
</code><br />
<code><br />
    // program 2<br />
    #include &lt;list&gt;<br />
    #include &lt;iostream&gt;</p>
<p>    int main() {<br />
        std::list&lt;int&gt; l1;</p>
<p>        l1.push_back(1);<br />
        l1.push_back(2);<br />
        l1.push_back(3);<br />
        l1.push_back(4);</p>
<p>        for(std::list&lt;int&gt;::iterator it = l1.begin(); it != l1.end(); ++it) {<br />
            printf("%d\n", *it);<br />
        }<br />
    }<br />
</code></p>
<p>And asked that he compile them both with g++ -O3 and <strong>look</strong> at the results. Not just assume what some other jackass told him was correct. I had already done this, and knew that the result on the latest g++ is identical. At this point I had a good feeling, knowing I had prevailed&#8230; until he responded with this:</p>
<blockquote><p>GCC 4.01 with g++ -O3 -S produces different assembly outputs and different binaries with vectors and lists. GCC 4.2 produces identical output for lists but different output for vectors. The OP uses a vector, my comment stands.</p></blockquote>
<p>Seriously?! This guy just couldn&#8217;t admit being even slightly wrong. To be clear, the OP used a <strong>list, not a vector</strong>. So at this point he was just making things up without taking the time to read. In addition, I checked and the &#8220;difference&#8221; between the two was more or less cosmetic. Doing the same work in slightly different order (but not repeatedly calling end(), which was the original concern).</p>
<p>Finally, justice came and people started to downvote his answer.  Finally he edited his post to remove the incorrect advice he gave and the downvotes were removed. None of this would have happened if he hadn&#8217;t gotten fixated on silly little micro-optimizations. When will people learn?</p>
<p>Tricks like this may have made a difference in the early days of c++, but modern compilers are suprisingly good at optimization. Let them do their job so that you can do your job!</p>
<p>At this point in time, every compitent developer should know that it is best to do things the simplest, most obvious way first. This is better in many ways, most importantly in maintainability. Everyone can agree that simple and obvious code is easier to understand. Then if after <strong>profiling</strong> you find that a particular segment of code is not performant enough, feel free to go bananas with optimizing the little things in that particular section.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2009/02/11/micro-optimization-is-stupid/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>It Lives!</title>
		<link>http://blog.codef00.com/2008/12/05/it-lives/</link>
		<comments>http://blog.codef00.com/2008/12/05/it-lives/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 06:42:36 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=17</guid>
		<description><![CDATA[It’s official, I’ve gotten the core component of EDB to compile on Vista! It took a lot of effort and to be honest, some working around various compiler bugs. But step #1 has been completeled. Next I’ll have to port &#8230; <a href="http://blog.codef00.com/2008/12/05/it-lives/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="post-12" class="post">
<div class="entry">
<p>It’s official, I’ve gotten the core component of <a href="http://www.codef00.com/projects.php#Debugger" target="_blank">EDB</a> to compile on Vista!</p>
<p><a href="http://blog.codef00.com/wp-content/uploads/2008/12/edb_vista1.png"><img class="aligncenter size-medium wp-image-25" title="edb_vista1" src="http://blog.codef00.com/wp-content/uploads/2008/12/edb_vista1-300x270.png" alt="" width="300" height="270" /></a></p>
<p><a href="http://blog.codef00.com/wp-content/uploads/2008/12/edb_vista2.png"><img class="aligncenter size-medium wp-image-21" title="edb_vista2" src="http://blog.codef00.com/wp-content/uploads/2008/12/edb_vista2-300x153.png" alt="" width="300" height="153" /></a></p>
<p>It took a lot of effort and to be honest, some working around various compiler bugs. But step #1 has been completeled. Next I’ll have to port the “DebuggerCore” plugin, and it should be smooth sailing from there. I plan to have Win32 support before calling it 1.0, we’ll see. I hope to have more updates soon <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2008/12/05/it-lives/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>GTA IV Actually Discourages Attacking Police</title>
		<link>http://blog.codef00.com/2008/06/25/gta-iv-actually-discourages-attacking-police/</link>
		<comments>http://blog.codef00.com/2008/06/25/gta-iv-actually-discourages-attacking-police/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 20:41:04 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/2008/06/25/gta-iv-actually-discourages-attacking-police/</guid>
		<description><![CDATA[I&#8217;ve been a huge fan of the GTA series ever since GTA 3 came out. It is a genuinely fun game which gives you your money&#8217;s worth of entertainment. The plots have been good and the missions are hard enough &#8230; <a href="http://blog.codef00.com/2008/06/25/gta-iv-actually-discourages-attacking-police/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been a huge fan of the GTA series ever since GTA 3 came out. It is a genuinely fun game which gives you your money&#8217;s worth of entertainment. The plots have been good and the missions are hard enough to be challenging, but not so hard that you&#8217;ll wanna stop playing. I&#8217;ve always gotten a little amusement from the people who claim that games like GTA encourage violence, particularly violence towards law enforcement. As of today, I&#8217;m about 50% done with the game, and have come to a conclusion. GTA IV actually discourages violence towards the police!</p>
<p><span id="more-11"></span></p>
<p>I know this sounds crazy, and I know that the game itself centers around violent and criminal behavior&#8230;but hear me out. To give you some background, here&#8217;s how the wanted level system works in GTA. You can get stars, each of which on a scale of 0 through 6 which roughly translates to &#8220;how pissed are the police.&#8221; The more overt your criminal activity, the more stars you get. One or two stars are pretty easy to evade. At three it starts to get hard. Four or more, and I wish you luck getting away alive.</p>
<p>Throughout the game there are plenty of &#8220;kill the bad guys, steal their stuff, get away clean&#8221; missions. Usually the police will show up shortly after the &#8220;steal the stuff&#8221; with two stars. Here&#8217;s the thing, the moment you do anything violent towards the police, the stars jump up to three or four. This makes escape much more annoying. The path of least resistance is nearly always to just get in a vehicle and get away as fast as possible. Forget shooting the police, just get away and get away fast.</p>
<p>The bottom line of this is that you tend to be much more successful in the game if you just <strong>avoid</strong> the police instead of trying to brute force your way through them and killing all in your way.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2008/06/25/gta-iv-actually-discourages-attacking-police/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How Microsoft Could Have Handled Compatibility In Vista</title>
		<link>http://blog.codef00.com/2008/06/08/how-microsoft-could-have-handled-compatibility-in-vista/</link>
		<comments>http://blog.codef00.com/2008/06/08/how-microsoft-could-have-handled-compatibility-in-vista/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 23:31:35 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/2008/06/08/how-microsoft-could-have-handled-compatibility-in-vista/</guid>
		<description><![CDATA[So I&#8217;ve been using Windows Vista for a while on my desktop and have been generally happy. The system is stable, most features work as expected, and let&#8217;s be honest, it looks really nice. One thing that has constantly frustrated &#8230; <a href="http://blog.codef00.com/2008/06/08/how-microsoft-could-have-handled-compatibility-in-vista/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve been using Windows Vista for a while on my desktop and have been generally happy. The system is stable, most features work as expected, and let&#8217;s be honest, it looks really nice. One thing that has constantly frustrated me is the shear <strong>size</strong> of each release of Windows. Every release is noticeably larger than the previous. I certainly understand that each release adds more features, and more features means bigger. But I think it&#8217;s about time that Microsoft started to trim the fat.</p>
<p><span id="more-10"></span></p>
<p>The primary place that comes to mind with trimming the fat is backwards compatibility. One of Windows strengths in the past has been that upgrades usually keep your programs running. But at this point, after all these versions, I think it has become a weakness. Not to fret, I have an idea <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>In essence, I think that compatibility should be far more modular and optional. A good way to do this would be to run older programs in something that functions like the UNIX &quot;chroot.&quot; Microsoft could create a few new folders, something like &quot;C:\WindowsXP\&quot; and &quot;C:\Windows2K&quot;, etc. Each of these would function like a virtual &quot;C:\&quot; drive for each compatibility module. Inside of each of these would be an entirely functional file structure which matches the previous versions of windows. This would be complete with older versions of various dlls so programs can&#8217;t tell the difference between the fake XP mode and the original.</p>
<p>A few things such as user document folders could be handled with something that can function like symbolic links. In addition to this, each compatibility mode would probably need to have it&#8217;s own registry tree.</p>
<p>Actual installation could be handled a few ways with various levels of compatibility.</p>
<ol>
<li>Have a &quot;Run in Windows XP mode&quot; right click menu similar to &quot;Run as Administrator.&quot;</li>
<li>Have a new flag in the PE header to indicate newest supported version of Windows. Lack of this flag would imply some common denominator.</li>
<li>Have the system detect writes to program folders and registry keys, and provide a user prompt asking which mode to run it in.</li>
<li>Have a program database of some sort.</li>
</ol>
<p>Installation is the toughest part of this system, but I think can be handled. This idea is actually inspired by two things I&#8217;ve already seen. <a title="Wine" href="http://www.winehq.org/" target="_blank" title="Wine">Wine</a> and how Apple handled the migration of OS9 to OSX by being able to virtually run OS9 in OSX.</p>
<p>Basically, in essence, what I am talking about is a Win32 port of Wine that would be supported by the system on a kernel level. This would allow the compatibility to be <strong>optional</strong> which could be a huge saver of resources and space on the system if you intend to be up to date on your programs and only run applications intended for the newer OS. Best part, if you don&#8217;t need it, you don&#8217;t have it. It can be that simple!</p>
<p>All in all, I can see few downsides to this concept. It&#8217;s already in practice on linux systems which run wine. Since Windows XP is an iterative build on top of NT and 2K, the PE flag idea would work well (compatibility mode would be either on or off). In the end you have a virtual Windows XP environment which is sandboxed and let&#8217;s face it, who is better equipped to build this system than the designers of the original?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2008/06/08/how-microsoft-could-have-handled-compatibility-in-vista/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Time to update older UI toolkits?</title>
		<link>http://blog.codef00.com/2008/04/05/time-to-update-older-ui-toolkits/</link>
		<comments>http://blog.codef00.com/2008/04/05/time-to-update-older-ui-toolkits/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 05:35:45 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.blog.codef00.com/2008/04/05/time-to-update-older-ui-toolkits/</guid>
		<description><![CDATA[My favorite editor of choice for the past 10 years has been nedit, it is a wonderfully simple yet complete GUI based text editor with a focus on development. It has all of the basics that I need; syntax highlighting, &#8230; <a href="http://blog.codef00.com/2008/04/05/time-to-update-older-ui-toolkits/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My favorite editor of choice for the past 10 years has been <a href="http://www.nedit.org/" title="nedit" target="_blank">nedit</a>, it is a wonderfully simple yet complete GUI based text editor with a focus on development. It has all of the basics that I need; syntax highlighting, relatively smart indenting, brace matching, the ability to highlight an include and open the file it refers to. All of the basics are there, so as an editor it suites my needs and development habits. There is only one thing, it&#8217;s ugly. And this is no fault of the developers, it&#8217;s the fault of how Motif looks.</p>
<p><span id="more-9"></span> You can improve things a little bit by playing with X resources, in fact on nedit&#8217;s site, there is <a href="http://www.nedit.org/technotes/looks-1.php" title="How to take 15 years off NEdit's looks" target="_blank">an article about it</a>. This works ok, but on my <a href="http://www.kde.org" title="kde" target="_blank">KDE</a> or <a href="http://www.gnome.org" title="gnome" target="_blank">Gnome</a> desktops which use modern GUI toolkits it still stands out, it simply isn&#8217;t a pretty app. The nedit developers have actually expressed some interest in a port to other toolkits in the FAQs, but feel it is too large of a task, and to be honest, I agree. Rewriting all of that code just to update the toolkit is a bit much to ask for, especially since it functions so well.</p>
<p>What I propose is something different, which I feel is a bit more practical. Rewrite older UI toolkits on top of newer ones! This has several benefits. First and foremost, it allows applications to get a face lift simply by installing a new library, you probably wouldn&#8217;t even need to recompile your apps! Related to this, all of the &#8220;common dialogs&#8221; will be updated as well. This will provide a more cohesive user experience. More subtly, there would be a lot more code reuse. If I write my hypothetical &#8220;GTKTiff&#8221; library which implements a binary and source compatible API for Motif on top of GTK, all of the core functionality is already done. All of these toolkits implement the same core features; buttons, frames, tabs, file dialogs, etc. So this &#8220;GTKTiff&#8221; would likely be smaller and more maintainable than a full &#8220;from the ground up&#8221; implementation such as <a href="http://www.openmotif.org/" title="openmotif" target="_blank">OpenMotif</a> or <a href="http://www.lesstif.org/" title="lesstiff" target="_blank">LessTiff</a>.</p>
<p>For the more traditionalist users, well pretty much every major toolkit provides theming, and there could easily be a &#8220;Motif Classic&#8221; theme.</p>
<p>Don&#8217;t get me wrong, I think that the OpenMotif and LessTiff projects are wonderful, they let me run my favorite editor on GNU/Linux after all! But I do think that there is an opportunity to consolidate some code and provide a better user experience. The current state of the UNIX or GNU/Linux desktop is not just a mish-mash of applications, but instead is a collection of applications designed to share a look and feel in order to provide a good user experience.</p>
<p>Having many GUI APIs has its pros and cons. Operating Systems such as GNU/Linux are founded on the concept of choice, which is a wonderful thing. I just think that older APIs shouldn&#8217;t lock applications in the &#8220;stone age.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2008/04/05/time-to-update-older-ui-toolkits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux&#8217;s ptrace API sucks!</title>
		<link>http://blog.codef00.com/2008/01/29/linuxs-ptrace-api-sucks/</link>
		<comments>http://blog.codef00.com/2008/01/29/linuxs-ptrace-api-sucks/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 00:01:05 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.blog.codef00.com/2008/01/29/linuxs-ptrace-api-sucks/</guid>
		<description><![CDATA[I love Linux, as a developer, I find the tools available suit my style of work perfectly. Sometimes the tool that I want isn&#8217;t available. That&#8217;s OK though, because whenever I can, I try to contribute. I do a lot &#8230; <a href="http://blog.codef00.com/2008/01/29/linuxs-ptrace-api-sucks/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I love Linux, as a developer, I find the tools available suit my style of work perfectly. Sometimes the tool that I want isn&#8217;t available. That&#8217;s OK though, because whenever I can, I try to contribute.</p>
<p>I do a lot of reverse engineering work and thus the lack of anything like <a title="Ollydbg" href="http://www.ollydbg.de/" target="_blank">Ollydbg</a> spawned off my <a title="EDB" href="http://www.codef00.com/projects.php#Debugger">EDB</a> project. It&#8217;s a debugger designed to focus on applications at a machine code level.  This project is coming along nicely but there is one thing that I really wish I could change&#8230;ptrace sucks, and it sucks a lot.</p>
<p><span id="more-8"></span></p>
<p>First of all, it has no inherent support for threads. This is a huge problem as many modern applications are multi threaded. Instead, since Linux treats threads as independent processes which happen to share the the majority of there address spaces, you are supposed to ptrace each thread individually. So, you need to attach to all &#8220;pids&#8221; found in &#8220;/proc/&lt;pid&gt;/task/&#8221;. On top of this, you have to set an option in ptrace to attach to new threads as they are created with the clone system call. It is entirely undocumented whether you need to do this on a per process basis or a per-thread basis. Finally, you need track threads exiting so you know to stop looking for events on those. That&#8217;s an awful lot of effort just to be able to debug threads. By the way, the information necessary to know which bits of the status code tell you if it was a clone event (new thread) is also entirely undocumented.</p>
<p>Did i mention the potential race condition with attaching to all threads in the /proc/&lt;pid&gt;/task/ directory? Since the threads could be spawning more threads while you are enumerating the directories. Threads could even exit during this time. So you have to loop continually trying to attach until the you are sure the thread count is stabilized and all are attached to. The only saving grace here is that attaching stops a thread so it is possible to get them all if you think it through.</p>
<p>Next, I wish that the PTRACE_PEEK* and PTRACE_POKE* request types had support for non-word width granularity. It makes setting a breakpoint more annoying than it has to be since you really only want to read/write a single byte in that case. Not only that, but reading/writing from the edges of region boundaries is equally annoying. A much better interface would have been similar to the file API where you can specify and address and a length. In addition to this, you need to pay careful attention to the various gotchas due to the fact that the return value is both an error code and a result. So if it returns (long)-1, then you need to check errno just to make sure that it isn&#8217;t an error.</p>
<p>The usage of wait for debug events is just awkward. It works great for single threaded command line debuggers like gdb, but for a GUI, where you want things to be interactive while the debugger is waiting for the next event, it is a disaster. Sure you can use a separate thread to capture events and deliver them to the GUI,  but then you have issues properly shutting down that thread, since it will pretty much always be blocked! Also, wait has no timeout, so if you aren&#8217;t careful it is possible to get hung forever waiting for an even that will never happen. There is SIGCHLD, which sounds promising at first, but the fun part is that without sigprocmask trickery, you can&#8217;t predict which of your threads will get the signal. Grr!</p>
<p>Finally, there is lots of information that would be better suited being part of the debugging API. A great example of this is x86 segments. This really should be in the user area. You can get the segment values from the user area or even a PTRACE_GETREGS request. But the segment values are nearly worthless without being able to look at things like the segment base and limits. I understand not all platforms have this data, and x86-64 has much less usage of segments, but that&#8217;s why it should be in the user area.</p>
<p>A better API would first of all, be at a process level. I don&#8217;t care how it works under the hood, I want to attach to &#8220;processes.&#8221; There should also be a function to enumerate threads, this would only be valid when the process is stopped. This way you could get/set the context of each thread by passing a tid. Just these changes would make things much easier.</p>
<p>Overall, the user space API provided by ptrace could use a large overhaul. I understand the desire to be consistent with other unix&#8217;s debugging APIs, but  this should not get in the way of making something usable.</p>
<p><a title="utrace" href="http://people.redhat.com/roland/utrace/" target="_blank">utrace</a> sounds ok, but as far as I know, it is designed to be kernel level changes. In fact, it appears there are plans to have ptrace implemented on top of utrace in the future. That&#8217;s great and all, but the user space API needs an update! I can only hope that utrace bring along a new user space API as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2008/01/29/linuxs-ptrace-api-sucks/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
