Boost C++ Libraries: Ticket #1929: Borland/Codegear C++ 2007 creating boost::thread fails at initialisation of membervar boost::thread::thread_info https://svn.boost.org/trac10/ticket/1929 <p> I'm attempting to create a thread in <a class="missing wiki">Borland/Codegear</a> C++ 2007 (win32) by means of code similar to this: </p> <div class="wiki-code"><div class="code"><pre><span class="k">class</span> <span class="nc">Threaded</span> <span class="p">{</span> <span class="k">volatile</span> <span class="kt">bool</span> <span class="n">_quit</span><span class="p">;</span> <span class="n">boost</span><span class="o">::</span><span class="kr">thread</span> <span class="n">_thread</span><span class="p">;</span> <span class="k">public</span><span class="o">:</span> <span class="n">Threaded</span><span class="p">()</span> <span class="o">:</span> <span class="n">_quit</span><span class="p">(</span><span class="nb">false</span><span class="p">),</span> <span class="n">_thread</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">ref</span><span class="p">(</span><span class="o">*</span><span class="k">this</span><span class="p">))</span> <span class="p">{}</span> <span class="kt">void</span> <span class="k">operator</span><span class="p">()()</span> <span class="p">{</span> <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">_quit</span><span class="p">)</span> <span class="cm">/* do stuff here */</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> </pre></div></div><p> The results of several debugging sessions: </p> <p> However as soon as the constructor of boost::thread gets invoked it will call boost::thread::make_thread. This allocates some heap memory using the Windows API and uses an in-place new to construct a detail::thread_data&lt;T&gt; in that memory. The allocation and construction seem to work out very well. </p> <p> As soon as boost::thread::make_thread_info returns however it seems to fail to assign the pointer to member variable thread_info in the constructor. </p> <p> I tried the below patch for debugging purposes, to see what happens. Somehow the new variable (<code>tinfo</code>) remains NULL (all heap memory is initialised to zero while debugging, hence the NULL) however. Thus it seems that this compiler (borland) somehow fails to generate code that properly assigns the pointer to boost::thread's member variables. </p> <p> However, somehow assigning the value of <code>tinfo</code> to an on-stack variable <em>does</em> yield the correct pointer, while at the time the debugger says that <code>tinfo</code> is still NULL, even though assigning it to another pointer yields a non-NULL (and correct) value. So maybe it's pointer value is kept in a register but only gets assigned to stack based variables but not to member variables? </p> <p> What's even more strange is that compiling a minimal test case <em>outside</em> of the IDE (using bjam) produces code that works. Unfortunately I cannot use bjam for my project as it depends on Borland's VCL GUI library (if it's possible to use bjam with Borland's VCL anyway please tell me where to look/what to do, as up till now I've only failed miserably and have little experience with bjam anyway). </p> <p> Thus this <sup></sup> leads me to believe that something differs in the compiler options, I haven't got the slightest clue what it could be though. I've got all optimisations turned off. Although I have no clue how to know what command line options the IDE is calling the compiler with, so I cannot compare it. </p> <div class="wiki-code"> <div class="diff"> <ul class="entries"> <li class="entry"> <h2> <a>boost/thread/win32/thread.hpp</a> </h2> <table class="trac-diff inline" cellspacing="0"> <colgroup> <col class="lineno"/><col class="lineno"/><col class="content"/> </colgroup> <thead> <tr> <th title="File boost/thread/win32/thread.hpp (revision 45484)"> </th> <th title="File boost/thread/win32/thread.hpp (working copy)"> </th> <td> <em></em> &nbsp; </td> </tr> </thead> <tbody class="unmod"> <tr> <th>196</th><th>196</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; };</span></td> </tr> <tr> <th>197</th><th>197</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; </span></td> </tr> <tr> <th>198</th><th>198</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; mutable boost::mutex thread_info_mutex;</span></td> </tr> </tbody> <tbody class="add"> <tr class="last first"> <th>&nbsp;</th><th>199</th><td class="r"><ins>&nbsp; &nbsp; &nbsp; &nbsp; detail::thread_data_base* tinfo;</ins></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>199</th><th>200</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; detail::thread_data_ptr thread_info;</span></td> </tr> <tr> <th>200</th><th>201</th><td class="l"><span></span></td> </tr> <tr> <th>201</th><th>202</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; static unsigned __stdcall thread_start_function(void* param);</span></td> </tr> </tbody> <tbody class="skipped"> <tr> <th><a href="#L214">&hellip;</a></th> <th><a href="#L215">&hellip;</a></th> <td> <em></em> &nbsp; </td> </tr> </tbody> <tbody class="unmod"> <tr> <th>214</th><th>215</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; }</span></td> </tr> <tr> <th>215</th><th>216</th><td class="l"><span>#else</span></td> </tr> <tr> <th>216</th><th>217</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; template&lt;typename F&gt;</span></td> </tr> </tbody> <tbody class="mod"> <tr class="first"> <th>217</th><th>&nbsp;</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; static inline detail::thread_data_<del>ptr</del> make_thread_info(F f)</span></td> </tr> <tr class="last"> <th>&nbsp;</th><th>218</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; static inline detail::thread_data_<ins>base*</ins> make_thread_info(F f)</span></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>218</th><th>219</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; {</span></td> </tr> <tr> <th>219</th><th>220</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return detail::heap_new&lt;thread_data&lt;F&gt; &gt;(f);</span></td> </tr> <tr> <th>220</th><th>221</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; }</span></td> </tr> </tbody> <tbody class="skipped"> <tr> <th><a href="#L238">&hellip;</a></th> <th><a href="#L239">&hellip;</a></th> <td> <em></em> &nbsp; </td> </tr> </tbody> <tbody class="unmod"> <tr> <th>238</th><th>239</th><td class="l"><span>#else</span></td> </tr> <tr> <th>239</th><th>240</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; template &lt;class F&gt;</span></td> </tr> <tr> <th>240</th><th>241</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; explicit thread(F f):</span></td> </tr> </tbody> <tbody class="mod"> <tr class="first"> <th>241</th><th>&nbsp;</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thread_info(make_thread_info(f))</span></td> </tr> <tr> <th>&nbsp;</th><th>242</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tinfo(make_thread_info(f)),</span></td> </tr> <tr class="last"> <th>&nbsp;</th><th>243</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thread_info(tinfo)</span></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>242</th><th>244</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; {</span></td> </tr> <tr> <th>243</th><th>245</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; start_thread();</span></td> </tr> <tr> <th>244</th><th>246</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; }</span></td> </tr> </tbody> </table> </li> </ul> </div></div> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/1929 Trac 1.4.3 Giel van Schijndel <me@…> Sun, 18 May 2008 15:41:01 GMT <link>https://svn.boost.org/trac10/ticket/1929#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1929#comment:1</guid> <description> <p> Note, I've tested this with both trunk and 1.35 and it happens with both. </p> </description> <category>Ticket</category> </item> <item> <author>Giel van Schijndel <me@…></author> <pubDate>Sun, 18 May 2008 18:30:39 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/1929 https://svn.boost.org/trac10/ticket/1929 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">thread-borland-workaround.patch</span> </li> </ul> <p> Attempt to workaround bug </p> Ticket Giel van Schijndel <me@…> Sun, 18 May 2008 18:30:58 GMT <link>https://svn.boost.org/trac10/ticket/1929#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1929#comment:2</guid> <description> <p> After some further experimenting I found that <a class="attachment" href="https://svn.boost.org/trac10/attachment/ticket/1929/thread-borland-workaround.patch" title="Attachment 'thread-borland-workaround.patch' in Ticket #1929">thread-borland-workaround.patch</a><a class="trac-rawlink" href="https://svn.boost.org/trac10/raw-attachment/ticket/1929/thread-borland-workaround.patch" title="Download">​</a> fixes the problem, though only for the construction part of boost::thread. As soon as you call boost::thread::join it'll segfault. </p> </description> <category>Ticket</category> </item> <item> <author>Giel van Schijndel <me@…></author> <pubDate>Sun, 18 May 2008 18:33:35 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/1929#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1929#comment:3</guid> <description> <p> Btw <a class="attachment" href="https://svn.boost.org/trac10/attachment/ticket/1929/thread-borland-workaround.patch" title="Attachment 'thread-borland-workaround.patch' in Ticket #1929">thread-borland-workaround.patch</a><a class="trac-rawlink" href="https://svn.boost.org/trac10/raw-attachment/ticket/1929/thread-borland-workaround.patch" title="Download">​</a> only works because it moves the pointer assignment out of the IDE compiled code into bjam compiled code. </p> <p> PS I also found this thread on comp.lang.c++ on what seems to be the exact same problem: <a class="ext-link" href="http://groups.google.com/group/comp.lang.c++/browse_thread/thread/e532172a82d20674"><span class="icon">​</span>http://groups.google.com/group/comp.lang.c++/browse_thread/thread/e532172a82d20674</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Marshall Clow</dc:creator> <pubDate>Fri, 23 May 2008 16:10:40 GMT</pubDate> <title>component changed; owner set https://svn.boost.org/trac10/ticket/1929#comment:4 https://svn.boost.org/trac10/ticket/1929#comment:4 <ul> <li><strong>owner</strong> set to <span class="trac-author">Anthony Williams</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">thread</span> </li> </ul> Ticket Giel van Schijndel <me@…> Fri, 23 May 2008 23:27:42 GMT <link>https://svn.boost.org/trac10/ticket/1929#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/1929#comment:5</guid> <description> <p> I found that these are the compiler options that are used (on all source files) when I compile using the IDE: </p> <pre class="wiki">bcc32.exe -D_DEBUG;NO_STRICT -D_RTLDLL;USEPACKAGES -I"c:\program files\codegear\rad studio\5.0\include";"c:\program files\codegear\rad studio\5.0\include\dinkumware";"c:\program files\codegear\rad studio\5.0\include\vcl";..\..\..\Bureaublad\proia3\src\opengltest;"c:\program files\codegear\rad studio\5.0\include\Indy10";C:\boost_1_35_0 -y -v -vi- -k -r- -c -tWM -tW -H=Debug\borlandgltest.pch -oDebug\gldraw.obj -w-par -Od gldraw.cpp </pre><p> This the linker command used: </p> <pre class="wiki">ilink32.exe -L"c:\program files\codegear\rad studio\5.0\lib\debug";"c:\program files\codegear\rad studio\5.0\lib";"c:\program files\codegear\rad studio\5.0\lib\obj";"c:\program files\codegear\rad studio\5.0\lib\psdk";..\..\..\Bureaublad\proia3\src\opengltest;"c:\program files\codegear\rad studio\5.0\lib";"c:\program files\codegear\rad studio\5.0\lib\Indy10";"C:\Documents and Settings\All Users\Documenten\RAD Studio\5.0\DCP";Debug -j"c:\program files\codegear\rad studio\5.0\lib\debug";"c:\program files\codegear\rad studio\5.0\lib";"c:\program files\codegear\rad studio\5.0\lib\obj";"c:\program files\codegear\rad studio\5.0\lib\psdk";..\..\..\Bureaublad\proia3\src\opengltest;"c:\program files\codegear\rad studio\5.0\lib";"c:\program files\codegear\rad studio\5.0\lib\Indy10";"C:\Documents and Settings\All Users\Documenten\RAD Studio\5.0\DCP";Debug -lDebug -v -Gn -GA"C:\Documents and Settings\Giel van Schijndel\Mijn documenten\C++\proia3\src\opengltest\vfs24D.tmp"="C:\Documents and Settings\Giel van Schijndel\Mijn documenten\C++\proia3\src\opengltest\borlandgltest.res" -GA"C:\Documents and Settings\Giel van Schijndel\Mijn documenten\C++\proia3\src\opengltest\vfs24E.tmp"="C:\Documents and Settings\Giel van Schijndel\Mijn documenten\C++\proia3\src\opengltest\form1.dfm" -aa c0w32.obj vcl.bpi rtl.bpi vclx.bpi memmgr.lib sysinit.obj Debug\borlandgltest.obj Debug\devicecontext.obj Debug\form1.obj Debug\glcontext.obj Debug\gldraw.obj , Debug\borlandgltest.exe , Debug\borlandgltest.map , import32.lib cp32mti.lib , , "C:\Documents and Settings\Giel van Schijndel\Mijn documenten\C++\proia3\src\opengltest\vfs24D.tmp" </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Anthony Williams</dc:creator> <pubDate>Wed, 28 May 2008 15:32:33 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/1929#comment:6 https://svn.boost.org/trac10/ticket/1929#comment:6 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> This issue appears to be due to the lack of abi_prefix.hpp and abi_suffix.hpp. I've added these to trunk in revision 45865, which should fix the problem. </p> Ticket