Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
pthread_t m_thread_info;
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 )
{ // this is line 21
st_parameter_and_time *p_and_t
p_and_t = ( st_parameter_and_time * ) arg;
.... } // it does not do much yet.
File gl_strip_chart.h declares the class that the thread is started from. It contains:
Code:
...
class C_GL_Strip_Chart : public QGLWidget
{...
st_parameter_and_time m_p_and_t;
pthread_t m_thread_indo;
... }
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
Since it cored out right away it was started within gdb and the terminal window contains:
Quote:
Starting program .....
[New Thread 0x7fffe387f700 (LWP 38233)
<blank line>
thread start now
[NewThread 0x7fffdddfb700 (LWP 38239)]
<blank line>
Program received signal SIGSEGV, Segmentation fault.
[Switching to thread 0x7fffdddfb700 (LWP 38239) ]
0x00000000004326e6a in Get_One_Parameter( arg = <error reading variable: Cannot access memory at 0x7fffd9dfad28 at get_one_parameter.cpp:21
21 {
Missing separate debuginfos, // and continues on for multiple lines.
I am hoping my error is obvious to the more experienced developer.
I looked diligently for typos and hope any remaining are obvious.
Last edited by bkelly; 04-16-2019 at 01:16 PM.
Reason: additional information
The values looked reasonable and as I worked through the structure incremented by 8 or 4 depending on the type of item.
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.
Last edited by bkelly; 04-05-2019 at 10:29 AM.
Reason: formatting
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 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.
That tells me the argument for the thread to run is incorrect. I am pretty sure there are a few typos in there as I find this difficult to transcribe. I hope they are sufficiently few in number to allow the concept to be conveyed.
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
And everything is the same.
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,
0,
Get_One_Param,
(void * ) 0 ); // Note the zero here
And the result was exactly the same addresses as before. The address in argument 4 is not getting through to the code that is started. Argument 4 appears to be totally ignored. I don't have a clue as to where it ( with it meaning the compiler, the Centos O.S., or I don't know) might be getting the address handed to the thread. Co-workers are using pthread_create without a problem.
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.
The response is:
Quote:
Cannot access memory at 0x7fffd95afd18
GDB appears to have ignored the set variable command.
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
After a while I moved the class to be completely within the thread code, within the .cpp file, as in:
what you posted is more or less meaningless without the real code you tried.
I think what was posted is far from meaningless. However, your concept is exactly right. In my attempts at being brief I omitted what turned out to be the problem.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.