Why do I get "Segmentation fault (core dumped)" error when trying to implement multithreading in c++? - c++

I have a main file where I plan to initiate the threads for my c++ program, for now, I only want to get one of the threads up and running before moving on to the others, but that is proving to be difficult. The purpose of the threads is for a TCP Server and Client to run at the same time, I have already tested my TCP code and it works, the issue now is running each one in its own thread. The following shows my main.cpp code:
#include <thread>
#include <iostream>
#include <functional>
#include "./hdr/tcpip_server.hpp"
#include "./hdr/tcpip_client.hpp"
using namespace std;
tcpServer *backendServer;
//This is done because the callback function of std::thread tcpip_server_thread complains when I only use 'backendServer->Monitor' as my callback function
void StartThread (void) {backendServer->Monitor();}
int main (void)
{
/*Initiate and start TCP server thread*/
std::thread tcpip_server_thread; // done to define object to be used outside the scope of the if statement below
if (backendServer->Init())
{
std::thread tcpip_server_thread (StartThread);
}
/*Initiate and start data reader thread*/
//std::thread tcpip_client_thread (tcpip_client);
tcpip_server_thread.join();
//tcpip_client_thread.join();
return 0;
}
The backendServer class is as follows:
class tcpServer
{
private:
int listening;
sockaddr_in hint;
sockaddr_in client;
socklen_t clientSize;
int clientSocket;
char host[NI_MAXHOST];
char service[NI_MAXSERV];
char buf[4096];
public:
bool Init ();
void Monitor ();
};
The only error I am getting with this code is the one in the title, and I only get it when the code is executing, no errors are received while compiling the code.
When trying the following:
std::thread tcpip_server_thread (backendServer->Monitor);
I get the following warning:
a pointer to a bound function may only be used to call the function
and
no instance of constructor "std::thread::thread" matches the argument list
Any help would be appreciated as this is my first project implementing threads.

1. Initializing backendServer:
backendServer is a pointer to tcpServer, but it is uninitialized (and does not point to any valid object).
Therefore backendServer->Init(); invokes UB Undefined Behavior, and likely to crash.
If you must use a pointer you must allocate it. Better still use a smart pointer like std::unique_ptr instead.
But in your case I believe the best solution is not to use a pointer at all, and define backendServer as a local variable in main:
int main(void)
{
tcpServer backendServer;
// ...
}
This will require accessing it with backendServer. instead of backendServer->.
2. The thread issue:
At the moment, you have 2 tcpip_server_thread variables.
The 2nd one inside the if is shadowing the 1st one you have before.
When you get out of the if's scope, the 2nd tcpip_server_thread will be destroyed, and a std::thread must be joined before destruction.
Later on you attempt to join the 1st one which has not even started, causing a 2nd problem.
In order to fix it:
Inside the if, do not declare a new variable. Instead use the one you already have:
tcpip_server_thread = std::thread(StartThread);
If you made backendServer a local in main as suggested above, you can use a lambda that captures it by reference:
tcpip_server_thread = std::thread(
[&backendServer]() { backendServer.Monitor();});
//--------------^^^^^^^^^^^^^^---------------------------------
Before you join the thread check that it is joinable. In the current code this will not be the case if you didn't enter the if that started the thread:
if (tcpip_server_thread.joinable())
{
tcpip_server_thread.join();
}
A side note: Why is "using namespace std;" considered bad practice?.

