<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Programmabsturz beim Beenden]]></title><description><![CDATA[<p>Hallo Zusammen!</p>
<p>Ich bin gerade dabei meinen eigenen ClassLoader zu basteln (ich weiß, dass gibt es fertig, aber um meine C++-Fähigkeiten zu verbessern will ich es selbst machen). Dafür habe ich bis jetzt folgenden Code produziert (soweit zsuammengekürzt, dass der Fehler noch kommt):</p>
<p>child.hpp</p>
<pre><code class="language-cpp">#ifndef CHILD_HPP_
#define CHILD_HPP_

#include &lt;iostream&gt;
#include &lt;map&gt;

struct object_factories{};

template &lt;typename classtype&gt; struct object_factory : public object_factories {

	static classtype* new_instance() { return new classtype; }
	static void destroy_instance(classtype *&amp;ptr) { delete ptr; ptr = NULL; }

};

class instantiator {

	public:

		typedef std::map&lt;const char*, object_factories*&gt; object_factory_map;

		static void addClass(const char* className, object_factories* object_factory_ptr) { 
			std::cout &lt;&lt; &quot;Registriere Klasse '&quot; &lt;&lt; className &lt;&lt; &quot;' (Factory-Map: &quot; &lt;&lt; &amp;factory_map() &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
 			factory_map().insert(std::pair&lt;const char*, object_factories*&gt;(className, object_factory_ptr));
		}

		static void __attribute__ ((destructor)) destroy_factories() {
			for(object_factory_map::const_iterator i = factory_map().begin(); i != factory_map().end(); ++i) {
				std::cout &lt;&lt; &quot;Zerstöre Faktorie für Klasse '&quot; &lt;&lt; i-&gt;first &lt;&lt; &quot;' (Factory-Map: &quot; &lt;&lt; &amp;factory_map() &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
				object_factories *ptr = i-&gt;second; delete ptr;
			}
			factory_map().clear();
		}

	private:

		inline static object_factory_map&amp; factory_map() {
			static object_factory_map fac_map;
			return fac_map;
		}

};

class Child {

		Child();
		~Child();

};

// Registriere Klasse Child
namespace {

	template &lt;typename Context&gt; struct cl_reg_context { static bool placeholder; };
	template &lt;typename Context&gt; bool cl_reg_context&lt;Context&gt;::placeholder = false;

	template&lt;&gt; bool cl_reg_context&lt;Child&gt;::placeholder=(instantiator::addClass(&quot;Child&quot;, new object_factory&lt;Child&gt;), true);

}

#endif
</code></pre>
<p>child.cpp:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &quot;child.hpp&quot;

Child::Child() {}
Child::~Child() {}
</code></pre>
<p>main.cpp:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;dlfcn.h&gt;
#include &quot;child.hpp&quot;

int main() {

	void *handle = dlopen(&quot;./Child.so&quot;, RTLD_LAZY);
	dlclose(handle);

	std::cout &lt;&lt; &quot;Ping&quot; &lt;&lt; std::endl;

	return 0;
}
</code></pre>
<p>GNUmakefile</p>
<pre><code>all:
	g++ -g -Wall -shared -o Child.so child.cpp
	g++ -g -Wall -ldl main.cpp -o cl

clean:
	rm -f *.so cl cl.exe
</code></pre>
<p>Wenn ich das ganze nun übersetzte und Ausführe kommt folgende Ausgabe:</p>
<pre><code>Registriere Klasse 'Child' (Factory-Map: 0x443168)
Registriere Klasse 'Child' (Factory-Map: 0x18733168)
Zerstöre Faktorie für Klasse 'Child' (Factory-Map: 0x18733168)
Ping
      5 [main] cl 3084 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)
</code></pre>
<p>Also nochmal zum Mitdenken: Es gibt letztlich zwei Factory-Maps. Eine in der Exe-Datei und eine in der <a href="http://Child.so" rel="nofollow">Child.so</a>. Wenn das Programm startet registriert sich die Klasse Child in der Factory-Map der Exe-Datei. Dann Lade ich die <a href="http://Child.so" rel="nofollow">Child.so</a> und dabei registriert sich die Klasse Child nochmal in der Factory-Map der Child.so-Datei. Dann schließe ich die <a href="http://Child.so" rel="nofollow">Child.so</a> wieder und destroy_factories() wird in der <a href="http://Child.so" rel="nofollow">Child.so</a> sauber aufgerufen und verrichtet wie es soll seinen Dienst. Zurück in der main()-Funktion kommt auch noch das Test-Ping, d.h. hier leben wir noch. Also schmiert das Programm ab, wenn es am Ende aufräumen will (wie ich mal annehme, wenn es die object_factory_map fac_map aus der Funktion static object_factory_map&amp; factory_map() zerstören will).</p>
<p>Habe ich hier irgendwo etwas offensichtlich falsch gemacht?</p>
<p>Ich habe versucht die Funktion static void __attribute__ ((destructor)) destroy_factories() mal auszukommentieren - es könnte ja sein, dass die auf etwas arbeiten will, dass es zu diesem Zeitpunkt gar nicht mehr gibt - aber das hilft nichts.<br />
Weg ist der Fehler, wenn ich die Inhalte der Funktionen static void addClass und static void __attribute__ ((destructor)) destroy_factories() auskommentiere. Dann wird ja factory_map() nie aufgerufen und die somit nie die statische object_factory_map fac_map erzeugt (weswegen ich ja annehme, das es beim Zerstören selbiger zum Problem kommt).</p>
<p>Für Hilfe und Tipps bin ich dankbar. Viele Grüße,<br />
Maik</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/218748/programmabsturz-beim-beenden</link><generator>RSS for Node</generator><lastBuildDate>Thu, 08 Oct 2026 23:44:52 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/218748.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 24 Jul 2008 16:21:07 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Programmabsturz beim Beenden on Thu, 24 Jul 2008 16:21:07 GMT]]></title><description><![CDATA[<p>Hallo Zusammen!</p>
<p>Ich bin gerade dabei meinen eigenen ClassLoader zu basteln (ich weiß, dass gibt es fertig, aber um meine C++-Fähigkeiten zu verbessern will ich es selbst machen). Dafür habe ich bis jetzt folgenden Code produziert (soweit zsuammengekürzt, dass der Fehler noch kommt):</p>
<p>child.hpp</p>
<pre><code class="language-cpp">#ifndef CHILD_HPP_
#define CHILD_HPP_

#include &lt;iostream&gt;
#include &lt;map&gt;

struct object_factories{};

template &lt;typename classtype&gt; struct object_factory : public object_factories {

	static classtype* new_instance() { return new classtype; }
	static void destroy_instance(classtype *&amp;ptr) { delete ptr; ptr = NULL; }

};

class instantiator {

	public:

		typedef std::map&lt;const char*, object_factories*&gt; object_factory_map;

		static void addClass(const char* className, object_factories* object_factory_ptr) { 
			std::cout &lt;&lt; &quot;Registriere Klasse '&quot; &lt;&lt; className &lt;&lt; &quot;' (Factory-Map: &quot; &lt;&lt; &amp;factory_map() &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
 			factory_map().insert(std::pair&lt;const char*, object_factories*&gt;(className, object_factory_ptr));
		}

		static void __attribute__ ((destructor)) destroy_factories() {
			for(object_factory_map::const_iterator i = factory_map().begin(); i != factory_map().end(); ++i) {
				std::cout &lt;&lt; &quot;Zerstöre Faktorie für Klasse '&quot; &lt;&lt; i-&gt;first &lt;&lt; &quot;' (Factory-Map: &quot; &lt;&lt; &amp;factory_map() &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
				object_factories *ptr = i-&gt;second; delete ptr;
			}
			factory_map().clear();
		}

	private:

		inline static object_factory_map&amp; factory_map() {
			static object_factory_map fac_map;
			return fac_map;
		}

};

class Child {

		Child();
		~Child();

};

// Registriere Klasse Child
namespace {

	template &lt;typename Context&gt; struct cl_reg_context { static bool placeholder; };
	template &lt;typename Context&gt; bool cl_reg_context&lt;Context&gt;::placeholder = false;

	template&lt;&gt; bool cl_reg_context&lt;Child&gt;::placeholder=(instantiator::addClass(&quot;Child&quot;, new object_factory&lt;Child&gt;), true);

}

#endif
</code></pre>
<p>child.cpp:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &quot;child.hpp&quot;

Child::Child() {}
Child::~Child() {}
</code></pre>
<p>main.cpp:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;dlfcn.h&gt;
#include &quot;child.hpp&quot;

int main() {

	void *handle = dlopen(&quot;./Child.so&quot;, RTLD_LAZY);
	dlclose(handle);

	std::cout &lt;&lt; &quot;Ping&quot; &lt;&lt; std::endl;

	return 0;
}
</code></pre>
<p>GNUmakefile</p>
<pre><code>all:
	g++ -g -Wall -shared -o Child.so child.cpp
	g++ -g -Wall -ldl main.cpp -o cl

clean:
	rm -f *.so cl cl.exe
</code></pre>
<p>Wenn ich das ganze nun übersetzte und Ausführe kommt folgende Ausgabe:</p>
<pre><code>Registriere Klasse 'Child' (Factory-Map: 0x443168)
Registriere Klasse 'Child' (Factory-Map: 0x18733168)
Zerstöre Faktorie für Klasse 'Child' (Factory-Map: 0x18733168)
Ping
      5 [main] cl 3084 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)
</code></pre>
<p>Also nochmal zum Mitdenken: Es gibt letztlich zwei Factory-Maps. Eine in der Exe-Datei und eine in der <a href="http://Child.so" rel="nofollow">Child.so</a>. Wenn das Programm startet registriert sich die Klasse Child in der Factory-Map der Exe-Datei. Dann Lade ich die <a href="http://Child.so" rel="nofollow">Child.so</a> und dabei registriert sich die Klasse Child nochmal in der Factory-Map der Child.so-Datei. Dann schließe ich die <a href="http://Child.so" rel="nofollow">Child.so</a> wieder und destroy_factories() wird in der <a href="http://Child.so" rel="nofollow">Child.so</a> sauber aufgerufen und verrichtet wie es soll seinen Dienst. Zurück in der main()-Funktion kommt auch noch das Test-Ping, d.h. hier leben wir noch. Also schmiert das Programm ab, wenn es am Ende aufräumen will (wie ich mal annehme, wenn es die object_factory_map fac_map aus der Funktion static object_factory_map&amp; factory_map() zerstören will).</p>
<p>Habe ich hier irgendwo etwas offensichtlich falsch gemacht?</p>
<p>Ich habe versucht die Funktion static void __attribute__ ((destructor)) destroy_factories() mal auszukommentieren - es könnte ja sein, dass die auf etwas arbeiten will, dass es zu diesem Zeitpunkt gar nicht mehr gibt - aber das hilft nichts.<br />
Weg ist der Fehler, wenn ich die Inhalte der Funktionen static void addClass und static void __attribute__ ((destructor)) destroy_factories() auskommentiere. Dann wird ja factory_map() nie aufgerufen und die somit nie die statische object_factory_map fac_map erzeugt (weswegen ich ja annehme, das es beim Zerstören selbiger zum Problem kommt).</p>
<p>Für Hilfe und Tipps bin ich dankbar. Viele Grüße,<br />
Maik</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1553142</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1553142</guid><dc:creator><![CDATA[maikg]]></dc:creator><pubDate>Thu, 24 Jul 2008 16:21:07 GMT</pubDate></item><item><title><![CDATA[Reply to Programmabsturz beim Beenden on Thu, 24 Jul 2008 17:29:55 GMT]]></title><description><![CDATA[<p>Brauch &quot;class instantiator&quot; nicht auch einen dtor??</p>
<p>sonst hätte ich keine idee,..</p>
<p>mfg</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1553174</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1553174</guid><dc:creator><![CDATA[zeusosc]]></dc:creator><pubDate>Thu, 24 Jul 2008 17:29:55 GMT</pubDate></item><item><title><![CDATA[Reply to Programmabsturz beim Beenden on Thu, 24 Jul 2008 17:35:30 GMT]]></title><description><![CDATA[<p>kA, obs daran liegt, so ganz seh ich bei deinem Code nicht durch:</p>
<p>nimm anstatt map&lt;const char*, ...&gt; map&lt;std::string, ...&gt;.</p>
<p>const char* kann man nicht einfach vergleichen und so, das geht niemals richtig mit const char* in einer std::map als key.</p>
<p>was soll zB das hier:</p>
<pre><code class="language-cpp">template&lt;&gt; bool cl_reg_context&lt;Child&gt;::placeholder=(instantiator::addClass(&quot;Child&quot;, new object_factory&lt;Child&gt;), true);
</code></pre>
<p>Rufst du da einen Komma-operator auf?</p>
<p>weiterhin: verwende lieber std::make_pair oder noch besser:</p>
<pre><code class="language-cpp">fac_map()[&quot;DieKlasse&quot;]=Ptr_Auf_Die_Fabrik;
</code></pre>
<p>Dann wird das ganze schon mal leichter zu durchschauen</p>
<p>Edit: ach und nochwas:<br />
Wie du siehst, wird deine Factory_map auch zweimal angelegt, d.h. die .so greift auf die in der .so zu, die executable greift auf eine ganz andere map zu.<br />
Hab jetz aber auch nich so die Ahnung was man da machen könnte. Und wie du auch siehst, wird nur eine Factorymap davon zerstört, damit kanns auch zusammenhängen</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1553175</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1553175</guid><dc:creator><![CDATA[Maxi]]></dc:creator><pubDate>Thu, 24 Jul 2008 17:35:30 GMT</pubDate></item><item><title><![CDATA[Reply to Programmabsturz beim Beenden on Thu, 24 Jul 2008 18:07:10 GMT]]></title><description><![CDATA[<p>Habe eure vorgeschlagenen Änderungen eingebracht, aber das Ergebnis ist noch das gleiche. (neuer Code unten dran)</p>
<p>Die Zeile</p>
<pre><code>template&lt;&gt; bool cl_reg_context&lt;Child&gt;::placeholder=(instantiator::addClass(&quot;Child&quot;, new object_factory&lt;Child&gt;), true);
</code></pre>
<p>habe ich mir an anderer Stelle geklaut. Hier geht es nur darum, dass ich die Funktion addClass aufrufen kann, obwohl ich an dieser Stelle gar nicht in einer Funktion bin.</p>
<p>Das die Factory-Map zweimal angelegt wird ist mir bewusst und auch durchaus beabsichtigt für den Zweck das man ja später eine Bibliothekt A in eine exe einbinden will und aber die Bibliothek A wiederum Bibliothek B benutzt usw. und dann hat jede Bibo ihre eigene Map.</p>
<p>Also hier der neue Code der child.hpp</p>
<pre><code class="language-cpp">#ifndef CHILD_HPP_
#define CHILD_HPP_

#include &lt;iostream&gt;
#include &lt;map&gt;
#include &lt;string&gt;

struct object_factories{};

template &lt;typename classtype&gt; struct object_factory : public object_factories {

	static classtype* new_instance() { return new classtype; }
	static void destroy_instance(classtype *&amp;ptr) { delete ptr; ptr = NULL; }

};

class instantiator {

	public:

		instantiator() {}
		~instantiator() {}

		typedef std::map&lt;std::string, object_factories*&gt; object_factory_map;

		static void addClass(const std::string className, object_factories* object_factory_ptr) { 
			std::cout &lt;&lt; &quot;Registriere Klasse '&quot; &lt;&lt; className &lt;&lt; &quot;' (Factory-Map: &quot; &lt;&lt; &amp;factory_map() &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
			factory_map()[className] = object_factory_ptr;
		}

		static void __attribute__ ((destructor)) destroy_factories() {
			for(object_factory_map::const_iterator i = factory_map().begin(); i != factory_map().end(); ++i) {
				std::cout &lt;&lt; &quot;Zerstöre Faktorie für Klasse '&quot; &lt;&lt; i-&gt;first &lt;&lt; &quot;' (Factory-Map: &quot; &lt;&lt; &amp;factory_map() &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
				object_factories *ptr = i-&gt;second; delete ptr;
			}
			factory_map().clear();
		}

	private:

		inline static object_factory_map&amp; factory_map() {
			static object_factory_map fac_map;
			return fac_map;
		}

};

class Child {

		Child();
		~Child();

};

namespace {

	template &lt;typename Context&gt; struct cl_reg_context { static bool placeholder; };
	template &lt;typename Context&gt; bool cl_reg_context&lt;Context&gt;::placeholder = false;

	template&lt;&gt; bool cl_reg_context&lt;Child&gt;::placeholder=(instantiator::addClass(&quot;Child&quot;, new object_factory&lt;Child&gt;), true);

}

#endif
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1553185</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1553185</guid><dc:creator><![CDATA[maikg]]></dc:creator><pubDate>Thu, 24 Jul 2008 18:07:10 GMT</pubDate></item><item><title><![CDATA[Reply to Programmabsturz beim Beenden on Fri, 25 Jul 2008 16:18:09 GMT]]></title><description><![CDATA[<p>Ich habe den Code jetzt so geändert, das die Object-Factory-Map auf dem Heap liegt. Jetzt läufts...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1553703</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1553703</guid><dc:creator><![CDATA[maikg]]></dc:creator><pubDate>Fri, 25 Jul 2008 16:18:09 GMT</pubDate></item></channel></rss>