Skip to content

Commit 209588c

Browse files
committed
signal updated
1 parent faa9536 commit 209588c

File tree

4 files changed

+209
-85
lines changed

4 files changed

+209
-85
lines changed

CMakeLists.txt

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,7 @@ add_executable(arrays src/arrays.cpp)
7878
add_executable(dynamic_memory_allocation src/dynamic_memory_allocation.cpp)
7979

8080
# ADD_LIBRARY(add MODULE src/add.cpp)
81-
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
82-
add_library(add SHARED src/add.cpp)
83-
add_executable(loadeding_libraries src/loadeding_libraries.cpp)
84-
target_link_libraries(loadeding_libraries dl)
8581

86-
add_executable(align src/align.cpp)
87-
88-
add_executable(signals src/signals.cpp)
89-
add_executable(system_call src/system_call.cpp)
90-
91-
# add_executable(date_time src/date_time.cpp)
92-
93-
add_executable(fork src/fork.cpp)
94-
95-
endif()
9682

9783
add_executable(template src/template.cpp)
9884

@@ -406,3 +392,21 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp")
406392
add_executable(main src/main.cpp)
407393
endif()
408394

395+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
396+
add_library(add SHARED src/add.cpp)
397+
add_executable(loadeding_libraries src/loadeding_libraries.cpp)
398+
target_link_libraries(loadeding_libraries dl)
399+
400+
add_executable(align src/align.cpp)
401+
402+
403+
set(CMAKE_CXX_FLAGS "-fsanitize=address ${CMAKE_CXX_FLAGS}")
404+
set(CMAKE_CXX_FLAGS "-fno-omit-frame-pointer ${CMAKE_CXX_FLAGS}")
405+
add_executable(signals src/signals.cpp)
406+
add_executable(system_call src/system_call.cpp)
407+
408+
# add_executable(date_time src/date_time.cpp)
409+
410+
add_executable(fork src/fork.cpp)
411+
412+
endif()

docs/signals.md