The main issue of your code is an uninitialised (actually: zero-initialised) pointer:
tcpServer *backendServer;
Note that you never assign a value to! This results in (as a global variable) the pointer being initialised to nullptr, which you dereference illegally later on, e.g. at (the first time during the programme run)
if (backendServer->Init())
which most likely caused the crash. A quick and dirty fix might look as:
int main()
{
backendServer = new tcpServer(); // possibly with arguments, depending
// on how your constructor looks like
// the code you have so far
delete backendServer; // avoid memory leak!!!
return 0;
}
You spare all this hassle around manual memory management (-> explicit delete) if you use smart pointers instead, e.g. std::unique_ptr. However unless you possibly want to dynamically exchange the backend server, limit its life-time to anything else than the entire programme run or construct it with arguments that need to be retrieved/calculated within main before (none of appears pretty likely to me in given case) then you most likely are better off with a global object:
tcpServer backendServer; // note the dropped asterisk!
This way the object is created before entering main and correctly destructed after leaving.
As now no pointer any more you now refer to members via . instead of ->, i.e. backendServer.Monitor() for instance.
You actually can construct a std::thread with member function pointers, too. You need, though, to pass the object on which this member function should get called to the thread as well:
std::thread(&tcpServer::Monitor, backendServer);
This works with both functions and objects, the latter are accepted by value, though, thus if you use a global object as recommended above you might rather want to create a pointer:
std::thread(&tcpServer::Monitor, &backendServer);
// ^ (!)
// note: NOT if your variable remains a pointer!!!
This way you can actually spare the global variable entirely and create the object within main and the StartThread (actually you should better have named it RunThread) gets entirely obsolete as well.
Alternatives to are converting Monitor function into an operator() or adding such one as
void tcpServer::operator()()
{
this->Monitor();
}
which makes the object itself callable, thus you could pass it directly to the thread's constructor (std::thread(std::ref(backendServer)); with std::ref preventing the object getting copied) or using a lambda:
std::thread([&]() { backendServer.Monitor(); });
both with the same advantage as providing the member function that you can spare global variable and StartThread function.
Still your code reveals another problem:
if (backendServer->Init())
{
std::thread tcpip_server_thread(StartThread);
}
You create here a second local variable tcpip_server_thread which, as long as it exists, hides the previous one, but which runs out of scope and thus gets destructed again right after the end of the if-body!
Instead you want to assign the newly created thread to the already existing variable, which would look like:
tcpip_server_thread = std::thread(StartThread);
Actually you get nicer code if you move the entire thread-code into the if block:
// no thread code left here any more
if(backendServer->Init())
{
std::thread tcpip_server_thread(StartThread);
// start second thread here, too!
tcpip_server_thread.join();
}
// no thread code left here any more
Finally you should not join a thread that actually has failed to start. You spot this by checking if the thread is joinable
std::thread tcpip_server_thread (StartThread);
if(tcpip_server_thread.joinable())
{
// see above for correct construction!
std::thread tcpip_client_thread(tcpip_client);
if(tcpip_client_thread.joinable())
{
tcpip_server_thread.join();
}
else
{
// you might need some appropriate error handling like
// printing/logging a warning message
// and possibly stop the server thread
}
}
else
{
error handling, see above
}

