In-depth analysis of Linux debugging tool IPCS

Source: Internet
Author: User
1) System V shared memoryUse IPCS to debug the shared memory test source program as follows:
# Include <stdio. h>
# Include <string. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <sys/IPC. h>
# Include <sys/SHM. h>
# Include <sys/Wait. H>
Void error_out (const char * MSG)
{
Perror (MSG );
Exit (exit_failure );
} Int main (INT argc, char * argv [])
{
Key_t mykey = 12345678;
Const size_t region_size = sysconf (_ SC _page_size );
Int SMID = shmget (mykey, region_size, ipc_creat | 0666 );
If (SMID =-1)
Error_out ("shmget ");
Void * PTR;
PTR = shmat (SMID, null, 0 );
If (PTR = (void *)-1)
Error_out ("shmat ");
Pid_t pid = fork ();
If (pid = 0 ){
U_long * D = (u_long *) PTR;
* D = 0 xdeadbeef;
Exit (0 );
}
Else {
Int status;
Waitpid (PID, & status, 0 );
Printf ("child wrote % # lx \ n", * (u_long *) PTR );
}
Sleep (30 );
Int r = shmdt (PTR );
If (r =-1)
Error_out ("shmdt ");
R = shmctl (SMID, ipc_rmid, null );
If (r =-1)
Error_out ("shmdt ");
Return 0;
} Compilation:
GCC smem. C-o smem note: this program will apply for shared memory, and the parent and child processes will write data to the shared memory to achieve IPC communication.
Terminal 1)
./Smem
Child wrote 0xdeadbeef Terminal 2)
IPCS-m
------ Shared memory segments --------
Key shmid owner perms bytes nattch status
0x00bc614e 18874397 root 666 4096 1 Note:
The information listed in the key column is the key value defined by the application. If it is a private object, the key value is 0. Here we define the key value as 12345678, that is, the output 0x00bc614e (hexadecimal)
The shmid column lists the shared memory IDs. This value is unique.
The owner column lists the root users who created shared memory.
The perms column lists the shared memory permissions.
The Bytes column lists the size of the shared memory. By calling sysconf (_ SC _page_size), we can obtain that the size of the shared memory to be created is 4096 bytes.
The nattch column lists the processes connected to the associated shared memory segments.
The Status column lists the status of the current shared memory. When the Mode Field of the memory segment is set to the shm_dest bit, the message "DEST" is displayed,
When you call the shmctl ipc_rmid, the kernel first checks how many processes are associated with the memory. If the number of associated processes is 0, the memory is destroyed (released, otherwise, set the mode bit shm_dest of the memory segment,
And set its key to ipc_private, which means that the associated process can still legally access the memory, but it cannot be associated with a new process. in the above output, we did not see that the shared memory used by smem has a DEST state. However, when we manually delete this shared memory segment using ipcrm-M 18874397,
In this case, the key value of the shared memory segment will be 0x00000000 (ipc_private), and the shared memory will actually disappear when the program calls shmdt to release the shared memory segment.
To complete this test, we modify the above program and add the following after shmdt:
Printf ("shmdt function run finished \ n ");
Sleep (30 );
Add the following after the shmctl function:
Printf ("shmctl function run finished \ n"); Terminal 1, re-compile, run
GCC smem. C-o smem
./Smem
Child wrote 0xdeadbeef Terminal 2
Run IPCS-m to view the shared memory. The program enters the first sleep (30). The status is empty.
IPCS-m
------ Shared memory segments --------
Key shmid owner perms bytes nattch status
0x00bc614e 0 root 666 4096 1 Delete shared memory with shmid of 32768. The status is DEST, and the key is changed to 0x00000000.
Ipcrm-M 32768
------ Shared memory segments --------
Key shmid owner perms bytes nattch status
0x00000000 32768 root 666 4096 1 DEST after 30 seconds, the program runs the shmdt function to release the shared memory. We can use IPCS-m to see the shared memory, although it does not run to shmctl (SMID, ipc_rmid, null );
After 30 seconds, smem runs shmctl (SMID, ipc_rmid, null). If the shared memory is deleted, the following error occurs: shmdt: invalid argument, because we manually deleted the shared memory,
The program finally deletes the shared memory, so an error is reported. We can see more detailed information through IPCS-mi 32768, as shown below: shared memory segment shmid = 327680
Uid = 0 gid = 0 cuid = 0 cgid = 0
Mode = 0666 access_perms = 0666
Bytes = 4096 LPID = 3263 CPID = 3263 nattch = 0
Att_time = mon Mar 14 09:42:52 2011
Det_time = mon Mar 14 09:43:22 2011
Change_time = mon Mar 14 09:42:52 2011 Note:
Cuid = 0 indicates that the user ID used to create the shared memory is 0.
Cgid = 0 indicates that the Group ID used to create the shared memory is 0.
LPID = 3263 indicates that the PID for the last access to this shared memory segment is 3263
CPID = 3263 indicates that the PID of the shared memory segment created in the last production is 3263.
Att_time = mon Mar 14 09:42:52 2011 indicates the last time shmat () was called.
Det_time = mon Mar 14 09:43:22 2011 indicates the last time shmdt () was called.
Change_time = mon Mar 14 09:42:52 2011 indicates the last time the shared memory segment was modified with shmctl. finally, you can modify the maximum value of System V shared memory by modifying/proc/sys/kernel/shmmax. 2) System V system message queueUse IPCS to debug message queues. The test source code is as follows: # include <stdio. h>
# Include <string. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <sys/Wait. H>
# Include <sys/STAT. h>
# Include <sys/file. h>
# Include <sys/msg. h>
# Include <sys/IPC. h> struct message {
Long int mtype;
Char mtext [128];
}; Int send_msg (INT qid, int mtype, const char text []) {
Struct message MSG = {
. Mtype = mtype
};
Strncpy (msg. mtext, text, sizeof (msg. mtext); int r = msgsnd (qid, & MSG, sizeof (MSG), 0 );
If (r =-1 ){
Perror ("msgsnd ");
}
} Void producer (INT mqid)
{
Send_msg (mqid, 1, "Type 1-First ");
Send_msg (mqid, 2, "Type 2-second ");
Send_msg (mqid, 1, "Type 1-third ");
} Void consumer (INT qid)
{
Struct message MSG;
Int R;
Int I;
For (I = 0; I <3; I ++ ){
R = msgrcv (qid, & MSG, sizeof (struct message),-2, 0 );
Printf ("'% s' \ n", MSG. mtext );
}
} Int main (INT argc, char * argv [])
{
Int mqid;
Mqid = msgget (ipc_private, s_iread | s_iwrite );
If (mqid =-1 ){
Perror ("msgget ");
Exit (1 );
} Pid_t pid = fork ();
If (pid = 0 ){
Sleep (60 );
Consumer (mqid );
Exit (0 );
}
Else {
Int status;
Producer (mqid );
Wait (& status );
}
Int r = msgctl (mqid, ipc_rmid, 0 );
If (r)
Perror ("msgctl ");
Return 0;
} Compile mesg. c
GCC mesg. C-o mesg note: In this program, the parent process sends three messages to the message queue, and the child process receives the message after waiting for 60 seconds.
In 60 seconds, the message exists in the message queue so that we can view it. Execute mesg
./Mesg & IPCS-Q ------ message queues --------
Key msqid owner perms used-bytes messages
0x00000000 229376 root 600 408 3 Note:
The information listed in the key column is the key value defined by the application.
The values listed in the msgid column are system-defined key values.
As expected, the System-defined key values are unique, and in this example, all the key values defined by the application are 0, this means that these message queues are created using the ipc_private key value.
The owner column lists the users who created the message queue as root.
Permission to list this message queue in the perms column.
The used-bytes column lists the space occupied by this message queue. here our struct:
Struct message {
Long int mtype;
Char mtext [128];
};
Long int mtype occupies 8 bytes because it is a 64-bit system. If it is a 32-bit system, it occupies 4 bytes,
Char mtext [128] occupies 128 bytes, that is, one message is 136, and the three messages are exactly 408.
The messages column lists several messages in this message queue. We have sent three messages, so this is exactly 3. use IPCS-Q-I PID to view more detailed information, as shown below:
IPCS-Q-I 294912 Message Queue msqid = 294912
Uid = 0 gid = 0 cuid = 0 cgid = 0 mode = 0600
Cbytes = 408 qbytes = 16384 qnum = 3 lspid = 4036 lrpid = 0
Send_time = Fri Mar 11 20:52:21 2011
Rcv_time = not set
Change_time = Fri Mar 11 20:52:21 2011 Note:
The cuid column lists the user IDs used to create the message queue.
The cgid column lists the group IDs used to create the message queue.
The qbytes column lists the maximum values of System V message queues. You can modify the values by modifying/proc/sys/kernel/msgmnb and/proc/sys/kernel/msgmax.
The lspid column lists the last processes that send messages to this message queue.
The lrpid column lists the last process that receives messages from this message queue.
The send_time column lists the last time a message was sent to this queue.
The rcv_time column lists the last time a message was received from this message queue.
The change_time column lists the last time for changing the message queue. You can use ipcrm-Q to delete the message queue. 3) semaphore of System VUse IPCS to debug the semaphore test source program as follows:
# Include <stdio. h>
# Include <string. h>
# Include <stdlib. h>
# Include <assert. h>
# Include <errno. h>
# Include <unistd. h>
# Include <sys/STAT. h>
# Include <sys/SEM. h> int
Main (INT argc, char * argv [])
{
Key_t semkey = ftok ("/tmp", 'A'); int Semid =
Semget (semkey, 1, ipc_creat | ipc_excl | s_irusr | s_iwusr); If (Semid! =-1 ){
Printf ("created new semaphore \ n ");
}
Else
If (errno = eexist ){
Printf ("semaphore exists \ n ");
Semid = semget (semkey, 1, 0 );
} Assert (Semid! =-1 );
If (argc = 2 ){
Int op = atoi (argv [1]); struct sembuf sb = {
. Sem_num = 0,
. Sem_op = op,
. SEM _ {sensitive word} = 0
}; Int r = semop (Semid, & SB, 1); Assert (R! =-1); printf ("Operation % d done \ n", OP );
}
Else {
Printf ("no operation \ n ");
} Printf ("Semid % d value % d \ n", Semid, semctl (Semid, 0, getval ));
Return 0;
} Compile sysv_sem.c
GCC sysv_sem.c-O sysv_sem note:
This program creates a semaphore set through the semget function. The semop function operates a set number in the semaphore set to increase or decrease the values contained in the semaphore, in this way, program synchronization and resource mutual exclusion are achieved. execute the program and create a semaphore with the initial value. sem_num is 0, so the value obtained through the semctl function is 0.
./Sysv_sem 0
Created new semaphore
Operation 0 done
Semid 196608 value 0 run the program, replace the parameter with 1, and its value is 1, as shown below:
./Sysv_sem 1
Semaphore exists
Operation 1 done
Semid 196608 value 1 use IPCS-s to view the semaphore information, as shown below:
IPCS-s ------ semaphore arrays --------
Key Semid owner perms nsems
0x61018001 196608 root 600 1 Note:
The information listed in the key column is the key value defined by the application. Here we use ftok to generate its ID.
The Semid column lists the system-defined key values.
The owner column lists the users who created the semaphore set as root.
Permission to list the semaphore set in the perms column.
The nsems column lists how many semaphores are specified in this semaphores set. In our example, one semaphores are specified. You can use the semget function to specify multiple semaphores, for example:
Segmet (semkey, 5, ipc_creat | ipc_excl | s_irusr | s_iwusr );
In this way, five semaphores are specified in the signal set. You can see more detailed information using the-I parameter, as shown below;
IPCS-s-I 196608 semaphore array Semid = 196608
Uid = 0 gid = 0 cuid = 0 cgid = 0
Mode = 0600, access_perms = 0600
Nsems = 1
Otime = Tue Mar 11:44:49 2011
Ctime = Tue Mar 11:43:38 2011
Semnum value ncount zcount PID
0 1 0 0 2791 note:
Cuid = 0 lists the user IDs used to create the semaphore set.
Cgid = 0 lists the group IDs for creating this semaphore set.
Mode = 0600 lists the permissions for creating this semaphore set.
Access_perms = 0600 list the access permissions of this semaphore set.
Otime = Tue Mar 15 11:44:49 2011 lists the access operation time of the semaphore set. For example, the semop function operates on the semaphore set.
Ctime = Tue Mar 15 11:43:38 2011 lists the creation time of this semaphore set. For example, the semget function creates this semaphore set.
Semnum lists the sequence of semaphores in the semaphores set. If we specify two semaphores in the semget function, the output here will be the following information:
Semnum value ncount zcount PID
0 8 0 0 3270
1 0 0 0 0
Ncount lists the number of processes waiting for the increase of semaphores.
For example, if op is specified as a negative value, when the absolute value of the negative value is greater than the current signal value, blocking will occur, that is, the number of processes waiting for resources will increase, as shown below:
./Sysv_sem-6
Semaphore exists
Blocking at this time. We can view the current semaphore set in another terminal, as shown below:
IPCS-s-I 425984 semaphore array Semid = 425984
Uid = 0 gid = 0 cuid = 0 cgid = 0
Mode = 0600, access_perms = 0600
Nsems = 2
Otime = Tue Mar 12:14:06 2011
Ctime = Tue Mar 12:08:15 2011
Semnum value ncount zcount PID
0 0 1 0 3337
1 0 0 0 0
At this time, the number of processes waiting for the semaphore increase is 1, that is, ncount is 1, indicating that there is a process waiting for the signal to increase. zcount lists the number of processes waiting for the semaphore to become zero
For example, if the current signal value is greater than 0 and the specified op value is 0, it will be blocked until the semaphore changes to 0, the number of processes waiting for the semaphore to become zero during the blocking process is zcount, as shown below:
Increase the signal value to 1.
./Sysv_sem 1
Semaphore exists
Operation 1 done
Semid 425984 value 0 run the sysv_sem program again and specify OP as 0
./Sysv_sem 0
Semaphore exists
Blocking at this time. We can view the current semaphore set on another terminal, as shown below:
IPCS-s-I 425984 semaphore array Semid = 425984
Uid = 0 gid = 0 cuid = 0 cgid = 0
Mode = 0600, access_perms = 0600
Nsems = 2
Otime = Tue Mar 12:23:19 2011
Ctime = Tue Mar 12:08:15 2011
Semnum value ncount zcount PID
0 1 0 1 3499
1 0 0 0 0
At this time, the number of processes waiting for the semaphore to be zero is 1, that is, zcount is 1, indicating that a process waits for the signal to be zero. finally, we can modify/proc/sys/kernel/SEM to modify the maximum number of semaphores and related restrictions. for example:
CAT/proc/sys/kernel/SEM
250 32000 32 128
The first column indicates the maximum number of semaphores in each signal set.
The second column indicates the total number of semaphores in the system range.
The third column indicates the maximum number of system operations when each signal occurs.
The fourth column indicates the total number of signal sets in the system range.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.