Lines changed: 127 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
- [Signals](#signals)
2+
* [Types of Signals](#types-of-signals)
23
* [SIGILL](#sigill)
34
* [SIGSEGV](#sigsegv)
45
+ [Segmentation fault](#segmentation-fault)
@@ -8,46 +9,66 @@
89
* [SIGSYS](#sigsys)
910
* [SIGTRAP](#sigtrap)
1011
* [SIGTERM](#sigterm)
11-
- [Raising a Signal](#raising-a-signal)
1212
- [Setting Signal Handler](#setting-signal-handler)
13+
- [Examples](#examples)
14+
* [SIGINT_Handler](#sigint-handler)
15+
* [SIGSEGV_Handler](#sigsegv-handler)
16+
- [Raising a Signal](#raising-a-signal)
17+
1318

1419

1520
# Signals
16-
Signals in computers are a way of communication between the process and the OS.
17-
When a running program undergoes some serious error then the OS sends a signal to
18-
the process and the process further may not execute.
19-
Some processes may have a signal handler which does some important tasks before the
21+
Signals are a communication mechanism between a process and the operating system. When a running program encounters a significant error, the OS sends a signal to that process. Some processes may have a signal handler which does some important tasks before the
2022
process leaves the CPU.
21-
Signal and interrupt are basically same but a small distinction exists i.e interrupts
22-
are generated by the processor and handled by the kernel but signals are generated by
23-
the kernel and handled by the process.
24-
Error signals generally causes termination of the program and a core dump file is
25-
created named core, which stores the state of the process at the moment of termination.
26-
This file can be investigated using debugger to know the cause of program termination.
23+
24+
25+
Signals and interrupts serve similar purposes, but they differ in their origin and handling mechanisms. Interrupts originate from the processor and are managed by the operating system's kernel. In contrast, signals are generated by the kernel and are managed by the individual process to which they are sent.
26+
27+
28+
## Types of Signals
29+
There are various types of signals, each corresponding to different events.
2730
## SIGILL
28-
This signal denotes illegal instruction. When a garbage instruction or instruction
29-
which a program has no privilege to execute, is executed then this signal is
30-
generated.
31-
C does not produce illegal instruction so there is no chance of facing such error
32-
signal, as the probable cause may be that the object file may be corrupted.
33-
This signal is also generated when stack overflow occurs.
31+
This signal in Unix-like operating systems is sent to a process when it attempts to execute an illegal, malformed, unknown, or privileged instruction.
3432
## SIGSEGV
35-
The signal is generated when process tries to access memory location not
36-
allocated to it, like de-referencing a wild pointer which leads to
37-
“segmentation fault”.
33+
The signal is generated when process tries to access memory location which is not allocated to it.
3834

3935
### Segmentation fault
4036
The following are some typical causes of a segmentation fault:
4137
1. Attempting to access a nonexistent memory address (outside process's address space)
4238
2. Attempting to access memory the program does not have rights to (such as kernel structures in process context)
4339
3. Attempting to write read-only memory (such as code segment)
4440

45-
The above incidents will happens while dereferencing or assigning null pointer/ wild pointer/ dangling pointer, heap overflow, stack overflow.
41+
4642
When you access an array index, C and C++ don't do bound checking. Segmentation faults only happen when you try to
4743
read or write to a page that was not allocated (or try to do something on a page which isn't permitted,
4844
e.g. trying to write to a read-only page), but since pages are usually pretty big
4945
(multiples of a few kilobytes), it often leaves you with lots of room to overflow.
46+
47+
48+
```
49+
int main() {
50+
// Define an array with a small size
51+
int array[5] = {0, 1, 2, 3, 4};
52+
53+
std::cout << "Original array values:\n";
54+
for (int i = 0; i < 5; i++) {
55+
std::cout << "array[" << i << "] = " << array[i] << "\n";
56+
}
57+
58+
// Overflowing the array
59+
// Writing beyond the bounds of the array
60+
std::cout << "\nWriting beyond the bounds of the array...\n";
61+
for (int i = 0; i < 100;
62+
i++) { // This loop intentionally goes well beyond the array's bounds
63+
array[i] = i;
64+
}
65+
return 0;
66+
}
67+
```
68+
5069
By setting the followings flag you can find the issue:
70+
71+
5172
```
5273
set(CMAKE_CXX_FLAGS "-fsanitize=address ${CMAKE_CXX_FLAGS}")
5374
set(CMAKE_CXX_FLAGS "-fno-omit-frame-pointer ${CMAKE_CXX_FLAGS}")
@@ -77,38 +98,99 @@ Unlike `SIGKILL`, this signal can be blocked, handled, and ignored. It is
7798
the normal way to politely ask a program to terminate. The shell command
7899
kill generates `SIGTERM` by default.
79100

80-
# raising a Signal
81-
The `<csignal>` header file declared the function `raise()` to handle a particular signal. Signal learns some unusual behavior in a program, and calls the signal handler. It is implemented to check if the default handler will get called or it will be ignored.
82-
Syntax:
83-
```cpp
84-
int raise ( int signal_ )
85-
```
101+
86102
# Setting Signal Handler
87-
Sets the handler for signal sig
88-
```cpp
89-
signal(int sig, /*signal-handler*/* handler);
90-
```
103+
create the signal handler function:
91104

92-
defining a signal handler:
93105
```cpp
94-
sig_atomic_t s_value = 0;
95-
void handle(int signum)
96-
{
97-
s_value = signum;
106+
void signalHandler(int signum) {
107+
std::cout << "signal (" << signum << ") received.\n";
108+
// Cleanup and close up logic
109+
exit(signum);
98110
}
99111
```
112+
100113
setting the handler for a specific signal:
101114
```cpp
102-
//SIGILL,SIGINT,SIGSEGV,SIGTERM,SIGABRT,SIGFPE
103-
signal(SIGTERM, handle);
115+
116+
int main() {
117+
// Register signal SIGINT ( or any of SIGILL,SIGINT,SIGSEGV,SIGTERM,SIGABRT,SIGFPE) and signal handler
118+
signal(SIGINT, signalHandler);
119+
}
120+
```
121+
122+
123+
124+
# Examples
125+
## SIGINT_Handler
126+
In the following example signal that is being handled is `SIGINT`. This signal is typically sent when the user presses `Ctrl+C` in the terminal. The SIGINT_Handler function in the example is specifically set up to catch and handle the SIGINT signal.
127+
```
128+
#include <csignal>
129+
#include <iostream>
130+
131+
132+
// Signal handler function
133+
void SIGINT_Handler(int signum) {
134+
std::cout << "Interrupt signal (" << signum << ") received.\n";
135+
// Cleanup and close up logic
136+
exit(signum);
137+
}
138+
139+
int main() {
140+
// Register signal SIGINT and signal handler
141+
signal(SIGINT, SIGINT_Handler);
142+
143+
while(1) {
144+
std::cout << "Waiting for signal..." << std::endl;
145+
sleep(1);
146+
}
147+
148+
return 0;
149+
}
150+
```
151+
152+
## SIGSEGV_Handler
153+
154+
```
155+
#include <csignal>
156+
#include <cstdlib> // for exit()
157+
#include <iostream>
158+
#include <unistd.h> // getpid()
159+
160+
void SIGSEGV_Handler(int signum) {
161+
std::cout << "oh my god! segmenation fault happened" << std::endl;
162+
printf("Process %d got signal %d\n", getpid(), signum);
163+
// kill(getpid(), signum);
164+
exit(signum);
165+
}
166+
167+
int main() {
168+
signal(SIGSEGV, SIGSEGV_Handler);
169+
int *p;
170+
*p = 10;
171+
}
104172
```
105-
raising the signal:
173+
174+
175+
# Raising a Signal
176+
The `<csignal>` header file declared the function `raise()` to handle a particular signal.
177+
Syntax:
106178
```cpp
107-
std::cout << "Before called Signal = " << s_value << std::endl;
108-
raise(SIGTERM);
109-
std::cout << "After called Signal = " << s_value << std::endl;
179+
int raise ( int signal_ )
180+
```
181+
182+
complete example:
183+
184+
```
185+
sig_atomic_t s_value = 0;
186+
void SIGTERM_Handler(int signum) { s_value = signum; }
187+
188+
int main() {
189+
signal(SIGTERM, SIGTERM_Handler);
190+
std::cout << "Before called Signal = " << s_value << std::endl;
191+
raise(SIGTERM);
192+
std::cout << "After called Signal = " << s_value << std::endl;
193+
}
194+
110195
```
111-
112-
113-
114196
[code](../src/signals.cpp)

src/main.cpp

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,52 @@
1-
#include <algorithm>
21
#include <cmath>
32
#include <exception>
43
#include <iomanip>
54
#include <iostream>
6-
#include <list>
7-
#include <map>
85
#include <memory>
9-
#include <set>
10-
#include <unordered_map>
11-
#include <unordered_set>
12-
#include <vector>
136

14-
int main() {}
7+
struct Foo {
8+
std::string id;
9+
Foo(std::string id) : id(id) {
10+
11+
std::cout << id << " constructor" << std::endl;
12+
}
13+
~Foo() { std::cout << id << " destructor" << std::endl; }
14+
};
15+
16+
Foo globalFoo("global object");
17+
static Foo staticFoo("static object");
18+
19+
void runBeforeTermination() {
20+
std::cout << "cleaning up temp dir before termination..." << std::endl;
21+
}
22+
void abortExample() {
23+
Foo fooObject("abortExample");
24+
std::shared_ptr<Foo> fooObject_ptr(new Foo("abortExample_ptr"));
25+
atexit(runBeforeTermination);
26+
abort();
27+
}
28+
29+
int main() {
30+
int array[5] = {0, 1, 2, 3, 4};
31+
32+
std::cout << "Original array values:\n";
33+
for (int i = 0; i < 5; i++) {
34+
std::cout << "array[" << i << "] = " << array[i] << "\n";
35+
}
36+
37+
// Overflowing the array
38+
// Writing beyond the bounds of the array
39+
std::cout << "\nWriting beyond the bounds of the array...\n";
40+
for (int i = 0; i < 10;
41+
i++) { // This loop intentionally goes well beyond the array's bounds
42+
array[i] = i;
43+
}
44+
45+
// std::cout << "\nReading values after overflow:\n";
46+
// // Reading values after overflow
47+
// for (int i = 0; i < int(100);
48+
// i++) { // Again, intentionally reading beyond the array's bounds
49+
// std::cout << "array[" << i << "] = " << array[i] << "\n";
50+
// std::cout << "i = " << i << "\n";
51+
// }
52+
}

src/signals.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,32 @@
33
#include <iostream>
44
#include <unistd.h> // getpid()
55

6-
sig_atomic_t s_value = 0;
7-
void handle(int signum) { s_value = signum; }
8-
9-
void SIGSEGVhandle(int signum) {
6+
void SIGSEGV_Handler(int signum) {
107
std::cout << "oh my god! segmenation fault happened" << std::endl;
118
printf("Process %d got signal %d\n", getpid(), signum);
12-
139
// kill(getpid(), signum);
1410
exit(signum);
1511
}
1612

17-
void SIGExample() {
18-
// SIGILL,SIGINT,SIGSEGV,SIGTERM,SIGABRT,SIGFPE
19-
signal(SIGTERM, handle);
20-
std::cout << "Before called Signal = " << s_value << std::endl;
21-
raise(SIGTERM);
22-
std::cout << "After called Signal = " << s_value << std::endl;
13+
void SIGINT_Handler(int signum) {
14+
std::cout << "Interrupt signal (" << signum << ") received.\n";
15+
// Cleanup and close up logic
16+
exit(signum);
2317
}
2418

19+
sig_atomic_t s_value = 0;
20+
void SIGTERM_Handler(int signum) { s_value = signum; }
21+
2522
int main() {
26-
// first example
27-
// SIGExample();
23+
// signal(SIGSEGV, SIGSEGV_Handler);
24+
// int *p;
25+
// *p = 10;
26+
27+
// // Register signal SIGINT and signal handler
28+
// signal(SIGINT, SIGINT_Handler);
2829

29-
// second example
30-
signal(SIGSEGV, SIGSEGVhandle);
31-
// signal(SIGSEGV, SIG_DFL); // restore default behavior
32-
int *p;
33-
*p = 10;
30+
signal(SIGTERM, SIGTERM_Handler);
31+
std::cout << "Before called Signal = " << s_value << std::endl;
32+
raise(SIGTERM);
33+
std::cout << "After called Signal = " << s_value << std::endl;
3434
}

0 commit comments

Comments
 (0)