I am working on a lock-free shared variable class, and I want to be able to generate a SIGSEGV fault to see if my implementation works as I planned. I've tried creating a function that modifies a pointer and read it 100 times. I then call this function in both threads and have the threads run infinitely within my program. This doesn't generate the error I want. How should I go about doing this?
edit
I don't handle segfaults at all, but they are generated in my program if I remove locks. I want to use a lock-less design, therefore i created a shared variable class that uses CAS to remain lockless. Is there are way that I can have a piece of code that will generate segfaults, so that i can use my class to test that it fixes the problem?
#include <signal.h>
raise(SIGSEGV);
Will cause an appropriate signal to be raised.
malloc + mprotect + dereference pointer
This mprotect man page has an example.
Derefencing pointer to unallocated memory (at least on my system):
int *a;
*a = 0;
Related
I am new to C++ and I was playing around with string class. I realized when I run the following code in CodeBlocks with GNU compiler:
#include <iostream>
using namespace std;
int main()
{
string test = "hi";
cout<<"char is : "<<test[100];
return 0;
}
I actually get a value. I play with indexes (I tried from 100 to 10000) and I may get other characters or I may get null. Does that mean this way you are able to read parts of memory that you are not supposed to? can you use it for exploitation? or is it just my mind being illusional?
The answer is simple- Undefined Behavior. No, you can't trust this info and it is highly not recommended. Don't do it..
This is undefined behavior, so anything can happen. The compiler can optimize away the line, insert abort(), or do anything else.
If the compiler does not make big changes to the code, and std::string implements short-string-optimization, then test[100] will access the stack frame of one of the functions that call main().
These functions are responsible for loading shared libraries, arranging the environment variables, constructing global objects such as std::cout, and creating and passing argc, argv, to main(). This code peeks into the stack of these functions. On a system with memory protection, such as Linux or Windows, with far enough out-of-bounds access, the application will crash.
Don't rely on it, since the compiler can do something totally unexpected with it.
And yes, it can lead to exploitation. If out-of-bounds depends on user input, then that user may be able to read or write data they were not supposed to. This is one of the way a worm or a virus might spread: they read passwords, or write code that will execute upon a return from a function.
I have been having a peculiar problem. I have developed a C++ program on a Linux cluster at work. I have tried to use it home on an Ubuntu 14.04 machine, but the program, which is composed of 6 files: main.hpp,main.cpp (dependent on) sarsa.hpp,sarsa.cpp (class Sarsa) (dependent on) wec.hpp,wec.cpp, does compile, but when I run it it either returns segmenation fault or does not enter one fundamental function of the class Sarsa.
The main code calls the constructor and setter functions without problems:
Sarsa run;
run.setVectorSize(memory,3,tilings,1000);
etc.
However, it cannot run the public function episode , since learningRate, which should contain a large integer, returns 0 for all episodes (iterations).
learningRate[episode]=run.episode(numSteps,graph);}
I tried to debug the code with gdb, which has returned:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000408f4a in main () at main.cpp:152
152 learningRate[episode]=run.episode(numSteps,graph);}
I also tried valgrind, which returned:
==10321== Uninitialised value was created by a stack allocation
==10321== at 0x408CAD: main (main.cpp:112)
But no memory leakage issues.
I was wondering if there was a setting to try to debug the external file sarsa.cpp, since I think that class is likely to be the culpript
In the file, I use C++v11 language (I would be expecting errors at compile-time,though), so I even compiled with g++ -std=c++0x, but there were no improvements.
Unluckily, because of the size of the code, I cannot post it here. I would really appreciate any help with this problem. Am I missing anything obvious? Could you help me at least with the debugging?
Thank you in advance for the help.
Correction:
main.cpp:
Definition of the global array:
`#define numEpisodes 10
int learningRate[numEpisodes];`
Towards the end of the main function:
for (int episode; episode<numEpisodes; episode++) {
if (episode==(numEpisodes-1)) { // Save the simulation data only at the
graph=true;} // last episode
learningRate[episode]=run.episode(numSteps,graph);}
As the code you just added to the question reveals, the problem arises because you did not initialize the episode variable. The behavior of any code that uses its value before you assign one is undefined, so it is entirely reasonable that the program behaves differently in one environment than in another.
A segmentation fault indicates an invalid memory access. Usually this means that somewhere, you're reading or writing past the end of an array, or through an invalid pointer, or through an object that has already been freed. You don't necessarily get the segmentation fault at the point where the bug occurs; for instance, you could write past the end of an array onto heap metadata, which causes a crash later on when you try to allocate or release an unrelated object. So it's perfectly reasonable for a program to appear to work on one system but crash on another.
In this case, I'd start by looking at learningRate[episode]. What is the value of episode? Is it within the bounds of learningRate?
I was wondering if there was a setting to try to debug the external file sarsa.cpp, since I think that class is likely to be the culpript
It's possible to set breakpoints in functions other than main.cpp.
break location
Set a breakpoint at the given location, which can specify a function name, a line number, or an address of an instruction.
At least, I think that's your question. You'll also need to know how to step into functions.
More importantly, you need to learn what your tools are trying to tell you. A segfault is the operating system's reaction to an attempt to dereference memory that doesn't belong to you. One common reason for that is trying to dereference NULL. Another would be trying to dereference a pointer that was never initialized. The Valgrind error message suggests that you may have an unitialized pointer.
Without the code, I can't tell you why the pointer isn't initialized when you run the program on your home system, but is (apparently) initialized when you run it at work. I suspect that you don't have the necessary data on your home system, but you'll need to investigate and figure that out. The fundamental question to keep asking yourself is "what is different between my home computer an dmy work computer?"
I am working on a multithreaded process written in C++, and am considering modifying SIGSEGV handling using google-coredumper to keep the process alive when a segmentation fault occurs.
However, this use of google-coredumper seems ripe with opportunities to get stuck in an infinite loop of core dumps unless I somehow reinitialize the thread and the object that may have caused the core dump.
What best practices should I keep in mind when trying to keep a process alive through a core dump? What other 'gotchas' should I be aware of?
Thanks!
It is actually possible in C. You can achieve it in quite a complicated way:
1) Override signal handler
2) Use setjump() and longjmp() to set the place to jump back, and to actually jump back to there.
Check out this code I wrote (idea taken from "Expert C Programming: Deep C Secrets" by Peter Van Der Linden):
#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
//Declaring global jmp_buf variable to be used by both main and signal handler
jmp_buf buf;
void magic_handler(int s)
{
switch(s)
{
case SIGSEGV:
printf("\nSegmentation fault signal caught! Attempting recovery..");
longjmp(buf, 1);
break;
}
printf("\nAfter switch. Won't be reached");
}
int main(void)
{
int *p = NULL;
signal(SIGSEGV, magic_handler);
if(!setjmp(buf))
{
//Trying to dereference a null pointer will cause a segmentation fault,
//which is handled by our magic_handler now.
*p=0xdead;
}
else
{
printf("\nSuccessfully recovered! Welcome back in main!!\n\n");
}
return 0;
}
The best practice is to fix the original issue causing the core dump, recompile and then relaunch the application.
To catch these errors before deploying in the wild, do plenty of peer review and write lots of tests.
Steve's answer is actually a very useful formula. I've used something similar in a piece of complicated embedded software where there was at least one SIGSEGV error in the code that we could not track down by ship time. As long as you can reset your code to have no ill effects (memory or resource leaks) and the error is not something that causes an endless loop it can be a lifesaver (even though its better to fix the bug). FYI in our case it was single thread.
But what is left out is that once you recover from your signal handler, it will not work again unless you unmask the signal. Here is a chunk of code to do that:
sigset_t signal_set;
...
setjmp(buf);
sigemptyset(&signal_set);
sigaddset(&signal_set, SIGSEGV);
sigprocmask(SIG_UNBLOCK, &signal_set, NULL);
// Initialize all Variables...
Be sure to free up your memory, sockets and other resources or you could leak memory when this happens.
My experience with segmentation faults is that it's very hard to catch them portably, and to do it portably in a multithreaded context is next to impossible.
This is for good reason: Do you really expect the memory (which your threads share) to be intact after a SIGSEGV? After all, you've just proven that some addressing is broken, so the assumption that the rest of the memory space is clean is pretty optimistic.
Think about a different concurrency model, e.g. with processes. Processes don't share their memory or only a well-defined part of it (shared memory), and one process can reasonably work on when another process died. When you have a critical part of the program (e.g. the core temperature control), putting it in an extra process protects it from memory corruption by other processes and segmentation faults.
If a segmentation fault occurs, you're better off just ditching the process. How can you know that any of your process's memory is usable after this? If something in your program is messing with memory it shouldn't, why do you believe it didn't mess with some other part of memory that your process actually can access without segfaulting?
I think that doing this will mostly benefit attackers.
From description of coredumper seems it's purpose not what you intending, but just allowing to make snapshots of process memory.
Personally, I wouldn't keep process after it triggered core dump -- it just so many ways it could be broken -- and would employ some persistence to allow data recovery after process is restarted.
And, yes, as parapura has suggested, better yet, find out what causing SIGSEGV and fix it.
I've come across a strange issue in some code that I'm working on. Basically what's going on is that whenever I try to get some information from an empty map, the program segfaults. Here's the relevant code:
(note that struct Pair is a data structure that is defined earlier, and sendMasks is a std::map that is good)
std::map<std::string*, struct Pair*>::iterator it;
for(it = sendMasks->begin(); it != sendMasks->end(); it++){ //segfault
//(some code goes here)
}
I know that the pointer to the map is good; I can do
it = sendMasks->begin();
it = sendMasks->end();
before my loop, and it doesn't segfault at all then.
Now, if I put the following test before the for loop, it will segfault:
if( sendMasks->empty() )
As will any other attempt to determine if the map is empty.
This issue will only occur if the map is empty. My only thought on this issue would be that because I am updating sendMasks in a separate thread, that it may not have been updated properly; that however doesn't make any sense because this will only happen if the map is empty, and this code has worked perfectly fine before now. Any other thoughts on what could be happening?
EDIT:
I figured out what the problem was.
At an earlier part in my code, I was making a new char* array and putting that pointer into another array of length 4. I was then putting a NULL character at the end of my new array, but accidentally only did a subscript off of the first array - which went off the end of the array and overwrote a pointer. Somehow, this managed to work properly occasionally. (valgrind doesn't detect this problem)
The sequence was something like this:
object* = NULL; //(overwritten memory)
object->method();
//Inside object::method() :
map->size(); //segfault. Gets an offset of 0x24 into the object,
//which is NULL to begin with. memory location 0x24 = invalid
I wasn't expecting the instance of the object itself to be null, because in Java this method call would fail before it even did that, and in C this would be done quite differently(I don't do much object-oriented programming in C++)
If you are accessing a data structure from different threads, you must have some kind of synchronization. You should ensure that your object is not accessed simultaneously from different threads. As well, you should ensure that the changes done by one of the threads are fully visible to other threads.
A mutex (or critical section if on Windows) should do the trick: the structure should be locked for each access. This ensures the exclusive access to the data structure and makes the needed memory barriers for you.
Welcome to the multithreaded world!
Either:
You made a mistake somewhere, and have corrupted your memory. Run your application through valgrind to find out where.
You are not using locks around access to objects that you share between threads. You absolutely must do this.
I know that the pointer to the map is good; I can do
it = sendMasks->begin();
it = sendMasks->end();
before my loop, and it doesn't segfault at all then.
This logic is flawed.
Segmentation faults aren't some consistent, reliable indicator of an error. They are just one possible symptom of a completely unpredictable system, that comes into being when you have invoked Undefined Behaviour.
this code has worked perfectly fine before now
The same applies here. It may have been silently "working" for years, quietly overwriting bytes in memory that it may or may not have had safe access to.
This issue will only occur if the map is empty.
You just got lucky that, when the map is empty, your bug is evident. Pure chance.
I know it looks not necessary but I hope that it would help me find memory leak.
So having a function inside a class that returns int, how can I call it from another function of that class (call it so that function that returns int would run in another thread)?
You are trying to find a memory leak in a function by having it called from another thread? That is like trying to find a needle in a haystack by adding more hay to the stack.
Thread programming 101:
Spawn a new thread ("thread2") that invokes a new function ("foo").
Have the original thread join against thread2 immediately after the spawn.
Read a global variable that foo() has written its final value to.
Notice that foo() cannot return its value to the original thread; it must write the value to some shared memory (ie, global variable). Also note that this will not solve your memory leak problem, or even make it obvious where your memory leak is coming from.
Look for memory leaks with Valgrind. And read a book or tutorial about multithreading.
The operating system will not reclaim memory leaks in worker threads. That's not how it works.
Fix your bugs. The world doesn't need any more crappy software.