pthread_create, immediate seg fault
Centos, g++, linux novice, first attempt at threads.
Edit: See post 13 for the solution I am trying to create my first thread. I start the app and it gets to the part to start the thread and cores out. Here is the code but please be tolerant of typos as I cannot copy paste from my work computer to here. this is running inside a Qt widget, and within that an OpenGL widget. All of that was working before trying to add the thread and the symptoms indicate, to me, the problem is at the thread creation. EDIT: I have change the descriptions of the files since the OP File get_one_parameter.h declares Code:
st_parameter_and_time m_p_and_t; // a structure with some strings, ints, etc The code of the tread to start is in get_one_parameter.cpp and the code to run begins with Code:
void * Get_One_Parameter( void * arg ) Code:
... The code to start the thread is in the constructor of class c_gl_strip_chart and the file name is gl_strip_chart.cpp The code to start the thread is: Code:
... Quote:
I looked diligently for typos and hope any remaining are obvious. |
m_p_and_t occupies no actual memory.
You can reference it in an include file but you have to declare it in a C file. |
Quote:
Code:
std::cout << "\n address of m_p_and_t = " << (uint64_t ) &m_p_and_t << std::flush; Maybe I need to elaborate on the file names. The first mentioned h file is: gl_strip_chart.h Those are member variables within the class c_gl_strip_chart The structure is declared in show_one_parameter.h The thread code is in show_one_parameter.cpp The code to start the thread is in: gl_strip_chart.cpp And that code is in the constructor of class c_gl_strip_chart In file gl_strip_chart.h the member name of the structure was changed to mpt; Then in the constructure, just above the std::cout lines was added: st_parameter_and_time m_p_and_t; The goal was to create/instantiate it just before the code that starts the thread, recognizing that it is local to the constructor, but this is a test. The results were exactly the same. Meanwhile, I will edit the clarifications into the OP. |
A coworker that was unable to make this work holds the position that the structure passed into the pthread_create() must be either static or global. My searches about pthread_create() did not reveal that requirement. Any thoughts on that aspect?
|
I agree that it could be global. Sorry hadn't noticed that it was a member of a class. You need that object to exist somewhere, prior to sending it as an argument to a new thread.
|
I burned through all my co-workers without a solution. The system architect with more experience that all the rest of us put together came by, looked at the memory maps and said that the argument going into the thread was not right. Could not say why, just flat out wrong. He could see that the memory addresses are not right, meaning the proximate cause for the coring, but not the root cause.
Then he said that since this is within Qt and Open GL, that some things are known to be weird and do not work right. His suggestion is to use the threads functions within Qt rather than the normal pthread_create(). I am taking that path now. That will take a bit of time. After a few more searches for tutorials and I have not recognized anything that says pthreads must be static or global. |
The language of Qt is C++.
Meanwhile Qt does have its own thread classes. I suggest searching for pthread examples on the web, there are plenty. |
The thought occurred that moving the code to be created as a thread into the class might make the difference. I have not been able to derive a syntax that is acceptable to the compiler. Here is one attempt along with the error message.
Code:
void * ptr_test; Quote:
Quote:
|
To be honest, I never have had excellent luck when there's code which doesn't work, or compile, or execute correctly. I have tried things like that and sometimes they get worse. Meanwhile, I go (what I call) "back to basics" and I grab a known good example of pthread'ing or whichever code example I'm looking for, in the language I'm looking for it in. I'm not sure if there are Qt specific ones, I do know as I said before that Qt has a QThread class of it's own and that there are examples of that. Once I get that first working example, I go from there and see if I can get it to attain what I want. The other primary thing to do is to use the debugger to resolve things like if memory is not allocated for the process, etc. Sorry, but that's about the best I have here. I don't personally have an exact example that would suit what you're looking for.
What that error is telling you is that pthread_create() is expecting a certain prototype for one of the arguments. Besides example, the manual page of pthread_create() can also help there. But it says it wants a void* (*)(void*). |
pthread_create accept general pointers, because it is a general function. You need to cast this function pointer, otherwise you will get that cannot convert error.
From the other hand you need to pass the pointer to the function and you need the "address-of" operator here (&). https://stackoverflow.com/questions/...ember-function |
I am flip/flopping between the Qt threads and the Linux thread. On the Linux thread side I modified the code that starts the thread to look like this:
Code:
std::cout << "\n"m_pt address = " << std::hex << (uint64_t) &m_pt << std::endl; In GDB before the core details is the text: Quote:
Quote:
Within gdb enter the command: print arg the response is: Quote:
So just for fun tried this: Code:
uint64_t force address = (uint64_t) & m_pt; And just in case, the code to be started as the thread starts off like this: Code:
void * Get_One_Param( void * arg ) Code:
void * Get_One_Param( void * input_address ) Summary When Get_One_Parm is started the argument list, which I understand is to be the address of something that can be referenced by the thread, is an invalid address. I don't know what I might do to fix that. Edit: forgot one more permutation: Code:
status = pthread_create( & m_thread_info, Edit again: So the debugger is showing that the address does not match that provided by the call to pthread_create(...) However, since I do have what I appears to be the correct address, what might happen if, within that function Get_One_Parm, I were to use GDB and change the incoming argument to be the value shown before the call, and then attempt to continue running. I am looking at my cheat sheet and do not recognize any command that might do this. Can it be done? Edit last time: I tried the command: Code:
set var input_address = 73ed70 //the address from the std::cout statement. Quote:
|
what you posted is more or less meaningless without the real code you tried.
|
I have resolved the problem but do not know if this is the solution or a work-around.
The thread uses a class to read data from something called the ION buss, a commercial product. I was creating the class in the H file for the thread as in Code:
C_Read_Class m_read_class Code:
void * Get_One_Param( void * input_address ) Is this the way a class must be used with pthread_create()? |
Quote:
|
All times are GMT -5. The time now is 02:47 AM. |