I have this C program:
void main(){
*(unsigned int*)0x100000 = 0xdeadbeef;
}
When running this C Program, it obviously causes an address boundary error when running. Is there a way to detect potential address boundary errors on certain memory addresses?
Here is a way to recover from a SIGSEGV signal by using a signal handler and performing a non local goto :
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
static volatile sig_atomic_t jump = 0;
static sigjmp_buf env;
static void handler(int sig)
{
if (!jump)
return;
siglongjmp(env, 1);
}
int main()
{
/* install the signal handler */
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}
if (sigsetjmp(env, 1) == 0) {
jump = 1;
/* will trigger SIGSEGV */
*(unsigned int *)0x100000 = 0xdeadbeef;
} else {
/* after siglongjmp */
puts("SIGSEGV detected");
return 0;
}
return 1;
}
It is POSIX specific but at least it can gives a clue on how it can be done on Linux for example. Hope this helps.
I want to write some code that takes input from stdin, and prints the input on the next line, until a signal is sent, the signal being SIGINT in this case. So far I have this code which just prints a message when SIGINT is sent:
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
bool signalSent = false;
void flag(int signal) {
signalSent = true;
}
int main(int argc, char** argv) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = flag;
sa.sa_flags = SA_RESTART;
sigaction(SIGINT, &sa, 0);
while (true) {
while (!signalSent) {
usleep(500000);
}
printf("signal sent\n");
signalSent = false;
}
return 0;
}
I tried using fgets() to get the input from stdin and print to stdout, but when I enter ^C (SIGINT) I have to press enter, but I want it to send the message ("signal sent\n"); as soon as it is pressed like the code I currently have. Code using fgets():
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
bool signalSent = false;
void flag(int signal) {
signalSent = true;
}
int main(int argc, char** argv) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = flag;
sa.sa_flags = SA_RESTART;
sigaction(SIGINT, &sa, 0);
while (true) {
while (!signalSent) {
char buffer[80];
char* t = fgets(buffer, sizeof(buffer), stdin);
printf("%s", t);
fflush(stdout);
}
printf("signal sent\n");
signalSent = false;
}
return 0;
}
Output from code:
For reference I want my output to look like the picture below. Im very new to using signals in C as well.
As detailed in the manual pages for sigaction(2) and signal(7), the SA_RESTART flag causes certain system calls, including read(2), to automatically restart after the signal handler has ended.
It seems that you do not want this behaviour.
fgets is implemented by way of read, and can fail for the same reasons it can. Without SA_RESTART, while waiting on input from a "slow" device (this includes terminals), these functions will set errno to EINTR if interrupted by a signal.
Note that what can and cannot be done in a signal handler is complicated.
Consider using sig_atomic_t objects, declared as volatile, for these types of flags.
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
static volatile sig_atomic_t signal_sent = 0;
void flag(int signal) {
(void) signal;
signal_sent = 1;
}
int main(void) {
struct sigaction sa = { .sa_handler = flag };
sigaction(SIGINT, &sa, 0);
while (!signal_sent) {
char buffer[80];
if (fgets(buffer, sizeof buffer, stdin))
printf("%s", buffer);
else if (errno == EINTR && signal_sent) {
puts("signal sent");
signal_sent = 0;
} else
return 1;
}
}
Example of running this program (^D to terminate):
$ ./a.out
foo
foo
^Csignal sent
^Csignal sent
bar
bar
hello wor^Csignal sent
I have a simple code which uses two signal handlers for "Segmentation fault" signal. First one works when signal happens and after longjmp, I do reassigning of handler with second one for that signal. Unfortunately, the flow of code doesn't reach necessary handler and I still get "Segmentation fault".
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
int i;
int ci;
jmp_buf m_env_buffer;
jmp_buf max_env_buffer;
void handler(int signum){
printf("sigsegv on i:[%d]", i);
ci = (++i);
longjmp(m_env_buffer,1);
}
void top_handler(int signum){
printf("sigsegv on max i:[%d]", i);
longjmp(max_env_buffer,10);
}
int main(void) {
signal(SIGSEGV, handler);
char * pstart = "loremipsum";
int m_cell = 0;
char m_cell_v;
int point;
point = setjmp(m_env_buffer);
if(point == 0){
for(i=0; ;i--){
m_cell_v = pstart[i];
}
}
//this wasn't invoked
signal(SIGSEGV, top_handler);
point = setjmp(max_env_buffer);
if(point == 0){
for(i=ci; ;i++){
char cur = pstart[i];
if(cur==10)
printf("\n");
printf("%c",cur);
}
}
puts("finish");
return 0;
}
signal() should not be used. It has unreliable semantics. On your system the default action (termination) is performed when the second SIGSEGV is received. The second call to signal() has effectively no effect.
You should use sigaction() instead. In your case you can use the following function instead of signal():
void set_signal (int signum, void (*handler)(int))
{
struct sigaction act;
act.sa_handler = handler;
sigemptyset (&act.sa_mask);
act.sa_flags = SA_NODEFER;
act.sa_restorer = NULL;
sigaction (signum, &act, NULL);
}
In the future, read the documentation at your disposal. A good ressource is the glibc manual. It has a good chapter on signal handling.
I am trying to manually interrupt the main thread of a program when it is blocked on a read() system call. I do this in a second thread with a call to pthread_kill() however a segmentation fault occurs. However if I place the call to read() in the scond thread, i.e. NOT the main thread and call pthread_kill() from the main thread then all works as expected.
For example, the following code results in a segmentation fault, where I call pthread_kill() in the second thread, approximatelt 2 seconds after it is started. It uses the pthread_t of the main thread obtained by a call (in the main thread) to pthread_self():
Example 1
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <unistd.h>
#include <signal.h>
static int fd = 0;
unsigned char buf[255];
static pthread_t s;
void sigHandler(int sig){
printf("Signal handler called.\n");
}
void * closeFD(void *arg){
printf("Second thread started.\n");
sleep(2);
int r = pthread_kill(s, SIGUSR1);
}
int main(char *argv[], int argc){
struct termios newtio;
pthread_t t1;
unsigned char buf[255];
void *res;
struct sigaction int_handler = {.sa_handler=sigHandler};
sigaction(SIGUSR1,&int_handler,0);
s = pthread_self();
printf("Process id is: %d.\n", getpid());
fd = open("/dev/ttyS0", O_RDONLY | O_NOCTTY);
if (fd != -1){
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = B2400 | CS7 | CLOCAL | CREAD ;
newtio.c_iflag = ICRNL;
newtio.c_oflag = 0;
newtio.c_lflag = ~ICANON;
newtio.c_cc[VMIN] = 14;
tcsetattr(fd,TCSANOW,&newtio);
pthread_create(&t1, NULL, closeFD, NULL);
printf("Reading ..\n");
read(fd,buf,255);
close(fd);
}
return 0;
}
The following code is the same except I place the call to read() in the second thread (in closeFD()) and works as expected. The second thread unblocks and terminates while the main thread waits for it to exit then exits itself.
Example 2:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <unistd.h>
#include <signal.h>
static int fd = 0;
unsigned char buf[255];
static pthread_t s;
void sigHandler(int sig){
printf("Signal handler called.\n");
}
void * closeFD(void *arg){
printf("Second thread started.\n");
read(fd,buf,255);
printf("Read interrupted.\n");
}
int main(char *argv[], int argc){
struct termios newtio;
pthread_t t1;
unsigned char buf[255];
void *res;
struct sigaction int_handler = {.sa_handler=sigHandler};
sigaction(SIGUSR1,&int_handler,0);
s = pthread_self();
printf("Process id is: %d.\n", getpid());
fd = open("/dev/ttyS0", O_RDONLY | O_NOCTTY);
if (fd != -1){
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = B2400 | CS7 | CLOCAL | CREAD ;
newtio.c_iflag = ICRNL;
newtio.c_oflag = 0;
newtio.c_lflag = ~ICANON;
newtio.c_cc[VMIN] = 14;
tcsetattr(fd,TCSANOW,&newtio);
pthread_create(&t1, NULL, closeFD, NULL);
sleep(2);
int r = pthread_kill(t1, SIGUSR1);
pthread_join(t1, &res);
close(fd);
}
return 0;
}
So far I have not been able to find a specific reference stating that terminating the main thread from a second (within the same process) is an illegal operation, so is there something I am doing wrong?
UPDATE #1
Thanks for all those that have replied, however I should make a few points clear:
I am aware that using printf in the signal handler is unsafe however this is an example and it's not the cause of the segmentation fault, though it is a valid point. Taking the printf() out of the signal handler still results in a segmentation fault. Example 2 works with printf() either in or out of the signal handler.
I know sending a SIGUSR will not terminate the program. However by using the pthread_kill(pthread_t thread, int signal) it WILL send a signal to the thread thread and it will unblock (if indeed it is blocked). This is the action I desire, this is what actually happens in Example 2 and this is what I understand should happen in either example, but does not in example 1.
When describing example 1, I used the term 'method' when I meant 'thread', where I mention the call to pthread_kill().
Further, quoting from 'Programming with POSIX Threads', David R. Butenhof, section 6.6.3 p217 'pthread_kill':
Within a process, one thread can send a signal to a specific thread
(including itself) by calling pthread_kill.
With that said, the following example ALSO gives a segmentation fault:
Example 3
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <signal.h>
static pthread_t s;
int value = 0;
void sigHandler(int sig){
value = 1;
}
int main(char *argv[], int argc){
struct sigaction int_handler = {.sa_handler=sigHandler};
sigaction(SIGUSR1,&int_handler,0);
s = pthread_self();
printf("The value of 'value' is %d.\n", value);
printf("Process id is: %d.\n", getpid());
int r = pthread_kill(s, SIGUSR1);
printf("The value of 'value' is %d.\n", value);
return 0;
}
This also fails if instead of a call to sigaction() is replaced by the (non-portable) call to signal(). With the third example in mind, which is very simple, I am not able to find any documentation that expressly states it is an illegal action. In fact the quoted reference indicates it's allowable!
You forgot to #include <pthread.h>. That fixes your segfault for me in example #3 on a recent Linux system.
--- pthread_kill-self.c.orig 2015-01-06 14:08:54.949000690 -0600
+++ pthread_kill-self.c 2015-01-06 14:08:59.820998965 -0600
## -1,6 +1,6 ##
#include <stdio.h>
#include <string.h>
-#include <string.h>
+#include <pthread.h>
#include <signal.h>
and then...
$:- gcc -o pthread_kill-self pthread_kill-self.c -pthread
$:- ./pthread_kill-self
The value of 'value' is 0.
Process id is: 3152.
The value of 'value' is 1.
You're using printf(), which is not async-signal safe, and you're not initializing your struct sigaction properly (in particular, the signal mask is left undefined).
Third, sending a SIGUSR1 signal, with a handler installed, does not and should not terminate the main thread. You're just sending it a signal, that's all.
As Jens Gustedt mentioned in his comment to the original question, both of the programs have undefined behaviour. Therefore, I'm not going to try and guess exactly what part of the undefined behaviour causes the segmentation fault (in the first program).
Instead, I'll show you a working example.
For debugging/testing purposes, I like to start with async-signal safe output functions, based on write(2):
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <termios.h>
#include <pthread.h>
#include <errno.h>
#include <time.h>
#define MYSIGNAL SIGUSR1
#define SECONDS 10
static int wrstr(const int descriptor, const char *p, const char *const q)
{
while (p < q) {
ssize_t n;
n = write(descriptor, p, (size_t)(q - p));
if (n > (ssize_t)0)
p += n;
else
if (n != (ssize_t)-1)
return EIO;
else
if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK)
return errno;
}
return 0;
}
static const char *ends(const char *s)
{
if (s)
while (*s != '\0')
s++;
return s;
}
static int wrout(const char *const p)
{
if (p != NULL && *p != '\0') {
int saved_errno, result;
saved_errno = errno;
result = wrstr(STDOUT_FILENO, p, ends(p));
errno = saved_errno;
return result;
} else
return 0;
}
static int wrouti(const int value)
{
char buffer[32];
char *p = buffer + sizeof buffer;
unsigned int u;
if (value < 0)
u = -(long)value;
else
u = value;
do {
*(--p) = '0' + (u % 10U);
u /= 10U;
} while (u > 0U);
if (value < 0)
*(--p) = '-';
return wrstr(STDOUT_FILENO, p, buffer + sizeof buffer);
}
static int wrerr(const char *const p)
{
if (p != NULL && *p != '\0') {
int saved_errno, result;
saved_errno = errno;
result = wrstr(STDERR_FILENO, p, ends(p));
errno = saved_errno;
return result;
} else
return 0;
}
The above functions are async-signal safe, and therefore okay to use in a signal handler. wrout() and wrerr() also retain errno unchanged, which is useful. Saving and restoring errno in a signal handler is usually omitted, by the way, although I do believe there are some odd corner cases it might matter. The wrouti() is just a crude decimal signed integer printer, also async-signal-safe, but it does not retain errno unchanged.
Next, let's define the signal handler itself, and an installer function for it. (I like to do it this way, to make the main() simpler.)
static volatile sig_atomic_t handled = 0;
static void handler(int signum)
{
wrerr("Signal received.\n");
handled = signum;
}
static int install_handler(const int signum)
{
struct sigaction act;
/* memset(&act, 0, sizeof act); */
sigemptyset(&act.sa_mask);
act.sa_handler = handler;
act.sa_flags = 0;
if (sigaction(signum, &act, NULL))
return errno;
return 0;
}
The commented-out memset is recommended, but not required for proper operation. The sigemptyset(), however, is required, to clear the set of blocked signals.
Next, let's look at the thread function. You shouldn't use sleep(), as that interacts with signals; use POSIX.1-2001 nanosleep() instead.
static void *worker(void *target)
{
struct timespec duration, left;
int retval;
wrout("Worker started. Sleeping ");
wrouti((int)SECONDS);
wrout(" seconds...\n");
duration.tv_sec = SECONDS;
duration.tv_nsec = 0;
left.tv_sec = 0;
left.tv_nsec = 0;
while (1) {
retval = nanosleep(&duration, &left);
if (retval == 0)
break;
if (left.tv_sec <= 0 ||
(left.tv_sec == 0 && left.tv_nsec <= 0))
break;
duration = left;
left.tv_sec = 0;
left.tv_nsec = 0;
}
wrout("Sleep complete.\n");
if (target) {
wrout("Sending signal...\n");
retval = pthread_kill(*(pthread_t *)target, MYSIGNAL);
if (retval == 0)
wrout("Signal sent successfully.\n");
else {
const char *const errmsg = strerror(retval);
wrout("Failed to send signal: ");
wrout(errmsg);
wrout(".\n");
}
}
wrout("Thread done.\n");
return NULL;
}
The pointer given to the thread function should point to the thread identifier (pthread_t) the signal is directed to.
Note that above, nanosleep() can be interrupted by a signal delivery, if the signal is delivered to or caught by this particular thread. If that occurs, nanosleep() tells us how much time was left to sleep. The loop above shows how to make sure you sleep at least the specified time, even if interrupted by signal delivery.
Finally, the main(). Instead of opening a specific device, I use standard input. To reproduce OP's program, redirect standard input from /dev/ttyUSB0, i.e. ./program < /dev/ttyUSB0, when executing it.
int main(void)
{
pthread_t main_thread, worker_thread;
pthread_attr_t attrs;
struct termios original, settings;
int result;
if (!isatty(STDIN_FILENO)) {
wrerr("Standard input is not a terminal.\n");
return EXIT_FAILURE;
}
if (tcgetattr(STDIN_FILENO, &original) != 0 ||
tcgetattr(STDIN_FILENO, &settings) != 0) {
const char *const errmsg = strerror(errno);
wrerr("Cannot get terminal settings: ");
wrerr(errmsg);
wrerr(".\n");
return EXIT_FAILURE;
}
settings.c_lflag = ~ICANON;
settings.c_cc[VMIN] = 14;
if (tcsetattr(STDIN_FILENO, TCSANOW, &settings) != 0) {
const char *const errmsg = strerror(errno);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &original);
wrerr("Cannot set terminal settings: ");
wrerr(errmsg);
wrerr(".\n");
return EXIT_FAILURE;
}
wrout("Terminal is now in raw mode.\n");
if (install_handler(MYSIGNAL)) {
const char *const errmsg = strerror(errno);
wrerr("Cannot install signal handler: ");
wrerr(errmsg);
wrerr(".\n");
return EXIT_FAILURE;
}
main_thread = pthread_self();
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, 65536);
result = pthread_create(&worker_thread, &attrs, worker, &main_thread);
if (result != 0) {
const char *const errmsg = strerror(errno);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &original);
wrerr("Cannot create a worker thread: ");
wrerr(errmsg);
wrerr(".\n");
return EXIT_FAILURE;
}
pthread_attr_destroy(&attrs);
wrout("Waiting for input...\n");
while (1) {
char buffer[256];
ssize_t n;
if (handled) {
wrout("Because signal was received, no more input is read.\n");
break;
}
n = read(STDIN_FILENO, buffer, sizeof buffer);
if (n > (ssize_t)0) {
wrout("Read ");
wrouti((int)n);
wrout(" bytes.\n");
continue;
} else
if (n == (ssize_t)0) {
wrout("End of input.\n");
break;
} else
if (n != (ssize_t)-1) {
wrout("read() returned an invalid value.\n");
break;
} else {
result = errno;
wrout("read() == -1, errno == ");
wrouti(result);
wrout(": ");
wrout(strerror(result));
wrout(".\n");
break;
}
}
wrout("Reaping the worker thread..\n");
result = pthread_join(worker_thread, NULL);
if (result != 0) {
wrout("Failed to reap worker thread: ");
wrout(strerror(result));
wrout(".\n");
} else
wrout("Worker thread reaped successfully.\n");
tcsetattr(STDIN_FILENO, TCSAFLUSH, &original);
wrout("Terminal reverted back to original mode.\n");
return EXIT_SUCCESS;
}
Because it's much more fun to test using the terminal, the above tries hard to restore the terminal to its original state before returning.
Note that since the VMIN field in the termios structure is set to 14, the read() blocks until at least 14 bytes are available in the buffer. If a signal is delivered, a short count is returned if there is at least one byte in the buffer. Therefore, you cannot expect the read() to always return 14 bytes, and you cannot expect it to return -1 with errno == EINTR whenever a signal is delivered! Experimenting with this program is very useful, to clarify these in your mind.
I don't remember whether the USB serial drivers in Linux ever produce EPIPE or raise SIGPIPE, but that can definitely occur when using pipes. When using pipes, the most common reason is trying to read after read has already returned zero (end of input). Unless ignored or caught with a signal handler, the process dies much like in a segmentation fault, except that the cause is SIGPIPE signal instead of SIGSEGV. With terminal-like character devices, it depends on the driver, I seem to recall.
Finally, I wrote the above code under the weather (flu), so there might be bugs in tharrr. It should be POSIX.1 C99 code, and gcc -Wall -pedantic does not complain, but having a stuffed head, I'm not making any promises here. Fixes are more than welcome!
Questions? Comments?
Im trying to handle SIGINT. Main purpose of SIGINT in my program cancelling current search function and printing the currently avaliable results. But whenever I try to catch a SIGINT signal it just closes my program. (I ve searched so much ,please just do not say that I have not searched enough)
I have tried :
basic signal handling(as shown as below)
sigaction functionality
non-local signal handling
sigprocmask (problem with procmask whenever I block a signal I cannot catch it but I need to catch and make printing on screen)
after all i have run out of search keyword to find a solution. Any idea ? (search keyword or part of code or logic way to do it ^^)
NOTE : This text may have grammar errors. Sorry for any mistakes.
#ifdef DEBUG
#define DPRINT(file ,message ,arg) fprintf(file ,message ,arg);
#define NDPRINT(file ,message) fprintf(file ,message);
#endif
static volatile sig_atomic_t isSignalCaught = 0;
void SIGHandler(int signo);
int main(int argc, char** argv)
{
file_t *files,*nextP;
signal(SIGINT, SIGHandler);
files = findFiles("/");
while (files != NULL) {
DPRINT(stderr, "%s\n", files->fileName.string);
nextP = files->pNext;
free(files->fileName.string);
free(files);
files = nextP;
}
return(0);
}
void SIGHandler(int signo)
{
file_t *nextP;
if (signo == SIGINT) {
isSignalCaught = 1;
}
}
Here's an example of how to do what I think you want to do.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>
typedef void(* sig_func_t )(int);
volatile sig_atomic_t keep_looping = 1;
void sig_handler(int sig_number) {
switch (sig_number) {
case SIGINT:
keep_looping = 0;
break;
}
}
int should_continue(void) {
char line[256];
while (1) {
printf("Continue? (y/n) ");
fgets(line, sizeof line, stdin);
if (tolower(line[0]) == 'y') {
keep_looping = 1;
signal(SIGINT, sig_handler);
return 1;
}
if (tolower(line[0]) == 'n')
break;
}
return 0;
}
int main (void) {
sig_func_t sig_func;
sig_func = signal(SIGINT, sig_handler);
if (sig_func == SIG_ERR) {
perror("signal");
exit(EXIT_FAILURE);
}
unsigned n = 0;
printf("Starting...\n");
while (1) {
while (keep_looping)
n++;
printf("Current value: n=%u\n", n);
if (!should_continue())
break;
}
signal(SIGINT, sig_func);
return EXIT_SUCCESS;
}