To fix the code I had to do 2 things, one was to not define the tcpServer variable, backendServer, as a pointer, since I never pointed it toward an actual object of the type tcpServer.
Next, I removed the first tcpip_server_thread variable and made sure that the code that initiates ```tcpip_server_thread`` and the code that joins it is in the same scope. In the future, I will implement the std::move function as explained by #wohlstad.
My working code:
#include <thread>
#include <iostream>
#include <functional>
#include "./hdr/tcpip_server.hpp"
#include "./hdr/tcpip_client.hpp"
using namespace std;
/*All the threads*/
tcpServer backendServer;
void StartThread (void) {backendServer.Monitor();}
int main (void)
{
/*Initiate and start tcp server thread*/
if (backendServer.Init())
{
std::thread tcpip_server_thread (StartThread);
if (tcpip_server_thread.joinable())
{
tcpip_server_thread.join();
}
else
{
cout << "error";
}
}
return 0;
}

Related

c++ capture ctrl+c without using globals

I have simplified my example for an easier explanation. I am writing an application that counts to 100 but at any given time I allow the user to cancel the program by entering ctrl+c through the keyboard.
What seemingly started as a simple program quickly became complicated based on my lack of knowledge on function pointers. This is what I'm attempting to do:
Capture the SIGINT signal when ctrl+c is pressed.
Once captured, call a member function that shuts down a third-party resource.
The catch is that unlike the two examples that Michael Haidl and Grijesh Chauhan give on capturing SIGINT, I am not permitted to store any global variables. The ideal scenario is one in which all variables and function calls related to signal() are encapsulated within a class of mine.
Here's my modified attempt based on Haidl and Grijesh's code:
#include <thread>
#include <chrono>
#include <functional>
#include <iostream>
#include <signal.h>
class MyClass {
public:
volatile sig_atomic_t cancel = 0;
void sig_handler(int signal) {
cancel = true;
this->libCancel();
}
void libCancel() { std::cout << "Cancel and cleanup" << std::endl; }
};
int main(int argc, char *argv[]) {
MyClass mc;
//using std::placeholders::_1;
//std::function<void(int)> handler = std::bind(&MyClass::sig_handler, mc, _1);
//signal(SIGINT, handler);
signal(SIGINT, &mc.sig_handler); // **compiler error**
for (int i = 0; !mc.cancel && i < 100; ++i)
{
std::cout << i << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
As you can see, I'd like the code to simply count to 100 and exit if all goes well. But if the user calls ctrl+c then the class should handle SIGINT, call the external library for cleanup, and the for loop will exit.
The main problem is that I can't seem to setup the signal() declaration to bind to my instance of MyClass::sig_handler. I even tried casting my member function to std::function to be used by signal(), commented out, but the compiler isn't happy about the fact that C++ function<void(int)> isn't equivalent to the C lang void (*)(int).
Any and all criticism is welcome. I'm not at all tied to what I've written and I clearly don't have a great fundamental understanding of how to use function pointers with member functions.
It is not possible to communicate between the signal handler and the rest of the program using local variables. No parameters are passed into the handler other than the raised signal and the handler returns no value.
The words "global variables" are somewhat ambiguous. People sometimes mean different things depending on context. If your restriction applies only to the global scope, then simply use a volatile sig_atomic_t within some namespace. Or use static member variable, if you so prefer.
If your restriction applies to static storage duration, then you can use a thread local variable instead.
If your restriction applies to all global memory, then your problem is unsolvable using a signal handler. You simply need a global variable of some sort.
If you can rely on POSIX rather than C++ standard, A way to handle SIGINT without globals is to make sure that it is not handled, and block the thread with sigwait. If the call returns SIGINT, then stop the program, otherwise do what you want to do with the signal that was caught.
Of course, this means that the blocking thread doesn't do anything other than wait for signals. You'll need to do the actual work in other thread(s).
Technically though, global memory is probably still used. The use is simply hidden inside system library.
Furthermore, it is not safe to use std::cout within a signal handler. I know that is only an example, but "call the external library for cleanup" is very likely also async signal unsafe.
This can be fixed simply by calling the cleanup outside the for loop rather than inside the handler.
The main problem is that I can't seem to setup the signal() declaration to bind to my instance of MyClass::sig_handler.
That's because signal requires a function pointer (of type void(int)). Non-static member functions cannot be pointed by function pointers. They can only be pointed by member function pointers, which signal doesn't accept.

c++ class method thread [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 6 years ago.
i have a class that has a method that needs to be running continuously but also be able to receive input from user. So i thought i would make the method run separately using a thread.
the code looks something like this(just the backbone):
class SystemManager
{
private:
int command;
bool commandAcK;
bool running;
//other vars
public:
SystemManager()
{
//initialisation
}
void runningAlgorithm()
{
while (running)
{
if (commandAcK)
{
//solve command
}
//run algorithm
//print results
}
}
void readCmd()
{
cin >> command;
commandAcK = true;
}
};
int main()
{
SystemManager *SM = new SystemManager;
thread tRunning = SM->runningAlgorithm();
}
now the errors look like this:
no suitable constructor exists to convert from "void" to "std::thread"
Error C2440 'initializing': cannot convert from 'void' to 'std::thread'
i have found a new method and it doesn't give me any errors
std::thread tRunning(&SystemManager::runningAlgorithm, SystemManager());
the first thing i don't understand is that this method doesn't use an instance of the class just the generic function. How can i link it to a specific instance? I need it so it can read the values of the variables.
Secondly what does "&" in front of SystemManager do?
(&SystemManager::runningAlgorithm)
Thirdly is there a better way of doing it? Do you have any ideas?
Thank you in advance.
std::thread tRunning(&SystemManager::runningAlgorithm, SystemManager()); does use an instance of your class. The instance it uses is SystemManager() which is a temporary and only available to the thread. If you need to share the instance then you need to create one yourself and pass it by reference to the thread like
SystemManager sys_manager;
std::thread tRunning([&](){sys_manager.runningAlgorithm();});
And now your call site and your thread have the same instance.
Also note that command and commandAck need to be protected by some sort of synchronization since you can write to them while reading causing a data race and subsequently undefined behavior. Using std::atmoic should work for you.
The constructor for std::thread accepts a functor, and optionally it's arguments. A functor is anything that can be "called" using operator().
Then it starts a thread and inside that thread calls your functor.
std::thread tRunning(&SystemManager::runningAlgorithm, SystemManager());
This will call the member function SystemManager::runningAlgorithm, passing in the only argument being this (SystemManager() creates a temporary instance).
Remember that member functions always accept this as the first argument.
&SystemManager::runningAlgorithm returns the address of the member function runningAlgorithm from the class SystemManager.
In modern C++ this code can be simplified (i.e. made more readable) with a lambda:
std::thread tRunning([]{ SystemManager().runningAlgorithm(); });
The line
thread tRunning = SM->runningAlgorithm();
takes the result of running SM->runningAlgorithm() (a void), and tries to construct a thread from it. If you look at the relevant constructor, though, you can see it needs a function-like argument (with possibly arguments).
One way of running it is through a lambda function:
thread tRunning(
[SM](){SM->runningAlgorithm();});
Two other things to note:
You should join the thread before its destructor is called, in this case:
tRunning.join();
You have a (short lived) memory leak. Why not just create it on the stack?
SystemManager SM;
thread tRunning(
[&](){SM.runningAlgorithm();});
tRunning.join();
Uhm... I guesss you need to study some of the basic concepts of c++, before going multithread.
However... In your code,
thread tRunning = SM->runningAlgorithm();
tries to put the result of your function (that is void... ) inside a variable of type thread... Non likely to be right.
Instead, your second code takes 2 arguments:
std::thread tRunning(
&SystemManager::runningAlgorithm, //a pointer to a method (a pointer to the code of your function, and that is why you use the "&", even though you could have left that out)
SystemManager()); // An instance of the value, built on the stack.
I guest that you are confused by the lack of the word "new" (coming from higher level language?), but that's how it works here:
SystemManager sm = SystemManager(); // <- variable created on the stack, will be automatically destroyed when out of scope
SystemManager *psm = new SystemManager(); // Created in the heap, while in the stack remains just a pointer to it.
//You will need to delete it when done with :
delete psm;
To answer the question
How can i link it to a specific instance? I need it so it can read the values of the variables.
You can do:
int main()
{
SystemManager SM; // = SystemManager(); // <- this is not needed
std::thread tRunning(SystemManager::runningAlgorithm, SM);
// Access SM as you need
// REMEMBER TO CLOSE & JOIN THE THREAD!
tRunning.join();
}
I still think you should first get used to the underlying concepts or it will be really difficult to go on.

C++ std::thread of a member function

I'm trying to program a command line server that would receive information from a serial port, parse it, and record it in an internal object.
Then upon request from a client the server would return the requested information.
What I want to do is put the receiver & parser parts in a separated thread in order to have the server running along side, not interfering with the data collection.
#include <iostream>
#include <thread>
class exampleClass{
std::thread *processThread;
public void completeProcess(){
while(1){
processStep1();
if (verification()){processStep2()}
}
};
void processStep1(){...};
void processStep2(){...};
bool verification(){...};
void runThreaded();
} // End example class definition
// The idea being that this thread runs independently
// until I call the object's destructor
exampleClass::runThreaded(){
std::thread processThread(&exampleClass::completeProcess, this);
} // Unfortunately The program ends up crashing here with CIGARET
You are running a local thread inside a member function. You have to join it or detach it and, since it is local, you have to do this in the function itself:
exampleClass::runThreaded()
{
std::thread processThread(&exampleClass::completeProcess, this);
// more stuff
processThread.join();
} //
I am guessing what you really want is to launch a data member thread instead of launching a local one. If you do this, you still have to join it somewhere, for example in the destructor. In this case, your method should be
exampleClass::runThreaded()
{
processThread = std::thread(&exampleClass::completeProcess, this);
}
and the destructor
exampleClass::~exampleClass()
{
processThread.join();
}
and processThread should be an std::thread, not a pointer to one.
Just a note on design: if you are to have a runThreaded method acting on a thread data member, you have to be very careful about not calling it more than once before the thread is joined. It might make more sense to launch the thread in the constructor and join it in the destructor.
Thread object is on stack and it is going to be destructed on function end. Thread object destructor calls std::terminate if thread still running, as in your case. See here.

C++11 std::thread giving error: no matching function to call std::thread::thread

I'm testing c++11 threads with this code, but when creating the thread, I'm having the error no matching function for call to 'std::thread::thread()'.
It's like if there was something wrong with the function I'm giving to std::thread ctr, but I don't see how it's wrong. It is incompleted, but it looks right to me:
Header:
#ifndef CONNECTION_H
#define CONNECTION_H
#include <thread>
#include <mysql++.h>
class Connection
{
public:
Connection(std::string mysqlUser, std::string mysqlPassword);
~Connection();
private:
std::string mysqlUser;
std::string mysqlPassword;
std::string mysqlIP;
int mysqlPort;
mysqlpp::Connection mysqlConnection;
std::thread connectionThread;
void threadLoop();
};
#endif // CONNECTION_H
Source:
#include "connection.h"
Connection::Connection(std::string mysqlUser, std::string mysqlPassword)
{
this->mysqlUser = mysqlUser;
this->mysqlPassword = mysqlPassword;
this->mysqlIP = "localhost"; //default
this->mysqlPort = 3306; //default
//Launch thread
std::thread connectionThread(threadLoop);
}
Connection::~Connection(){
mysqlConnection.disconnect();
}
void Connection::threadLoop(){
//Connect to mySQL database
mysqlConnection = new mysqlpp::Connection(false);
if(mysqlConnection.connect(NULL, mysqlIP.c_str(), mysqlUser.c_str(), mysqlPassword.c_str(), mysqlPort)){
std::string consulta = "SELECT * FROM 'Coordinates'";
mysqlpp::Query query = mysqlConnection.query(consulta);
mysqlpp::StoreQueryResult res = query.store();
query.reset();
}
while(true){
// Stuff
}
}
The problem is that threadLoop is a member function, but there is no object for it to be applied to. Just guessing:
std::thread connectionThread(&Connection::threadLoop, this);
But that's just the syntactic issue; there's a logic problem, too: that line creates a local object of type std::thread that goes away when the function returns. Its destructor will call std::terminate() because the thread has not been joined. Most likely, this was supposed to attach a thread to the connectionThread member. To do that:
std::thread thr(threadLoop, this);
std::swap(thr, connectionThread);
Your code has two problems:
You are providing incomplete information to the std::thread constructor
You are destroying the std::thread before it is joined with the main thread.
For the first problem, as Pete Becker suggests, you need to provide the object on which the function will be called, because the constructor for std::thread has no other way to know it. Assuming that you want to call function threadLoop() on the Connection object you are constructing, you can do this:
//Launch thread
std::thread connectionThread(threadLoop, this);
Internally, the constructor will call this->threadLoop() (where this is the Connection* parameter it received, not the std::thread itself, of course). And you will be fine.
The second problem is that your std::thread is destroyed immediately after starting, without having joined it to the main thread: this will call terminate(), which is not a good thing. Once again, Pete suggests a good alternative. Replace the above code with this:
// Launch thread
std::thread thr(threadLoop, this);
std::swap(thr, connectionThread);
The situation before this code is as follows:
You have a trivial std::thread object, connectionThread, which does not really represent a thread
After executing the first line of code:
You still have connectionThread
You also have a live thread represented by the std::thread object thr, which will be destroyed at the end of the Connection constructor, causing a call to terminate() because it is never joined to the main thread.
Fortunately, the second line of code comes to the rescue. After executing it:
You have a trivial std::thread, thr, which can be safely destroyed because it does not represent a real thread (so it is not joinable)
You have a live thread represented by connectionThread, an object that will not be destroyed as long as the Connection object exists.
Now, the problem is that you want to join connectionThread to the main thread before it is destroyed, but you also want to avoid blocking the main thread. The right time to do this join is the latest possible time: when connectionThread is about to be destroyed. And this happens at the destructor of Connection. So we'll add a line to this destructor, this way:
Connection::~Connection(){
mysqlConnection.disconnect();
connectionThread.join(); // Now connectionThread can be safely destroyed
}
Besides, this is the safest place to call join(), because it ensures that you will never destroy an unjoined connectionThread. This is RAII in action; if you are not familiar with the concept of RAII (or RIIA, as it is sometimes called), you can find a lot of information about this very important concept in the web, including this site.
All this put together: creating a Connection object will create a new thread; in this thread, a new database connection will be established and a query will be executed, while the main thread remains free for whatever other use (for instance, managing the GUI). When the Connection object is finally destroyed, the main thread will wait for the additional thread to finish (if necessary) and then normal execution will continue. I hope this is what you wanted to accomplish with your code.
As you may evince from cppreference, std::thread's constructor expect some form of function; you can pass it a free function, a static member function or one of these packed together with its arguments by means of std::bind. In order to execute a non-static member function you should use std::mem_fn to pass it together with the object it should be called on.

Trouble tracking down a Bus Error/Seg Fault in C++ and Linux

I have a program that processes neural spike data that is broadcast in UDP packets on a local network.
My current program has two threads a UI thread and a worker thread. The worker thread simply listens for data packets, parses them and makes them available to the UI thread for display and processing. My current implementation works just fine. However for a variety of reasons I'm trying to re-write the program in C++ using an Object Oriented approach.
The current working program initialized the 2nd thread with:
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, getNetSpike, (void *)NULL);
Here is the getNetSpike function that is called by the new thread:
void *getNetSpike(void *ptr){
while(true)
{
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s;
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
}
Now in my new OO version of the program I setup the 2nd thread in much the same way:
void SpikePlot::initNetworkRxThread(){
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, networkThreadFunc, this);
}
However, because pthead_create takes a pointer to a void function and not a pointer to an object's member method I needed to create this simple function that wraps the SpikePlot.getNetworSpikePacket() method
void *networkThreadFunc(void *ptr){
SpikePlot *sp = reinterpret_cast<SpikePlot *>(ptr);
while(true)
{
sp->getNetworkSpikePacket();
}
}
Which then calls the getNetworkSpikePacket() method:
void SpikePlot::getNetworkSpikePacket(){
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s; // <--- SegFault/BusError occurs on this line
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
The code for the two implementations is nearly identical but the 2nd implementation (OO version) crashes with a SegFault or BusError after the first packet that is read. Using printf I've narrowed down which line is causing the error:
spikeBuff[writeIdx] = s;
and for the life of me I can't figure out why its causing my program to crash.
What am I doing wrong here?
Update:
I define spikeBuff as a private member of the class:
class SpikePlot{
private:
static int const MAX_SPIKE_BUFF_SIZE = 50;
spike_net_t spikeBuff[MAX_SPIKE_BUFF_SIZE];
....
}
Then in the SpikePlot constructor I call:
bzero(&spikeBuff, sizeof(spikeBuff));
and set:
writeIdx =0;
Update 2: Ok something really weird is going on with my index variables. To test their sanity I changed getNetworkSpikePacket to:
void TetrodePlot::getNetworkSpikePacket(){
printf("Before:writeIdx:%d nspikes:%d totSpike:%d\n", writeIdx, nSpikes, totalSpikesRead);
spike_net_t s;
NetCom::rxSpike(net, &s);
// spikeBuff[writeIdx] = s;
writeIdx++;// = incrementIdx(writeIdx);
// if (writeIdx>=MAX_SPIKE_BUFF_SIZE)
// writeIdx = 0;
nSpikes += 1;
totalSpikesRead += 1;
printf("After:writeIdx:%d nspikes:%d totSpike:%d\n\n", writeIdx, nSpikes, totalSpikesRead);
}
And I get the following output to the console:
Before:writeIdx:0 nspikes:0 totSpike:0
After:writeIdx:1 nspikes:32763 totSpike:2053729378
Before:writeIdx:1 nspikes:32763 totSpike:2053729378
After:writeIdx:1 nspikes:0 totSpike:1
Before:writeIdx:1 nspikes:0 totSpike:1
After:writeIdx:32768 nspikes:32768 totSpike:260289889
Before:writeIdx:32768 nspikes:32768 totSpike:260289889
After:writeIdx:32768 nspikes:32768 totSpike:260289890
This method is the only method where I update their values (besides the constructor where I set them to 0). All other uses of these variables are read only.
I'm going to go on a limb here and say all your problems are caused by the zeroing out of the spike_net_t array.
In C++ you must not zero out objects with non-[insert word for 'struct-like' here] members. i.e. if you have an object that contains a complex object (a std string, a vector, etc. etc.) you cannot zero it out, as this destroys the initialization of the object done in the constructor.
This may be wrong but....
You seemed to move the wait loop logic out of the method and into the static wrapper. With nothing holding the worker thread open, perhaps that thread terminates after the first time you wait for a UDP packet, so second time around, sp in the static method now points to an instance that has left scope and been destructed?
Can you try to assert(sp) in the wrapper before trying to call its getNetworkSpikePacket()?
It looks like your reinterpret_cast might be causing some problems. When you call pthread_create, you are passing in "this" which is a SpikePlot*, but inside networkThreadFunc, you are casting it to a TetrodePlot*.
Are SpikePlot and TetrodePlot related? This isn't called out in what you've posted.
If you are allocating the spikeBuff array anywhere then make sure you are allocating sufficient storage so writeIdx is not an out-of-bounds index.
I'd also check that initNetworkRxThread is being called on an allocated instance of spikePlot object (and not on just a declared pointer).