Program execute result:
zsh: segmentation fault ./test.out
Coverity analyse output:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// uaf
void test_1(void *p) {
free(p);
CID 358676: Read from pointer after free (USE_AFTER_FREE) [select issue]
printf("%x\n", *((int *)p));
}
// loop write
void test_2(int total, char *p) {
char a[100];
for(int i=0;i < total; i++) {
a[i] = *(p + i);
}
}
typedef struct {
char name[100];
}Person;
// uint8 *p
void test_3(Person *p) {
unsigned char *ptr = (unsigned char *)p;
for(int i=0; i < sizeof(Person) + 100; i++) {
*ptr = 'a';
}
free(p);
CID 358686: Read from pointer after free (USE_AFTER_FREE) [select issue]
printf("%x\n", *((int *)p));
}
// state machine
enum {
S_START,
S_IDLE,
S_BUSY,
S_UNKNOWN
};
int gState = S_START;
void *gPtr = NULL;
void handle_start() {
int size;
printf("input malloc size:\n");
CID 358721: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%d", &size);
CID 134591: Untrusted allocation size (TAINTED_SCALAR) [select issue]
gPtr = malloc(size);
gState = S_BUSY;
printf("S_START -> S_BUSY\n");
}
void handle_busy() {
char buff[100];
printf("input string:\n");
CID 358720: Unchecked return value from library (CHECKED_RETURN) [select issue]
CID 358719: Calling risky function (DC.STREAM_BUFFER) [select issue]
scanf("%s", buff);
strcpy(gPtr, buff);
puts(gPtr);
gState = S_IDLE;
printf("S_BUSY -> S_IDLE\n");
}
void handle_idle(void *p) {
char cmd;
printf("continue or exit(C/E)?");
CID 358718: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%c", &cmd);
if (cmd == 'c' || cmd == 'C') {
gState = S_BUSY;
printf("S_IDLE -> S_BUSY\n");
} else {
free(p);
printf("S_IDLE -> S_START\n");
printf("exit\n");
exit(0);
}
}
void process(void *p) {
switch (gState) {
case S_START:
handle_idle(p);
handle_start();
break;
case S_BUSY:
handle_busy();
break;
case S_IDLE:
handle_idle(p);
break;
default:
break;
}
}
void test_4(void *p) {
while (1)
{
process(p);
}
}
void test_5(void *pData) {
int kind = 0;
void *ptr = NULL;
printf("input kind:\n");
CID 358724: Unchecked return value from library (CHECKED_RETURN) [select issue]
scanf("%d", &kind);
1. Switch case default.
switch (kind) {
case 1:
ptr = malloc(100);
break;
case 2:
ptr = malloc(200);
break;
default:
2. alloc_fn: Storage is returned from allocation function malloc.
3. var_assign: Assigning: ptr = storage returned from malloc(64UL).
ptr = malloc(64);
4. Breaking from switch.
break;
}
5. Switch case default.
switch(kind) {
case 1:
memcpy(ptr, pData, 1000);
break;
case 2:
memcpy(ptr, pData, 2000);
break;
default:
6. noescape: Resource ptr is not freed or pointed-to in memcpy.
memcpy(ptr, pData, 64);
7. Breaking from switch.
break;
}
8. noescape: Resource (char *)ptr is not freed or pointed-to in printf.
printf("result: %s\n", (char *)ptr);
CID 358723 (#1-3 of 3): Resource leak (RESOURCE_LEAK)
9. leaked_storage: Variable ptr going out of scope leaks the storage it points to.
}
void test_6_sub(void *p) {
if (p == NULL) {
return;
}
free(p);
}
void test_6(void *p) {
test_6_sub(p);
}
int *n() {
return 0;
}
int main(void)
{
// int a;
// printf("input copy length: ");
// scanf("%d",&a);
// printf("copy %d bytes\n",a);
// void *p = malloc(100);
// memcpy(p, (char *)&a, a);
// printf("%s", (char *)&a);
gPtr = malloc(100);
char *p = gPtr;
free(gPtr);
char *name = "adfsasdfasdfasdfasdfasdf";
// test_4(p);
// test_6(p);
return *(n());
}
After analyse by coverity, I just do not get the vulnerability infomation what I want.
According to the introduction of Coverity
should be find the free of Null pointer vulnerability.
should be find the dead code
should be find the function call chains
But I got nothing
Is something wrong?
I got this test result at https://scan.coverity.com
Is the online service has some restrict?
The answer to the question in the title, "Does Coverity support Interprocedural-Analysis", is yes. The Coverity analysis indeed examines how functions call one another in an attempt to discover inconsistencies.
However, there are limitations to the precision of that interprocedural analysis. In particular, although it tries to keep track of relationships involving (at least) parameters, return values, and things pointed to by those, in most cases it cannot track relationships between global variables across function calls. (The reason for that is there are simply too many such variables and too many potential relationships, so trying to track them all would result in the analysis never terminating.)
In your example, there is an intended invariant that gPtr is a valid pointer if and only if gState == S_IDLE. Consequently, the handle_idle() function can only be called when gState == S_IDLE. The process() function violates that requirement by calling handle_idle() while gState == S_START, which (based on the clarification in the comments) is the bug you want to find. That deduction is unfortunately beyond the capabilities of the tool, so it does not report it.
Related
I am implementing Go back N protocol in C.I keep a char buffer and append the header informationa and data and send it to the server from the client process.
When I keep window size less than 10, the sequence number takes the value 1-9and occupies only one byte in the buffer. When the window size is >= 10 , sequence number may 1 or 2 bytes in the character array. So I am appending length of sequence number also as a header information. That time I am getting some random data written in the output file at the server. Whereas for window size less than 10 I coded without adding sequence no. length info. Everything works fine that time.
The codes are quiet exhaustive. Yet,
Can anybody suggest any corrections to be made in the code?
client code for window size 10:-
#include<stdio.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<time.h>
#include<sys/time.h>
unsigned short int checksum_2(void *buffer,unsigned int len,unsigned short int seed)
{
unsigned char *buf1 = (unsigned char*)buffer;
int i;
for(i=0;i<len;i++)
{
seed+=(unsigned int)(*buf1++);
}
//fold 32-bit sum to 16 bit
while(seed>>16)
seed = (seed & 0xFFFF)+ (seed>>16);
return seed;
}
unsigned short int checksum(unsigned char * buff,unsigned int count)
{
register unsigned int sum = 0;
//main summing loop
while(count >1)
{
sum += *((unsigned short int*) buff);
(buff)++;
count = count -2;
}
//add left over byte if any
if(count>0)
{
sum += *((unsigned char *)buff);
}
//fold 32-bit sum to 16 bit
while(sum>>16)
sum = (sum & 0xFFFF)+ (sum>>16);
return (~sum);
}
char* rand_corrupt(unsigned char* buff)
{
int n = strlen(buff);
char* str_temp = (char*)calloc(1,n); //allocate memory for a string
int i;
int num;
num = rand() %100;
if(num>95)
{
for(i=0;i<strlen(buff);i++)
{
buff[i] = buff[i]+1;
}
}
strcpy(str_temp,buff);
return str_temp;
}
char *itoa(long i,char *s,int dummy_radix)
{
sprintf(s,"%ld",i);
return s;
}
void rand_wait()
{
int num;
int i;
num = rand() %100;
if(num<5)
{
for(i=0;i<10;i++)
{
sleep(1);
}
}
return;
}
int
main (int argc, char **argv)
{
int sock,length,n;
struct sockaddr_in server,from;
struct hostent *hp;
long int packets =0;
clock_t t; //to measure CPU time
struct timeval start,end; //to measure actual execution time
struct timeval timer; //for the timer implementation
double time_diff;//to measure the timer for the execution time of code
unsigned short int check;
void* buff;
printf("initializing 2 d array\n");
char buf[1024][1024]={0};
printf("initialisation failed\n");
int nread[1024] = {0,};
char new_buff[65535]={0, };
char ack_buf[65535]={0, };
char* temp;
char checksum_info[1024]={0, } ;
char bytes_info[1024] = {0, } ;
unsigned short int bytes_len;
char bytes_len_str[1024]={0, };
char seqnum[10] = {0,};
int seq_no;
char current;
char data_1[75535]={0, };
unsigned short int check_length;
char check_len_str[1024]={0, };
char ack_check_len[1024]={0, };
unsigned short int ack_checksum_len;
char ack_check[65535]={0, };
unsigned short int ack_checksum;
char temp_buf[65535]={0, };
char temp_buffer[655]={0,};
unsigned short int actual_checksum;
unsigned short int length1;
char content[65535]={0, };
int i,j;
char end_flag =0; //to mark the end of file or error occured while reading file
int total_len[1024]={0,};
char data[1024][6553]= {0,};
char *tmp = NULL;
int msec,trigger;
clock_t difference,initial;
char ack_seqlen_char[8]= {0,};
int ack_seqlen;
int ack_seq;
char ack_seq_char[10] ={0,};
int seqnum_len;
char seqlen_char[10] = {0,};
t = clock();
gettimeofday(&start,NULL);
buff = calloc(1,1024);//allocating memory for message buffer
if(buff == NULL)
{
printf("memory allocation failedi\n");
return 1;
}
temp = calloc(1,65535); //allocating memory for new message
if(temp == NULL)
{
printf("memory allocation failed\n");
return 1;
}
// checking if hostname and the port address is provided //
if(argc!=3)
{
printf("insufficient arguments\n");
exit(1);
}
//create a socket//
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
{
printf("error in opening socket\n");
return 1;
}
//to get the hostname of the system or the machine//
hp= gethostbyname(argv[1]);
if(hp==0)
{
printf("Unknown host\n");
return 1;
}
//build the server's IP address //
bzero((char *)&server,sizeof(server));
bcopy((char*)hp->h_addr,(char *)&server.sin_addr,hp->h_length);
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
length = sizeof(server);
/*open the file that we wish to transfer*/
FILE *fp = fopen("alice.txt","rb");
if(fp==NULL)
{
printf("file open error");
return 1;
}
fseek(fp,0,SEEK_END); //if exists read the size of the file
size_t file_size = ftell(fp);
fseek(fp,0,SEEK_SET);
printf("size of the file is %d\n", file_size);
/*find the number of packets*/
if(file_size == 0)
{
packets = 0;
}
else
{
packets = (file_size/1024)+1 ;
}
/*send the number of packets to the server*/
itoa(packets,(char*)buff,10);
printf("packets =%s\n",(char*)buff);
n= sendto(sock,buff,1024,0,(struct sockaddr *)&server,sizeof(struct sockaddr));
if(n<0)
{
printf("error in sending message to the server");
return 1;
}
int loop =1;
/*Read data from file and send it*/
int packetNum = 0;
int N = 10;
int base = 1;
int nextseqnum =1;
int sequence;
int seqnum_next = 1;
while(1)
{
while(nextseqnum<base+N) //send N consecutive packets
{
memset(buf[nextseqnum], 0, 65535); //clear the contents of buf before fread
memset(seqnum,0,10);
memset(seqlen_char,0,10);
memset(checksum_info,0,1024);
memset(check_len_str,0,1024);
memset(bytes_info,0,1024);
memset(bytes_len_str,0,1024);
memset(data[nextseqnum],0,6553);
/*First read file in chunks of 1024 bytes */
nread[nextseqnum] = fread(buf[nextseqnum],1,1024,fp);
printf("Bytes read %d\n",nread[nextseqnum]);
/*if read was success ,send data*/
if(nread[nextseqnum]>0)
{
printf ("I am HERE\n");
check = checksum(buf[nextseqnum],nread[nextseqnum]); //calculate the checksum
printf("checksum is %d\n",check);
itoa(check,checksum_info,10); //convert checksum into string
check_length = strlen(checksum_info); //calculate the length of the checksum
itoa(check_length,check_len_str,10); //convert the checksum lenght to string form
itoa(nread[nextseqnum],bytes_info,10); //the data length in string format
bytes_len = strlen(bytes_info);
itoa(bytes_len,bytes_len_str,10);
itoa(seqnum_next,seqnum,10); //combine seq no,checksum and the data content into one packet
printf("sequence number is %s\n",seqnum);
seqnum_len = strlen(seqnum); //getting the length of the sequence
itoa(seqnum_len,seqlen_char,10); //converting it into string format
strncat(data[nextseqnum],seqlen_char,strlen(seqlen_char));
strncat(data[nextseqnum],seqnum,strlen(seqnum));
strncat(data[nextseqnum],check_len_str,(strlen(check_len_str)));
strncat(data[nextseqnum],checksum_info,(strlen(checksum_info))); //adding checksum
strncat(data[nextseqnum],bytes_len_str,strlen(bytes_len_str)); //adding data length
strncat(data[nextseqnum],bytes_info,strlen(bytes_info)); //adding the data length info
j= seqnum_len+3+bytes_len+check_length;
for(i=0;i<nread[nextseqnum];i++)
{
data[nextseqnum][j] = buf[nextseqnum][i];
j++;
}
total_len[nextseqnum] = nread[nextseqnum]+3+bytes_len+check_length;//finding the total length
data[nextseqnum][total_len[nextseqnum]] = '\0';
n= sendto(sock,data[nextseqnum],total_len[nextseqnum],0,(struct sockaddr *)&server,sizeof(struct sockaddr));///send the data packet after adding the header info
if(n<0)
{
printf("error in sending message to the server");
fclose(fp);
return 1;
}
if(nextseqnum == base)
{
msec = 0;
trigger = 50; /*50 ms*/
initial = clock(); /*start the timer*/
}
nextseqnum++;
seqnum_next = nextseqnum%N;
if(seqnum_next == 0)
{
seqnum_next = N;
}
sleep(1);
}
/*There is something tricky going on with the read..
* Either there was error ,or we reached end of file.
*/
else
{
if(feof(fp))
printf("End of file\n");
if(ferror(fp))
printf("Error reading\n");
end_flag = 1; //set the flag that it has reached EOF or encountered error
break;
}
}
while(1) //wait for the acknowledgement for the sent packets till timeout , here timer value is set to 50 ms
{
difference = clock()-initial;
msec = difference*1000/CLOCKS_PER_SEC;
if(msec<trigger) //if it is not timeout then receive the ack packets
{
memset(ack_buf, 0, 65535); //clear the contents of ack_buf
memset(ack_check_len,0,1024);
memset(ack_check,0,65535);
memset(content,0,65535);
memset(temp_buf,0,65535);
//printf ("Receiving packet\n");
n = recvfrom(sock,ack_buf,1024,MSG_DONTWAIT,&server, &length); //receive the ack from the server
if(n>0)
{
j=0;
for(i=0;i<1;i++)
{
temp_buffer[j] = ack_buf[i];
j++;
}
temp_buffer[j] = '\0';
strcpy(ack_seqlen_char,temp_buffer);//get the length of the ack sequence //number
ack_seqlen = atoi(ack_seqlen_char); //converting it to int
j=0;
for(i=1;i<1+ack_seqlen;i++)
{
ack_seq_char[j]= ack_buf[i];
j++; //next bytes till i=ack_seqlen will be sequence number
}
seq_no = atoi(ack_seq_char);
printf("Ack received for the sequence number %d\n",seq_no);
j =0;
for(i=1+ack_seqlen;i<2+ack_seqlen;i++) //next byte will have the length of checksum
{
temp_buf[j] = ack_buf[i]; //extracting the checksum length
j++;
}
temp_buf[j] = '\0'; //ending the string with a null character
strcpy(ack_check_len,temp_buf); //length of checksum will be in string format
ack_checksum_len = atoi(ack_check_len); //convert it into int
j = 0;
for(i=2+ack_seqlen;i<(2+ack_seqlen+ack_checksum_len);i++) //extract the checksum
{
ack_check[j] = ack_buf[i];
j++;
}
ack_check[j] ='\0';
ack_checksum = atoi(ack_check); //the checksum will be in string format,convert it into the integer format
j=0; //extract the content i.e the actual ack message
while(i<n)
{
content[j] = ack_buf[i];
i++;
j++;
}
content[j] ='\0';
length1 = strlen(content);
actual_checksum = checksum(content,length1);//calculate the actual checksum
printf("checksum of the ack received is %d\t and the checksum of the ack sent is %d\n",actual_checksum,ack_checksum);
if(actual_checksum == ack_checksum) //if the ack is not corrupt then update the base
{
printf("successfully recived packet %d\n",seq_no);
base =seq_no+1;
if(base == nextseqnum) //go to sending next series of packets
{
printf ("base is %d\n", base);
break;
}
else
{
initial = clock(); //start timer for next in-flight packet
}
}
else //if it is a corrupt ack
{
printf("Ack corrupted,wait till timeout\n");
}
} else {
if (end_flag == 1) {
printf ("Reached END\n");
break;
}
}
}
else //if the timer is out, resend the packet from the packet with seqno
// base till nextseqnum-1,start timer
{
initial = clock();
sequence = base;
while(sequence <= nextseqnum-1)
{
n= sendto(sock,data[sequence],total_len[sequence],0,(struct sockaddr *)&server,sizeof(struct sockaddr));///send the data packet after adding the header info
if(n<0)
{
printf("error in sending message to the server");
fclose(fp);
return 1;
}
sleep(0.5);
}
}
}
if(end_flag == 1) //if there had been an error in reading file of EOF had reached break out of
// the outermost while loop
{
printf ("I am at the END\n");
break;
}
}
printf ("Sending finish packet\n");
strcpy(buff,"Finish");
n= sendto(sock,buff,1024,0,(struct sockaddr *)&server,sizeof(struct sockaddr));
if(n<0)
{
printf("error in sending message to the server");
return 1;
}
fclose(fp); //close the file to complete the transmission
t = clock()-t;
gettimeofday(&end,NULL);
double time_taken = ((double)t)/CLOCKS_PER_SEC; //in secconds
printf(" The CPU time for transmission %f seconds \n",time_taken);
double delta = ((end.tv_sec - start.tv_sec)*1000000u+ end.tv_usec - start.tv_usec)/1.e6;
printf("The actual execution time took %f seconds\n", delta);
close(sock); //close api tries to complete the transmission if there is data waiting to be transmitted
return 0;
}
I attach here my kernel module I developed and the test I am using at application level
memalloc.c
/*
* DMA memory allocation
* This kernel module allocates coherent, non-cached memory
* and returns the physical and virtual address of the allocated buffer
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include "memalloc.h"
#define DEVICE_NAME "memalloc"
// Max number of buffers
#define BUFFER_MAX_NUMBER 16
// Structure for buffer information
struct bufferInfo {
int active;
int size;
dma_addr_t handle;
int virtualAddress;
int *kernelAddress;
};
static struct bufferInfo bufferInfoTable[BUFFER_MAX_NUMBER];
// Defines which buffer is currently active - for mmap
static int activeBufferID;
struct memAllocIF {
struct device *device_p;
dev_t dev_node;
struct cdev cdev;
struct class *class_p;
};
static struct memAllocIF interface;
// Methods
static int releaseBuffer(int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
printk("Releasing buffer %d\n", i);
bufferInfoTable[i].active = 0;
dma_free_coherent(NULL, bufferInfoTable[i].size, bufferInfoTable[i].kernelAddress, bufferInfoTable[i].handle);
return 0;
}
static int reserveBuffer(size_t size)
{
int i;
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
if (bufferInfoTable[i].active == 0)
{
printk("Reserving buffer %d\n", i);
bufferInfoTable[i].active = 1;
break;
}
}
if (i < BUFFER_MAX_NUMBER)
{
bufferInfoTable[i].kernelAddress = dma_alloc_coherent(NULL, size, &bufferInfoTable[i].handle, GFP_KERNEL);
if (bufferInfoTable[i].kernelAddress == NULL)
{
printk("Allocation failure\n");
return -1;
}
bufferInfoTable[i].size = (int)size;
return i;
}
else
{
printk("No buffer available\n");
return -1;
}
}
static void cleanup(void)
{
int i;
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
if (bufferInfoTable[i].active != 0)
{
dma_free_coherent(NULL, bufferInfoTable[i].size, bufferInfoTable[i].kernelAddress, bufferInfoTable[i].handle);
bufferInfoTable[i].active = 0;
}
}
}
static unsigned int memAllocGetVirtual (int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
if (bufferInfoTable[i].active == 0)
{
printk("Inactive buffer - ID %d\n", i);
return -1;
}
printk("request for buffer %d: vaddr = %X\n", i, (unsigned int)bufferInfoTable[i].virtualAddress);
return bufferInfoTable[i].virtualAddress;
}
static unsigned int memAllocGetPhysical (int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
return (unsigned int)bufferInfoTable[i].handle;
}
static long memAllocIoctl (struct file *fd, unsigned int cmd, unsigned long arg)
{
printk("received command %u arg %lu\n", cmd, arg);
switch(cmd)
{
case MEMALLOC_RESERVE:
return reserveBuffer(arg);
break;
case MEMALLOC_RELEASE:
return releaseBuffer(arg);
break;
case MEMALLOC_GET_VIRTUAL:
return memAllocGetVirtual(arg);
break;
case MEMALLOC_GET_PHYSICAL:
return memAllocGetPhysical(arg);
break;
case MEMALLOC_ACTIVATE_BUFFER:
if (arg > BUFFER_MAX_NUMBER || bufferInfoTable[arg].active == 0)
{
printk("Wrong bufferID %lu\n", arg);
return -1;
}
activeBufferID = arg;
return arg;
break;
default:
printk("Wrong command: %d\n", cmd);
return -1;
break;
}
}
static int memAllocMmap (struct file *fd, struct vm_area_struct *vma)
{
bufferInfoTable[activeBufferID].virtualAddress = dma_common_mmap(interface.device_p, vma, bufferInfoTable[activeBufferID].kernelAddress, bufferInfoTable[activeBufferID].handle, vma->vm_end-vma->vm_start);
printk("mmap for idx %d: vaddr = %X\n", activeBufferID, (int)bufferInfoTable[activeBufferID].virtualAddress);
return bufferInfoTable[activeBufferID].virtualAddress;
}
static int memAllocRelease(struct inode *in, struct file *fd)
{
cleanup();
return 0;
}
static int memAllocOpen(struct inode *ino, struct file *file)
{
file->private_data = container_of(ino->i_cdev, struct memAllocIF, cdev);
return 0;
}
static struct file_operations fops = {
.unlocked_ioctl = memAllocIoctl,
.mmap = memAllocMmap,
.release = memAllocRelease,
.open = memAllocOpen
};
static int __init memAllocInit(void)
{
int rc;
int i;
static struct class *local_class_p = NULL;
printk("Loading DMA allocation module\n");
// Allocate a character device from the kernel for this driver
rc = alloc_chrdev_region(&interface.dev_node, 0, 1, DEVICE_NAME);
if (rc)
{
printk("Unable to get a char device number\n");
return rc;
}
// Initialize the ter device data structure before registering the character device with the kernel
cdev_init(&interface.cdev, &fops);
rc = cdev_add(&interface.cdev, interface.dev_node, 1);
if (rc)
{
printk("Unable to add char device\n");
cdev_del(&interface.cdev);
return rc;
}
// Create the device in sysfs which will allow the device node in /dev to be created
local_class_p = class_create(THIS_MODULE, DEVICE_NAME);
interface.class_p = local_class_p;
// Create the device node in /dev so the device is accessible as a character device
interface.device_p = device_create(interface.class_p, NULL, interface.dev_node, NULL, DEVICE_NAME);
if (IS_ERR(interface.device_p))
{
printk("Unable to create the device\n");
class_destroy(interface.class_p);
cdev_del(&interface.cdev);
return rc;
}
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
bufferInfoTable[activeBufferID].active = 0;
}
return 0;
}
static void __exit my_memAllocExit(void)
{
printk("Module unloading\n");
cleanup();
cdev_del(&interface.cdev);
device_destroy(interface.class_p, interface.dev_node);
class_destroy(interface.class_p);
unregister_chrdev_region(interface.dev_node, 1);
}
module_init(memAllocInit);
module_exit(my_memAllocExit);
MODULE_AUTHOR("me");
MODULE_DESCRIPTION("Create a buffer and return physical and virtual address, for DMA userspace driver");
MODULE_LICENSE("GPL");
memalloc.h
#ifndef MEMALLOC_H
#define MEMALLOC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <linux/types.h>
#include <asm/ioctl.h>
static long memAllocIoctl (struct file *, unsigned int, unsigned long);
static int memAllocMmap (struct file *, struct vm_area_struct *);
static int memAllocRelease (struct inode *, struct file *);
static int memAllocOpen(struct inode *, struct file *);
enum memAllocCmd
{
MEMALLOC_RESERVE = 0,
MEMALLOC_RELEASE = 1,
MEMALLOC_GET_VIRTUAL = 2,
MEMALLOC_GET_PHYSICAL = 3,
MEMALLOC_ACTIVATE_BUFFER = 4,
};
#ifdef __cplusplus
}
#endif
#endif /* MEMALLOC_H */
test.c
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
// derive this from memalloc.h
enum memAllocCmd
{
MEMALLOC_RESERVE = 0,
MEMALLOC_RELEASE = 1,
MEMALLOC_GET_VIRTUAL = 2,
MEMALLOC_GET_PHYSICAL = 3,
MEMALLOC_ACTIVATE_BUFFER = 4,
};
int main ()
{
int memAllocFd;
volatile int iVaddr;
volatile int oVaddr;
volatile int iVaddr_2;
volatile int oVaddr_2;
volatile void * iPaddr;
volatile void * oPaddr;
int iBufID;
int oBufID;
int size = 2048;
memAllocFd = open("/dev/memalloc", O_RDWR);
// create iBuffer
iBufID = ioctl(memAllocFd, MEMALLOC_RESERVE, size);
iPaddr = (void *)ioctl(memAllocFd, MEMALLOC_GET_PHYSICAL, iBufID);
ioctl(memAllocFd, MEMALLOC_ACTIVATE_BUFFER, iBufID);
iVaddr = (int)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, memAllocFd, 0);
ioctl(memAllocFd, MEMALLOC_GET_VIRTUAL, iBufID);
/*
if (iVaddr != iVaddr_2)
{
printf("Error: virtual addresses for buffer %d don't match: %X %X\n", iBufID, iVaddr, iVaddr_2);
}
*/
// create oBuffer
oBufID = ioctl(memAllocFd, MEMALLOC_RESERVE, size);
oPaddr = (void *)ioctl(memAllocFd, MEMALLOC_GET_PHYSICAL, oBufID);
ioctl(memAllocFd, MEMALLOC_ACTIVATE_BUFFER, oBufID);
oVaddr = (int)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, memAllocFd, 0);
ioctl(memAllocFd, MEMALLOC_GET_VIRTUAL, oBufID);
/*
if (oVaddr != oVaddr_2)
{
printf("Error: virtual addresses for buffer %d don't match: %X %X\n", oBufID, oVaddr, oVaddr_2);
}
*/
ioctl(memAllocFd, MEMALLOC_RELEASE, iBufID);
ioctl(memAllocFd, MEMALLOC_RELEASE, oBufID);
return 0;
}
Result of the test is
received command 0 arg 2048
Reserving buffer 0
received command 3 arg 0
received command 4 arg 0
mmap for idx 0: vaddr = 0
received command 0 arg 2048
Reserving buffer 1
received command 3 arg 1
received command 4 arg 1
mmap for idx 1: vaddr = 0
received command 1 arg 0
Releasing buffer 0
received command 1 arg 1
Releasing buffer 1
Which means that all ioctl calls with arg=MEMALLOC_GET_VIRTUAL are not executed, while all the others are.
What can be the reason for that?
Thanks,
Max
Hello I've written the following code which is a part of a project. It is used to find the ESSID of the current associated network.
But it has a flaw: it also the displays the ESSID of the network with which I am not associated i.e. if I try to associate myself with a wireless n/w and if it is unsuccessful i.e. NO DHCP OFFERS ARE RECEIVED, then also it will display the that ESSID with which I have made my attempt.
Could anyone give me an ioctl call to find the BSSID of current associated wireless n/w?. In my opinion it is the only way with which I a can mark b/w associated and non associated.
CODE:-
int main (void)
{
int errno;
struct iwreq wreq;
CStdString result = "None";
int sockfd;
char * id;
char ESSID[100];
memset(&wreq, 0, sizeof(struct iwreq));
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "Cannot open socket \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description is : %s\n",strerror(errno));
return result ;
}
CLog::Log(LOGINFO,"Socket opened successfully");
FILE* fp = fopen("/proc/net/dev", "r");
if (!fp)
{
// TBD: Error
return result;
}
char* line = NULL;
size_t linel = 0;
int n;
char* p;
int linenum = 0;
while (getdelim(&line, &linel, '\n', fp) > 0)
{
// skip first two lines
if (linenum++ < 2)
continue;
p = line;
while (isspace(*p))
++p;
n = strcspn(p, ": \t");
p[n] = 0;
strcpy(wreq.ifr_name, p);
id = new char[IW_ESSID_MAX_SIZE+100];
wreq.u.essid.pointer = id;
wreq.u.essid.length = 100;
if ( ioctl(sockfd,SIOCGIWESSID, &wreq) == -1 ) {
continue;
}
else
{
strcpy(ESSID,id);
return ESSID;
}
free(id);
}
free(line);
fclose(fp);
return result;
}
The following code compiles successfully and returns the correct results when called the first time. Making the same call a second time, I get a segmentation fault error.
//% function TF = InWindow(Date,WindowStartDates,WindowEndDates,EndHint)
//% INWINDOW returns true for window that contains Date. All inputs must be
//% uint32 and WindowEndDates must be sorted.
//% EndHint is an optional input that specifies the row number to start
//% searching from.
#include "mex.h"
#include "matrix.h"
#include "math.h"
void CalculationRoutine(mxLogical *ismember, uint32_T *Date, uint32_T *WindowStartDates, uint32_T *WindowEndDates, unsigned int *StartIndex, int NumObs) {
mwIndex Counter;
// Find the first window that ends on or after the date.
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) {
if (*Date <= *(WindowEndDates+Counter)) {
break;
}
}
*StartIndex = (unsigned int) Counter;
// Now flag every observation within the window. Remember that WindowStartDates
// is not necessarily sorted (but WindowEndDates is).
for (Counter = (mwIndex) *StartIndex; Counter < NumObs; Counter++) {
if (*Date >= *(WindowStartDates+Counter)) {
*(ismember+Counter) = true;
}
}
}
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
mxArray *ismember;
unsigned int *StartIndex;
//Input Checking.
if (nrhs == 3) {
// Default Hint to first entry.
mexPrintf("SI Starts OK.\n");
*StartIndex = 1;
mexPrintf("SI Ends OK.\n");
} else if (nrhs == 4) {
if (!mxIsUint32(prhs[3])) {
mexErrMsgTxt("EndHint must be uint32.");
}
StartIndex = mxGetData(prhs[3]);
} else {
mexErrMsgTxt("Must provide three or four input arguments.");
}
// Convert the hint to base-zero indexing.
*StartIndex = *StartIndex - 1;
// Check the inputs for the window range.
if (!mxIsUint32(prhs[0])) {
mexErrMsgTxt("DatesList must be uint32.");
}
if (!mxIsUint32(prhs[1])) {
mexErrMsgTxt("WindowStartsDates must be uint32.");
}
if (!mxIsUint32(prhs[2])) {
mexErrMsgTxt("WindowEndsDates must be uint32.");
}
if (mxGetM(prhs[1]) != mxGetM(prhs[2])) {
mexErrMsgTxt("WindowStartDates must be the same length as WindowEndDates.");
}
// Prepare the output array.
ismember = mxCreateLogicalArray(mxGetNumberOfDimensions(prhs[1]), mxGetDimensions(prhs[1]));
CalculationRoutine(mxGetLogicals(ismember),mxGetData(prhs[0]),
mxGetData(prhs[1]), mxGetData(prhs[2]), StartIndex, (int) mxGetM(prhs[1]));
plhs[0] = ismember;
}
I call it with:
>>InWindow(uint32(5),uint32((1:6)'),uint32((3:8)'))
The code reaches the line between the two mexPrintf calls before the segmentation fault (ie the first call prints, but not the second).
I am on Matlab 2007a (yes, I know), Win7 64bit and VS 2008.
You need to initialize the pointer StartIndex - you're "lucky" that it works the first time, since it is not pointing to a defined memory location. Why not do something more like:
unsigned int StartIndex;
// and either:
StartIndex = 1;
// or:
StartIndex = * (static_cast< unsigned int * >( mxGetData(prhs[3]) ) );
My professor asks this question for Homework.
Consult a Linux Manual or a Microsoft Windows manual. Find the actual contents of the Process Control Block (Process Descriptor) in the operating system of your choice.
I know in general PCB contains
Process number or process ID
Process state
Program counter
CPU registers
CPU scheduling information
Memory-management information
Accounting information
I/O status information
I am trying to find manual but I did not see it online. Could anybody help me with this.
From what I understand in Linux, PCB or Process Descriptors are dynamically allocated by the kernel and cannot directly be read from user-space.
IBM's developerWorks library has a nice article which shows you how to create a kernel module for Linux and access task_struct struct.
http://www.ibm.com/developerworks/linux/library/l-linux-process-management/index.html
Hope this helps.
edit: task_struct as defined in Linux v2.6.37 : http://lxr.linux.no/#linux+v2.6.37/include/linux/sched.h#L1182
Courtesy of google. :)
For Linux, start here (and go to more current versions of the Linux kernel). Though old, this should sufficiently help find your answer.
For windows, you can take a look at the user-mode equivalent called the 'PEB'. It can be inspected using WinDbg using '!peb'.
This could help you out. I previously post it but I had to cancel my account for security reasons.
#include <iostream>
#include <sstream>
#include <vector>
#include <list>
#include <string>
#include "proc.h"
#include "rq.h"
using namespace std;
// creates a vector of Queues
void load_queue(vector<rq> &queue, unsigned int num_of_queues)
{
for(int pos=0; pos<num_of_queues; pos++)
{
queue.push_back(rq());
}
}
//returns the biggest queue position in the vector
unsigned int get_biggest_queue_pos(vector<rq> queues)
{
unsigned int queue_pos = 0; // Pos of smaller queue. Default 0.
unsigned int queue_size = queues.at(queue_pos).size(); // Its size
for(unsigned int pos = 0; pos < queues.size(); pos++)
{
if(queues.at(pos).size() > queue_size)
{
queue_pos = pos;
queue_size = queues.at(pos).size();
}
}
return queue_pos; // Return smaller queue position in vector.
}
// Returns the smaller queue position in the vector.
unsigned int get_smaller_queue_pos(vector<rq> queues)
{
unsigned int queue_pos = 0; // Pos of smaller queue. Default 0.
unsigned int queue_size = queues.at(queue_pos).size(); // Its size
for(unsigned int pos = 0; pos < queues.size(); pos++)
{
if(queues.at(pos).size() < queue_size)
{
queue_pos = pos;
queue_size = queues.at(pos).size();
}
}
return queue_pos; // Return smaller queue position in vector.
}
//Searches for a PID in entire system and erases it.
bool get_pid_process(vector<rq> &queue, int id)
{
vector <proc> temp;
proc process(0,0,0);
int check;
int number=id;
int size=queue.size();
/*checks rest of queues, including ready queues and device queues*/
for(int i=0; i<size; i++)
{
temp=queue[i].get_queue();
int size1=temp.size();
for(int j=0; j<size1; j++)
{
process=temp.at(j);
check=process.get_pid();
if(check==number)
{
cout<<"Process found in a queue and being erased..."<<endl;
queue[i].remove_process(j);
float cputime=process.get_burst();
float burstime=process.get_average();
cout<<"Process information:"<<endl;
cout<<"PID: "<<number<<endl<<"Acc CPU time: "<<cputime<<endl<<"Average burst time: "<<burstime<<endl;
cout<<"Process killed"<<endl<<endl;
return true;
}
}
}
/*Checks all CPUs in ready queues*/
for(int k=0; k<size; k++)
{
temp=queue[k].get_cpu();
process=temp.front();
check=process.get_pid();
if(check==number)
{
cout<<"Process found in a CPU and being erased..."<<endl;
float cputime=process.get_burst();
float burstime=process.get_average();
queue[k].clear_cpu();
cout<<"Process information:"<<endl;
cout<<"PID: "<<number<<endl<<"Acc CPU time: "<<cputime<<endl<<"Average burst time: "<<burstime<<endl;
cout<<"Process killed"<<endl<<endl;
return true;//ends if PID is found in CPU and returns true
}
}
return false;
}
int main()
{
cout << "Sys gen starting..."<<endl;
cout<<"Please enter the amount of CPUs (between 1 and 9)"<<endl;
int cpu;
cin>>cpu;
while(cpu<1 || cpu>9)
{
cout<<"Invalid value, please re-enter amount:"<<endl;
cin>>cpu;
}
cout<<"Enter amount of PRINTERs:"<<endl;
int pr;
cin>>pr;
cout<<"Enter amount of DISKs:"<<endl;
int di;
cin>>di;
cout<<"Enter amount of CD/RWs:"<<endl;
int cd;
cin>>cd;
int devices=(cpu*2)+pr+di+cd;//amount of devices(queues and CPU's)
int PID=0;
int PCB=0;
vector<rq> RQ; //vector of ready queues
vector<rq> PQ; //vector of printer queues
vector<rq> DQ; //vector of disk queues
vector<rq> CQ; //vector of CD/RW queues
load_queue(RQ, cpu);
load_queue(PQ, pr); //load printer queues to PQ vector
load_queue(DQ, di); // ...
load_queue(CQ, cd); // ...
cout << "Running section..." <<endl<< endl;
cout<<"Start inputting commands; To terminate program press E or e at any time:"<<endl;
while(true)
{
string device;//for name of device
string enter;//for input
cin>>enter;
int correspond=0;
int smaller;
char num11=enter[0];//1st position character
char input=enter[1];//2nd position char
char num=enter[2];//3rd position char
int num1=num11 -'0';//1st position integer
int n=num -'0';//3rd position int
int inp=input - '0';//2nd position int
int empty;
/*creates a new process and puts it into emptiest Ready Queue*/
if(num11=='A')
{
smaller=get_smaller_queue_pos(RQ); //determines which ready queue has less processes
RQ[smaller].create_process(smaller, PID, PCB);
PID++;
PCB++;
if(RQ[smaller].get_cpu().size() == 0)
{
RQ[smaller].cpu();
}
}
/*terminates a process from a particular CPU*/
else if(input=='t')
{
if(num1>0 && num1<=cpu)
{
RQ[num1-1].terminate();
PCB--;
RQ[num1-1].cpu();
}
else
{
cout<<"Invalid entry"<<endl;
}
}
/*Prints out a snapshot of a particular device Q or the ready queues*/
else if(num11 == 'S')
{
cout << "Select a queue: "<<endl;
char sele;
cin >> sele;
switch(sele)
{
case 'p':
if(pr==0)
{
cout<<"There are no printer queues created."<<endl;
}
else
{
device="Printer";
cout<<"A snapshot of your "<<device<<" queues:"<<endl<<"PCB\tPID\tLENGTH\tLOCATION\tFILE NAME\tUsed CPU time(ms)\tAverage Burst time(ms)"<<endl;
for(int i = 0; i < PQ.size(); i++)
{
cout<<device<<" "<<i+1<<":"<<endl;
PQ.at(i).snapshot(device);
}
}
break;
case 'r':
cout<<endl<<"___A Snapshot of your Ready Queue(s)___"<<endl;
for(int i = 0; i < RQ.size(); i++)
{
cout<<"Ready queue "<<i+1<<":"<<endl;
RQ[i].snapshot();
}
break;
case 'd':
if(di==0)
{
cout<<"There are no disk queues created."<<endl;
}
else
{
device="Disk";
cout<<"A snapshot of your "<<device<<" queues:"<<endl<<"PCB\tPID\tLENGTH\tLOCATION\tFILE NAME\tUsed CPU time(ms)\tAverage Burst time(ms)"<<endl;
for(int i = 0; i < PQ.size(); i++)
{
cout<<device<<" "<<i+1<<":"<<endl;
DQ.at(i).snapshot(device);
}
}
break;
case 'c':
if(cd==0)
{
cout<<"There are no cd/rw queues created."<<endl;
}
else
{
device="Cd/rw";
cout<<"A snapshot of your "<<device<<" queues:"<<endl<<"PCB\tPID\tLENGTH\tLOCATION\tFILE NAME\tUsed CPU time(ms)\tAverage Burst time(ms)"<<endl;
for(int i = 0; i < PQ.size(); i++)
{
cout<<device<<" "<<i+1<<":"<<endl;
CQ.at(i).snapshot(device);
}
}
break;
default:
cout << "No such queue; wrong option." << endl;
break;
}
}
/*moves a process from a particular CPU into a particular printer queue*/
else if(input=='p')
{
if(n>pr)
{
cout<<"You are exceding the amount of queues available for this device."<<endl;
}
else
{
/*start of push */
vector <proc> temp1;
int big;
temp1=RQ[num1-1].get_cpu();
if (temp1.empty())
{
big=get_biggest_queue_pos(RQ);
temp1=RQ[big].get_front();
temp1.at(0).change_q(num1-1);
RQ[num1-1].enter_to_rq(temp1.front());
RQ[num1-1].cpu();
}
/*end of push */
int ind=1;// to determines it's a printer when asking for parameters
vector <proc> temp;
temp=RQ[num1-1].get_cpu();
int nn=temp.at(0).get_first();//to determine if process already has parameters (if nn=1)
if(nn==0)
{
RQ[num1-1].get_info(ind);//input process parameters
RQ[num1-1].bur_info();
temp=RQ[num1-1].get_cpu();
}
else
{
RQ[num1-1].bur_info();
temp=RQ[num1-1].get_cpu();
}
RQ[num1-1].clear_cpu();
proc te(0,0,0);
te=temp.front();
PQ[n-1].enter_to_rq(te);
}
}
/*moves a process from a particular CPU into a particular disk queue*/
else if(input=='d')
{
if(n>di)
{
cout<<"You are exceding the amount of queues available for this device."<<endl;
}
else
{
/*start of push */
vector <proc> temp1;
int big;
temp1=RQ[num1-1].get_cpu();
if (temp1.empty())
{
big=get_biggest_queue_pos(RQ);
temp1=RQ[big].get_front();
temp1.at(0).change_q(num1-1);
RQ[num1-1].enter_to_rq(temp1.front());
RQ[num1-1].cpu();
}
/*end of push */
int ind=0;// to determine it's a printer when asking for parameters
vector <proc> temp;
temp=RQ[num1-1].get_cpu();
int nn=temp.at(0).get_first();//to determine if process already has parameters (if nn=1)
if(nn==0)
{
RQ[num1-1].get_info(ind);//input process parameters
RQ[num1-1].bur_info();
temp=RQ[num1-1].get_cpu();
}
else
{
RQ[num1-1].bur_info();
temp=RQ[num1-1].get_cpu();
}
RQ[num1-1].clear_cpu();
proc te(0,0,0);
te=temp.front();
DQ[n-1].enter_to_rq(te);
}
}
/*moves a process from a particular CPU into a particular cd/rw queue*/
else if(input=='c')
{
if(n>pr)
{
cout<<"You are exceding the amount of queues available for this device."<<endl;
}
else
{
/*start of push */
vector <proc> temp1;
int big;
temp1=RQ[num1-1].get_cpu();
if (temp1.empty())
{
big=get_biggest_queue_pos(RQ);
temp1=RQ[big].get_front();
temp1.at(0).change_q(num1-1);
RQ[num1-1].enter_to_rq(temp1.front());
RQ[num1-1].cpu();
}
/*end of push */
int ind=0;// to determine it's a printer when asking for parameters
vector <proc> temp;
temp=RQ[num1-1].get_cpu();
int nn=temp.at(0).get_first();//to determine if process already has parameters (if nn=1)
if(nn==0)
{
RQ[num1-1].get_info(ind);//input process parameters
RQ[num1-1].bur_info();
temp=RQ[num1-1].get_cpu();
}
else
{
RQ[num1-1].bur_info();
temp=RQ[num1-1].get_cpu();
}
RQ[num1-1].clear_cpu();
proc te(0,0,0);
te=temp.front();
CQ[n-1].enter_to_rq(te);
}
}
/*moves a process from a particular printer queue to it's ready queue*/
else if(num11=='P')
{
if(enter=="P")
{
cout<<"missing values"<<endl;
}
else if(inp>pr)
{
cout<<"Invalid input."<<endl;
}
else if(PQ[inp-1].tamano()==0)
{
cout<<"There are no more processes in the Queue"<<endl;
}
else
{
vector<proc> temp;
temp=PQ[inp-1].get_device();
proc te(0,0,0);
te=temp.front();
correspond=te.get_q();
RQ[correspond].enter_to_rq(te);
}
}
/*moves a process from a particular disk queue to it's ready queue*/
else if(num11=='D')
{
if(enter=="D")
{
cout<<"missing values"<<endl;
}
else if(inp>di)
{
cout<<"Invalid input."<<endl;
}
else if(DQ[inp-1].tamano()==0)
{
cout<<"There are no more processes in the Queue"<<endl;
}
else
{
vector<proc> temp;
temp=DQ[inp-1].get_device();
correspond=DQ[inp-1].queue();
proc te(0,0,0);
te=temp.front();
correspond=te.get_q();
RQ[correspond].enter_to_rq(te);
}
}
/*moves a process from a particular cr/rw queue to it's ready queue*/
else if(num11=='C')
{
if(enter=="C")
{
cout<<"missing values"<<endl;
}
else if(inp>cd)
{
cout<<"Invalid input."<<endl;
}
else if(CQ[inp-1].tamano()==0)
{
cout<<"There are no more processes in the Queue"<<endl;
}
else
{
vector<proc> temp;
temp=CQ[inp-1].get_device();
correspond=PQ[inp-1].queue();
proc te(0,0,0);
te=temp.front();
correspond=te.get_q();
RQ[correspond].enter_to_rq(te);
}
}
/*terminates program*/
else if(num11=='E' || num11=='e')
{
return 0;
}
/*Moves process from CPU to it's ready queue*/
else if(input=='T')
{
if(enter=="T")
{
cout<<"missing values"<<endl;
}
else if (num1>cpu)
{
cout<<"Invalid entry, no such CPU."<<endl;
}
else if (num1==0)
{
cout<<"Invalid entry, no such CPU."<<endl;
}
else
{
vector<proc> temp;
temp=RQ[num1-1].get_cpu();
RQ[num1-1].cpu_clear();
proc te(0,0,0);
te=temp.at(0);
RQ[num1-1].enter_to_rq(te);
RQ[num1-1].clear_cpu();
}
}
/*Kills a process determined by it's PID*/
else if(num11=='K')
{
if(enter=="K")
{
cout<<"missing values"<<endl;
}
else
{
/*Borrowed code to convert a string into an int*/
/*converts the rest of numbers into a separate string*/
int n=enter.length();
char number[n-1];
for (int j=0; j<n; j++)
{
number[j]=enter[j+1];
}
string final=number;
/*end of conversion, final= string containing PID*/
/*convert the string final into an int*/
int id;
stringstream test(final);
test>>id;
/*end of conversion, id= int containing PID*/
/*End of Borrowed code to convert a string into an int*/
if (id > PID)
{
cout<<"Invalid PID, no such process"<<endl;
}
else
{
/*Check if PID is in a Q or CPU and delete process*/
bool buscar;
buscar=get_pid_process(RQ, id);
if(buscar==false)
{
buscar=get_pid_process(PQ, id);
}
if(buscar==false)
{
buscar=get_pid_process(DQ, id);
}
if(buscar==false)
{
buscar=get_pid_process(CQ, id);
}
if(buscar==false)
{
cout<<"Process not found."<<endl;
}
}
}
}
/*If invalid input*/
else
{
cout<<"Invalid input, re-enter command."<<endl<<endl;
}
}
return 0;
}
PROCESS CONTROL BLOCK
There is a Process Control Block for each process, enclosing all the information about the process. It is a data structure, which contains the following :
Process State - It can be running, waiting etc.
Process ID and parent process ID.
CPU registers and Program Counter. Program Counter holds the address of the next instruction to be executed for that process.
CPU Scheduling information - Such as priority information and pointers to scheduling queues.
Memory Management information - Eg. page tables or segment tables.
Accounting information - user and kernel CPU time consumed, account numbers, limits, etc.
I/O Status information - Devices allocated, open file tables, etc.
to get in details concept i should suggest you to learn from here
https://coderworld109.blogspot.in/2017/12/process-control-block-pcb.html
https://coderworld109.blogspot.in/2017/12/operating-system-process-management.html