I can't figure out why the code below is causing Segmentation Faults.
If I remove the call to pushLock.lock() and .unlock(), it runs fine.
#include <mutex>
#include <queue>
class FunctionQueue{
public:
FunctionQueue();
~FunctionQueue();
void pushInt(int);
private:
std::mutex pushLock;
int currentPushQueue;
std::queue<int> instructionQueues[2];
};
FunctionQueue::FunctionQueue(){
instructionQueues[0] = std::queue<int>();
instructionQueues[1] = std::queue<int>();
// pushLock.unlock();
}
FunctionQueue::~FunctionQueue(){}
void FunctionQueue::pushInt(int newArgument){
pushLock.lock();
instructionQueues[currentPushQueue].push(newArgument);
pushLock.unlock();
}
int main(int argc, char* argv[]){
FunctionQueue testQueue;
testQueue.pushInt(10);
}
The output from a gdb BackTrace was the very unhelpful:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x00007ffff347a291 in ?? () from /lib/x86_64-linux-gnu/libdl.so.2
#2 0x00007ffff347a6d7 in ?? () from /lib/x86_64-linux-gnu/libdl.so.2
#3 0x00007ffff347a198 in dlsym () from /lib/x86_64-linux-gnu/libdl.so.2
#4 0x00007ffff7904b3e in ?? () from /usr/lib/nvidia-331/libGL.so.1
#5 0x00007ffff78e8db4 in ?? () from /usr/lib/nvidia-331/libGL.so.1
#6 0x00007ffff7dea0fd in ?? () from /lib64/ld-linux-x86-64.so.2
#7 0x00007ffff7dea223 in ?? () from /lib64/ld-linux-x86-64.so.2
#8 0x00007ffff7ddb30a in ?? () from /lib64/ld-linux-x86-64.so.2
#9 0x0000000000000001 in ?? ()
#10 0x00007fffffffe8a6 in ?? ()
#11 0x0000000000000000 in ?? ()
Any help you can give would be excellent.
Thanks in advance.
Completely remove the commented out code in the constructor of your class as that shouldn't be there in the first place since you haven't locked anything. Problems with this are:
1. You haven't initialized or assigned the member variable 'currentPushQueue' to any value so this code:
instructionQueues[currentPushQueue].push(newArgument);
is completely wrong unless currentPushQueue is assigned.
2. You aren't using mutexs as they are meant to be used, which is with the provided wrappers (std::unique_lock/std::lock_guard).
Try this code and respond please:
#include <mutex>
#include <queue>
class FunctionQueue
{
public:
FunctionQueue();
~FunctionQueue();
void pushInt(int);
private:
std::mutex pushLock;
int currentPushQueue = 0; // Set this variable somehow
std::queue<int> instructionQueues[2];
};
FunctionQueue::FunctionQueue()
{
instructionQueues[0] = std::queue<int>();
instructionQueues[1] = std::queue<int>();
}
FunctionQueue::~FunctionQueue() {}
void FunctionQueue::pushInt(int newArgument)
{
std::unique_lock<std::mutex> mutexLock(pushLock);
instructionQueues[currentPushQueue].push(newArgument);
// Unlocks automatically
}
int main(int argc, char* argv[])
{
FunctionQueue testQueue;
testQueue.pushInt(10);
}
Related
gtk_init caused crash on ubuntu 16.04 if run program without sudo. If run with sudo, then have not problem. On other ubuntu versions also have not problem with and without sudo.
Minimally reproducible example:
#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
gtk_init (&argc, &argv);
for (int i = 0; i < 10; ++i)
{
printf("%d\n", i);
usleep(1000 * 1000);
}
return 0;
}
Stacktrace:
Thread 2 "dconf worker" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb6567b40 (LWP 6735)]
0xb71bbfd0 in g_source_set_ready_time () from /lib/i386-linux-gnu/libglib-2.0.so.0
(gdb) bt
#0 0xb71bbfd0 in g_source_set_ready_time () from /lib/i386-linux-gnu/libglib-2.0.so.0
#1 0xb73e8bf4 in g_task_get_type () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#2 0xb744b6a0 in ?? () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#3 0xb743eb00 in ?? () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#4 0xb73bd0e9 in g_initable_init () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#5 0xb743f230 in g_bus_get_sync () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#6 0xb668c314 in ?? () from /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#7 0xb668c423 in ?? () from /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#8 0x0807e22a in g_main_context_dispatch ()
#9 0x0807e638 in g_main_context_iterate.isra ()
#10 0x0807e700 in g_main_context_iteration ()
#11 0xb668c58b in ?? () from /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#12 0x0809eabd in g_thread_proxy ()
#13 0xb7aaf295 in start_thread (arg=0xb6567b40) at pthread_create.c:333
#14 0xb79d10ae in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:114
I tried to compare strace output with sudo and without - without sudo is being created problem thread dconf worker, but if run with sudo it thread is not being created and programm work correctly
What can be done to fix this problem?
UPD: Stacktrace with `libglib2.0-0-dbg
Thread 2 "dconf worker" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb6567b40 (LWP 3574)]
0xb71bbfd0 in g_source_set_ready_time (source=0xb5c09938, ready_time=-1)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./glib/gmain.c:1786
1786 /build/glib2.0-2aRhhS/glib2.0-2.48.2/./glib/gmain.c: No such file or directory.
(gdb) bt
#0 0xb71bbfd0 in g_source_set_ready_time (source=0xb5c09938, ready_time=-1)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./glib/gmain.c:1786
#1 0xb73e8bf4 in g_task_get_type () at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gtask.c:1907
#2 0xb73e8bf4 in g_task_get_type () at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gtask.c:590
#3 0xb744b6a0 in _g_dbus_worker_new () at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusprivate.c:227
#4 0xb744b6a0 in _g_dbus_worker_new () at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusprivate.c:267
#5 0xb744b6a0 in _g_dbus_worker_new (stream=0xb5c016c8, capabilities=G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING, initially_frozen=0, message_received_callback=0xb7438400 <on_worker_message_received>, message_about_to_be_sent_callback=0xb7435eb0 <on_worker_message_about_to_be_sent>, disconnected_callback=0xb74359c0 <on_worker_closed>, user_data=0xb5c04818)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusprivate.c:1649
#6 0xb743eb00 in initable_init (initable=0xb5c04818, cancellable=0x0, error=0xb6567068)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusconnection.c:2573
#7 0xb73bd0e9 in g_initable_init (initable=0xb5c04818, cancellable=0x0, error=0xb6567068)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/ginitable.c:112
#8 0xb743f230 in g_bus_get_sync (bus_type=G_BUS_TYPE_SESSION, cancellable=0x0, error=0xb6567068)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusconnection.c:7254
#9 0xb668c314 in () at /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#10 0xb668c423 in () at /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#11 0x0807e22a in g_main_context_dispatch ()
#12 0x0807e638 in g_main_context_iterate.isra ()
#13 0x0807e700 in g_main_context_iteration ()
#14 0xb668c58b in () at /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#15 0x0809eabd in g_thread_proxy ()
#16 0xb7aaf295 in start_thread (arg=0xb6567b40) at pthread_create.c:333
#17 0xb79d10ae in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:114
Unset GTK2_MODULES, GTK_MODULES and GTK_IM_MODULE fixed this problem, but i don't understend why it work
#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
unsetenv("GTK2_MODULES");
unsetenv("GTK_MODULES");
unsetenv("GTK_IM_MODULE");
gtk_init (&argc, &argv);
for (int i = 0; i < 10; ++i)
{
printf("%d\n", i);
usleep(1000 * 1000);
}
return 0;
}
Hy,
i have a gtkmm application, which does some async network-requests, to ask the server for additional properties of the gtk-widgets.
This means for example, that the application should be able to change the label of a widget.
In this example I have created a new widget based on Gtk::ToggleButton.
But I found out that sometimes the gtkmm-application crashes with a segfault. When debuging with gdb I always get the line where i set the label.
For better understanding, I have created a MWE which does the label-changes in a loop, to simulate lots of async-calls:
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <iostream>
#include <thread>
#include <mutex>
#include <gtkmm/application.h>
#include <gtkmm/window.h>
#include <gtkmm/togglebutton.h>
class led_label_t : public Gtk::ToggleButton {
public:
using value_list_t = std::vector<Glib::ustring>;
using lock_t = std::lock_guard<std::mutex>;
led_label_t(Glib::ustring label = "<no data>", bool mnemonic = false)
: Gtk::ToggleButton(std::move(label), std::move(mnemonic)),
_values{"SEL1", "SEL2"} {}
protected:
virtual void on_toggled(void) override {
std::cout << "Clicked Button." << std::endl;
lock_t lock(_mtx);
value_changed(_values[get_active()]);
}
virtual void value_changed(Glib::ustring& value) {
std::string path;
if (get_active()) {
path =
"/usr/share/icons/Adwaita/16x16/emblems/emblem-important.png";
} else {
path = "/usr/share/icons/Adwaita/16x16/emblems/emblem-default.png";
}
remove(); // remove previous label
std::cout << "Changed Label of led_label: "
<< ", value: " << value << std::endl;
add_pixlabel(path, value);
}
private:
mutable std::mutex _mtx;
value_list_t _values;
};
int main(void) {
auto app = Gtk::Application::create();
Gtk::Window window;
window.set_default_size(200, 200);
led_label_t inst{};
inst.show();
window.add(inst);
auto f = [&inst, &window]() {
using namespace std::chrono_literals;
boost::asio::io_service io;
{ //wait for startup
boost::asio::steady_timer t{io, 100ms};
t.wait();
}
bool toggle = true;
for (auto i = 0; i < 2000; i++) {
std::cout << "i=" << i << std::endl;
//wait until next simulated button click
boost::asio::steady_timer t{io, 1ms};
t.wait();
inst.set_active(toggle);
toggle = !toggle;
}
};
std::thread c1(f);
std::thread w([&app, &window]() { app->run(window); });
c1.join();
window.hide();
w.join();
return EXIT_SUCCESS;
}
To compile this example, I use following command:
g++ main.cpp -o main `pkg-config --cflags --libs gtkmm-3.0` -Wall -pedantic -Wextra -Werror -Wcast-qual -Wcast-align -Wconversion -fdiagnostics-color=auto -g -O0 -std=c++14 -lboost_system -pthread
I am using GCC 4.9.2 and libgtkmm-3.14 (both standard debian jessie)
The segfault I get is the following:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe7fff700 (LWP 7888)]
0x00007ffff6288743 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
(gdb) bt
#0 0x00007ffff6288743 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#1 0x00007ffff6288838 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#2 0x00007ffff6267ce9 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#3 0x00007ffff627241b in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#4 0x00007ffff63a1601 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#5 0x00007ffff63a154c in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#6 0x00007ffff63a26b8 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#7 0x00007ffff644d5ff in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#8 0x00007ffff644d9b7 in gtk_widget_realize ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#9 0x00007ffff644dbe8 in gtk_widget_map ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#10 0x00007ffff621c387 in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#11 0x00007ffff626270f in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#12 0x00007ffff46bf474 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#13 0x00007ffff46d9087 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#14 0x00007ffff46d99df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#15 0x00007ffff644db99 in gtk_widget_map ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#16 0x00007ffff64506d8 in gtk_widget_set_parent ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#17 0x00007ffff6217a9b in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#18 0x00007ffff79a44eb in Gtk::Container_Class::add_callback(_GtkContainer*, _GtkWidget*) () from /usr/lib/x86_64-linux-gnu/libgtkmm-3.0.so.1
#19 0x00007ffff46c253b in g_cclosure_marshal_VOID__OBJECTv ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#20 0x00007ffff46bf474 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#21 0x00007ffff46d9087 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#22 0x00007ffff46d99df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#23 0x00007ffff6261aa5 in gtk_container_add ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#24 0x000000000040b0b5 in led_label_t::value_changed (this=0x7fffffffe2a0,
value=...) at main.cpp:38
#25 0x000000000040afb1 in led_label_t::on_toggled (this=0x7fffffffe2a0)
at main.cpp:24
#26 0x00007ffff7a18af0 in Gtk::ToggleButton_Class::toggled_callback(_GtkToggleButton*) () from /usr/lib/x86_64-linux-gnu/libgtkmm-3.0.so.1
#27 0x00007ffff46bf245 in g_closure_invoke ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#28 0x00007ffff46d083b in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#29 0x00007ffff46d9778 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#30 0x00007ffff46d99df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#31 0x00007ffff63ecb4d in ?? () from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#32 0x00007ffff798a4a0 in Gtk::Button_Class::clicked_callback(_GtkButton*) ()
from /usr/lib/x86_64-linux-gnu/libgtkmm-3.0.so.1
#33 0x00007ffff46bf474 in ?? ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#34 0x00007ffff46d9087 in g_signal_emit_valist ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#35 0x00007ffff46d99df in g_signal_emit ()
from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#36 0x00007ffff63ec936 in gtk_toggle_button_set_active ()
from /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#37 0x0000000000405e12 in <lambda()>::operator()(void) const (
__closure=0x74f4f8) at main.cpp:73
#38 0x000000000040811a in std::_Bind_simple<main()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>) (this=0x74f4f8) at /usr/include/c++/4.9/functional:1700
#39 0x0000000000407fa9 in std::_Bind_simple<main()::<lambda()>()>::operator()(void) (this=0x74f4f8) at /usr/include/c++/4.9/functional:1688
#40 0x0000000000407e9e in std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> >::_M_run(void) (this=0x74f4e0) at /usr/include/c++/4.9/thread:115
#41 0x00007ffff3f47970 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#42 0x00007ffff37650a4 in start_thread (arg=0x7fffe7fff700)
at pthread_create.c:309
#43 0x00007ffff349a04d in clone ()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Maybe the Interesting line of this is
#24: 0x000000000040b0b5 in led_label_t::value_changed (this=0x7fffffffe2a0,
value=...) at main.cpp:38)
this is the line where add_pixlabel(path, value); is called.
What am I doing wrong here?
Attention:
This segfault doesn't come always, I found out, that on my desktop-machine I get the error once every 10 calls. (Intel i7-3xxx)
And on my laptop I get the error nearly every call (Intel i5-3xxx)
Now I have found a solution, based on the answer of #user4581301. He was right, that gtkmm doesn't support multithreading. (To be more precise, libsigc++ and sigc::trackable are not thread-safe)
However, care is required when writing programs based on gtkmm using
multiple threads of execution, arising from the fact that libsigc++,
and in particular sigc::trackable, are not thread-safe.
Quote from gtkmm documentation.
Therefore I have used Glib::Dispatcher, to execute the set_label() - method in the context of the gtkmm-Main-Loop of the window.
Here is the code, that did not segfault anymore on my machine(s) (even with many retries)
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <cassert>
#include <iostream>
#include <thread>
#include <mutex>
#include <gtkmm/application.h>
#include <gtkmm/window.h>
#include <gtkmm/togglebutton.h>
#include <glibmm/dispatcher.h>
#define LOG() \
std::cout << (std::chrono::system_clock::now() - start).count() << " " \
<< std::this_thread::get_id() << ": "
auto start = std::chrono::system_clock::now();
class led_label_t : public Gtk::ToggleButton {
public:
using value_list_t = std::vector<Glib::ustring>;
using lock_t = std::lock_guard<std::mutex>;
using action_queue_t = std::vector<Glib::ustring>;
led_label_t(Glib::ustring label = "<no data>", bool mnemonic = false)
: Gtk::ToggleButton(std::move(label), std::move(mnemonic)),
_values{"SEL1", "SEL2"} {}
void set_dispatcher(Glib::Dispatcher* dp) {
_dp = dp;
_dp->connect([this](void) { dispatcher_task(); });
}
protected:
virtual void on_toggled(void) override {
LOG() << "Clicked Button." << std::endl;
{
lock_t lock(_action_mtx);
auto value = _values[get_active()];
_action_queue.push_back({value});
LOG() << "Added label into queue " << value << std::endl;
if (_action_queue.size() > 1) {
return;
}
}
_dp->emit();
}
void dispatcher_task(void) {
Glib::ustring label;
for (;;) {
{
lock_t lock(_action_mtx);
if (_action_queue.size() == 0) {
return;
}
label = *_action_queue.begin();
_action_queue.erase(_action_queue.begin());
}
set_label(label);
LOG() << "Set the label " << label << std::endl;
}
}
private:
mutable std::mutex _action_mtx;
action_queue_t _action_queue;
value_list_t _values;
Glib::Dispatcher* _dp;
};
int main(void) {
auto app = Gtk::Application::create();
Gtk::Window window;
window.set_default_size(200, 200);
led_label_t inst{};
inst.show();
window.add(inst);
auto f = [&inst, &window]() {
using namespace std::chrono_literals;
boost::asio::io_service io;
{ // wait for startup
boost::asio::steady_timer t{io, 100ms};
t.wait();
}
bool toggle = true;
for (auto i = 0; i < 200000; i++) {
// wait until next simulated button click
boost::asio::steady_timer t{io, 250us};
t.wait();
LOG() << "i=" << i << std::endl;
inst.set_active(toggle);
toggle = !toggle;
LOG() << "finished" << std::endl;
}
};
std::thread c1(f);
std::thread w([&app, &window, &inst]() {
Glib::Dispatcher dp;
inst.set_dispatcher(&dp);
app->run(window);
});
c1.join();
window.hide();
w.join();
return EXIT_SUCCESS;
}
Accessing and changing UI components from multiple threads is always tricky. UIs need to be fast and responsive to user input, so they can't hang around for background tasks to complete. As a result UI components are rarely protected by mutex or other synchronization. You write, it happens. Except when something else gets in the way.
If you write from two threads... Ooops.
You're half way through a write when another thread reads... Ooops.
Say for example Thread 4 is part way through writing a new string into the label when a screen refresh is triggered. If the backend for label is a c-style string, the terminating NULL may have been overwritten and the label write runs off the end into bad RAM.
All sorts of things could go wrong, and some will be survivable or, worse, look like it. You're better off having all of the UI management in one thread and have the other threads queue updates to the UI thread. Start by looking into Model View Controller and then try related patterns if needed.
I'm having trouble using boost_threads with clang. The clang version is 3.6.0 and boost version is 1.55.0 from the new Ubuntu 15.04. Program that used to work with previous versions of clang now segfaults at startup. There is no problems when I use g++ instead.
Here is an example program to illustrate the point.
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
void output() {
try {
int x = 0;
for (;;) {
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
cerr << x++ << endl;
}
} catch (boost::thread_interrupted&) {}
}
int main(int argc, char* argv[]) {
try {
boost::thread output_worker(output);
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
output_worker.interrupt();
output_worker.join();
} catch (...) {
cerr << "Unexpected error!" << endl;
exit(1);
}
}
If I compile it with g++ it works, i.e.
g++ thread.cpp -lboost_thread -lboost_system
If I compile it with clang
clang++ thread.cpp -lboost_thread -lboost_system
I get a segfault with the gdb trace below
Starting program: /home/dejan/test/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bd0580 in boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_alloc_>() ()
from /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.55.0
(gdb) bt
#0 0x00007ffff7bd0580 in boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_alloc_>() ()
from /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.55.0
#1 0x00007ffff7bcb16a in ?? () from /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.55.0
#2 0x00007ffff7de95ba in call_init (l=<optimized out>, argc=argc#entry=1, argv=argv#entry=0x7fffffffdf98, env=env#entry=0x7fffffffdfa8)
at dl-init.c:72
#3 0x00007ffff7de96cb in call_init (env=<optimized out>, argv=<optimized out>, argc=<optimized out>, l=<optimized out>) at dl-init.c:30
#4 _dl_init (main_map=0x7ffff7ffe188, argc=1, argv=0x7fffffffdf98, env=0x7fffffffdfa8) at dl-init.c:120
#5 0x00007ffff7dd9d0a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#6 0x0000000000000001 in ?? ()
#7 0x00007fffffffe2fe in ?? ()
#8 0x0000000000000000 in ?? ()
Am I doing something wrong?
Compiling using clang -std=c++11 makes boost change its internal implementation and actually solves the segmentation fault.
It is not an ideal solution, but it is the way I will be going with our code.
Update: the previous code does not accurately describe my problem. Now changed:
Below is a few lines of code of my program (C++ on Linux). My program often (but not always) crashes at the lines LINE_A and LINE_B
class A{
//...
map<int, const string> m_int2StrMap;
//...
void problematic(){
//...insert and erase of m_int2StrMap are involved
char temp[6] = {0};
int key = 12345;
//...temp's elements and key might be changed
map<int, const string>::iterator iter = this->m_int2StrMap.find(key);
if(iter != this->m_int2StrMap.end())
{
/*LINE_A*/ this->m_int2StrMap.erase(iter);
}
/*LINE_B*/ this->m_int2StrMap.insert(pair<int, const string>(key, string ((const char*)temp, 6)));
//...
}
//...
}
I used gdb to backtrack the core dumps generated, some gave me this info:
(gdb) bt
#0 0x00ae0410 in __kernel_vsyscall ()
#1 0x00138df0 in vfprintf () from /lib/libc.so.6
#2 0x0013a701 in vfprintf () from /lib/libc.so.6
#3 0x0017128b in __wcstod_internal () from /lib/libc.so.6
#4 0x00179595 in ____wcstof_l_internal () from /lib/libc.so.6
#5 0x001799d9 in ____wcstof_l_internal () from /lib/libc.so.6
#6 0x05bfd581 in operator delete () from /usr/lib/libstdc++.so.6
#7 0x05bda14d in std::string::_Rep::_M_destroy () from /usr/lib/libstdc++.so.6
#8 0x08084bf7 in problematic() at /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/basic_string.h:233
and some showed:
(gdb) bt
#0 0x00b81410 in __kernel_vsyscall ()
#1 0x009ccdf0 in vfprintf () from /lib/libc.so.6
#2 0x009ce701 in vfprintf () from /lib/libc.so.6
#3 0x00a0528b in __wcstod_internal () from /lib/libc.so.6
#4 0x00a0e250 in ____wcstof_l_internal () from /lib/libc.so.6
#5 0x00a0fd87 in wcsxfrm_l () from /lib/libc.so.6
#6 0x05bfeab7 in operator new () from /usr/lib/libstdc++.so.6
#7 0x05bda0fb in std::string::_Rep::_S_create () from /usr/lib/libstdc++.so.6
#8 0x05bdaef5 in ?? () from /usr/lib/libstdc++.so.6
#9 0x05bdaff1 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string () from /usr/lib/libstdc++.so.6
#10 0x080843e4 in probblematic() at bad.cpp:LINE_B
Is there anything unsafe in my code shown above? Thanks
I'm having trouble figuring out the problem with my code...I'm in the early stages of prototyping a game (my first serious project). It frequently, but not always, crashes with a segmentation fault. Here's the flow of the program...
title screen - press z to start new game
player and enemy on screen...enemy takes a life when collided with, there are 4 lives.
when character's life is 0, game goes back to title screen - press z to start new game
The last step is where the crash occurs...The crash only seems to happen after the player dies and is brought back to the title screen and the player presses z to start another game, but it doesn't always crash. Through gdb, I've determined that it happens when the deconstructor for Title is called...
Here's the debug info and relevant code...I'll provide any other code/info if requested.
*** glibc detected *** /home/rzrscm/code/demogamething/game: free(): invalid pointer: 0x080c6b98 ***
//memory map info omitted
0xb7c54537 in raise () from /lib/libc.so.6
(gdb) where
#0 0xb7c54537 in raise () from /lib/libc.so.6
#1 0xb7c57922 in abort () from /lib/libc.so.6
#2 0xb7c8afbd in ?? () from /lib/libc.so.6
#3 0xb7c950ca in ?? () from /lib/libc.so.6
#4 0xb7c96918 in ?? () from /lib/libc.so.6
#5 0xb7c99a5d in free () from /lib/libc.so.6
#6 0xb7f4e776 in SDL_FreeSurface () from /usr/lib/libSDL-1.2.so.0
#7 0x0804ac7f in ~Title (this=0x80b4250, __in_chrg=<value optimized out>) at title.cpp:13
#8 0x08049d3a in GameState::load (this=0x804e368, loadState=LEVEL) at gamestate.cpp:39
#9 0x08049c5c in GameState::change (this=0x804e368, changeTo=LEVEL) at gamestate.cpp:26
#10 0x08049753 in Player::handleEvent (this=0x804e300) at player.cpp:102
#11 0x080490c8 in main () at main.cpp:27
So, what I know is that the crash occurs when it's changing states from TITLE to LEVEL...Here's the class function that unloads and loads the states...currentState is a private vector in the GameState class...
std::vector<GameState *> currentState;
void GameState::load(STATE loadState) {
if(state == TITLE) {
while(!currentState.empty()) {
delete currentState.back();
currentState.pop_back();
}
currentState.push_back(new Title());
}
else if(state == LEVEL) {
while(!currentState.empty()) {
delete currentState.back();
currentState.pop_back();
}
currentState.push_back(new Level(currentLevel));
}
}
The crash happens when the deconstructor for the Title class is called...It happens whether it's freeing the music or the image...Whichever one is the first function is the one it crashes on.
Title::~Title() {
SDL_FreeSurface(background);
Mix_FreeMusic(music);
background = NULL;
music = NULL;
}
Here's the code for the image loading function...
SDL_Surface *loadImage(std::string imageFile) {
SDL_Surface *loadedImage;
SDL_Surface *newImage;
loadedImage = IMG_Load(imageFile.c_str());
newImage = SDL_DisplayFormatAlpha(loadedImage);
SDL_FreeSurface(loadedImage);
return newImage;
}
[edit] I ran it through the debugger a couple more times without making changes to the code since I still can't find what's wrong...And each time the crash occurred while trying to free the music...
0xb7c54537 in raise () from /lib/libc.so.6
(gdb) backtrace
#0 0xb7c54537 in raise () from /lib/libc.so.6
#1 0xb7c57922 in abort () from /lib/libc.so.6
#2 0xb7c8afbd in ?? () from /lib/libc.so.6
#3 0xb7c950ca in ?? () from /lib/libc.so.6
#4 0xb7c9633e in ?? () from /lib/libc.so.6
#5 0xb79974e2 in ?? () from /usr/lib/libmikmod.so.2
#6 0xb7997640 in Player_Free () from /usr/lib/libmikmod.so.2
#7 0xb7ebb6e3 in Mix_FreeMusic () from /usr/lib/libSDL_mixer-1.2.so.0
#8 0x0804ac8d in ~Title (this=0x80c6bc0, __in_chrg=<value optimized out>) at title.cpp:14
#9 0x08049d3a in GameState::load (this=0x804e368, loadState=LEVEL) at gamestate.cpp:39
#10 0x08049c5c in GameState::change (this=0x804e368, changeTo=LEVEL) at gamestate.cpp:26
#11 0x08049753 in Player::handleEvent (this=0x804e300) at player.cpp:102
#12 0x080490c8 in main () at main.cpp:27
#5 0xb7c99a5d in free () from /lib/libc.so.6
#6 0xb7f4e776 in SDL_FreeSurface () from /usr/lib/libSDL-1.2.so.
You are probably freeing a pointer which is invalid. Now I read
free(): invalid pointer: 0x080c6b98
You might be trying to free an object which was not allocated dynamically. How does background get his value?