GNU toolchain on InterProcess Communication(IPC)
Run, break, study, re-run, dump. The 3G from GNU tool chain is here to make your life easier.
While gorging down your favorite snack, what tells your hands to stop before you die from overeating? Well thanks to our operating systems, we never need to check over our process queue to ensure everything is working smooth.
So does this box thingy in our hands also needs a check over it’s workflow?
Just a screenshot of my dramatic phone’s log file.
What stops them from dying from overeating? While diagnosing disorders in us doesn’t require anatomizing ourselves, in the IT world there are tools that can be used to troubleshoot or “Look What’s Inside?” any operating system and how process communication work.
*enter stage The 3G. Here’s a short bio for each:
gcc : the GNU project C and C++ compiler. Involves preprocessing, compilation,
assembly and linking.
gdb : the GNU Debugger. Allows you to see what
happens “inside” a program when it executes.
gcov : the GNU coverage
testing tool. Helps you to discover untested parts of your code, helps you to
analyze the number of times every line of your code is executed.
To know more about each of them, open your terminal, type
man followed by any
To investigate their business and their roles in systems development, we will
now create a tiny subsystem of 2 processes communicating with each other.
I will summon the powers of IPC and SIGNALs to help me make them talk.
A brief little map of how I established communication:
- Neighbour1 creates a shared memory segment and invites anyone willing to share the place with him(I have used ftok() to create the key, shmget() to get the memory, shmat() to attach a pointer which will point to the process id).
- Neighbour2, knowing the address of neighbour1’s house, decides to live with him(I have used shmget() to get the memory of the previous process, shmat() to attach pointer to the previous process id, shmdt() to detach the pointer).
Read more about process communication and signal handling.
These are the neighbours we’ll be studying today. One annoys, while the other tries to calm things down and provides the user with 3 options:
The nextdoor neighbour annoys me. What should I do to him? Kidnap, kill or let him go?
Neighbour 1(annoying infinite looped process disturbing neighbour 2):
View neighbour1.c on gist.github.com
Neighbour 2(resolves by sending signals to neighbour 1):
View neighbour2.c on gist.github.com
Compile both the processes using gcc. Although, we will use different flags for
For process 1, we will analyze code coverage using gcov. Compile using:
$gcc -Wall -fprofile-arcs -ftest-coverage neighboour1.c -o neighbour1
For process 2, we will experiment and try changing the user input data in the course of execution process using gdb.(Wait. Is that possible?) Compile using:
$gcc -g neighbour2.c -o neighbour2
Alright! Now that our mini ecosystem is created, we employ the 3G to analyse what’s going on. Execute them to make them talk.
You can either execute them in 2 different windows, or use the following to send neighbour1 to background and execute them simultaneously:
$./neighbour1 & ./neighbour2
Both of them should work. Now, what will a normal user do to a process annoying him? Kill? Kidnap? Let’s see:
So we see process 2 ended up killing process 1. Although just before getting killed neighbour 1 dumped his execution logs. Let’s analyze that. Remember gcov? Next step:
$gcov neighbour1 File 'neighbour1.c' Lines executed:55.10% of 49 Creating 'neighbour1.c.gcov' $cat neighbour1.c.gcov
What you now see is the number of times each line of code is executed/checked. Here’s a snippet for you to relate:
Owkay..time for repentance. Now it’s time to employ
gdb . Did you notice that
the user opted to spare the life of his fellow neighbour?
Can’t he be let go once? A second chance? Why so cruel?
Suppose the user has the evil intention to always kidnap or kill or send
corrupted data. So…can you check on the input data and change it while it gets
executed? Of course input data is received, there shouldn’t be any way you can
change values of variables while they’re still inside your process memory?
gdb can do it for you! Here’s how:
Code injection with gdb to change value of variables:
- Invoke debugging using
gdb ./neighbour2. Now we create 2 stops in the program where we can examine the value of the variables. Create breakpoints at the declaration and at the calling of
- Use command
lto view the line numbers and
break <line number>or
b <line number>to set the breakpoints.
- Now use
rto start execution inside the debugger. The process will ask for an input as usual, enter a choice(This is the value we will attempt in changing).
- When it reaches it’s 1st breakpoint, examine all the local variables using
info locals. After that, enter
continueto reach the next breakpoint.
Breakpoint 2, main (argc=1, argv=0x7fffffffddc8) at neighbour2.c:67 67 i=find(randv, randt); (gdb)info locals pid = 8623 keygen = 1929685536 shmid = 20774943 shmptr = 0x7ffff7ff6000 i = 21845 randt = 2 randv = 0x555555757260 (gdb)continue Continuing.
- At the next breakpoint(which will be at the defination of
find(), we examine the values again to ensure the input value(which is key=2 in our case)has been passed correctly. As the variables here are not local, we use
Breakpoint 1, find (tree=0x555555757260, key=2) at neighbour2.c:33 33 if (! tree) (gdb) info args tree = 0x555555757260 key = 2
Cool. So… neighbour1 is about to get killed. Can we save him?
- We now attempt in changing the value of key. Follow:
(gdb) compile code key=3; (gdb) continue Continuing. Breakpoint 1, find (tree=0x5555557572c0, key=3) at neighbour2.c:33 33 if (! tree) (gdb) info args tree = 0x5555557572c0 key = 3 (gdb) continue Continuing.
compile code we were successful to change the value of the input
data. Guess who just got saved?
Sent SIGUSR2 signal to neighbour. Neighbour 8623 is spared
So there you go! Today we learnt how to analyze inter-process communication(and
even change the messages) with the help of The 3G. Legends say that 3G is
always around you. They’re just a few commands away. Give them a call whenever
you need ❤.
If you’re interested in further reading, these are some nice starting points: