I have written some code in order to read another process memory. This is for macOS/GNU Mach.
#include <stdio.h>
#include <sys/types.h>
#include <mach/mach.h>
#include <mach/mach_vm.h>
int main() {
pid_t pid;
printf("PID: ");
scanf("%d", &pid);
vm_address_t address;
printf("Address: ");
scanf("%lx", &address);
vm_offset_t readMem;
vm_map_read_t task = task_for_pid(mach_task_self(), pid, &task);
mach_msg_type_number_t size = sizeof(int);
kern_return_t result = vm_read(task, address, (pointer_t)sizeof(int), &readMem, &size);
if (result) {
fprintf(stderr, "cant read, result 0x%x\n", result);
}
printf("%lu", readMem);
}
Upon running it and providing a valid PID, it returns MACH_SEND_INVALID_DEST.
Related
This is my code system call in C.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int n;
int i;
pid_t pid;
int time = 1000;
int sum = 0;
int main(void) {
printf("n: ");
scanf("%d", &n);
pid = fork();
if (pid < 0) {
printf("Fork Failed");
exit(-1);
} else if (pid == 0) {
//child
for (i = 1; i <= n; i++) {
sum += i;
}
printf("Sum of 1 to %d: %d\n", n, sum); // this is ok
} else {
// parent
wait(&time);
printf("Sum of 1 to %d: %d\n", n, sum); // this always return 0;
}
return 0;
}
I don't know why in parent's code block, the sum is always equal to 0.
How to make parent wait for child or am I doing something wrong ?
Waiting for the child works. However, your expectations are wrong.
Apparently you think that computations in the child process after the fork are visible in the parent process. They are not. The child is a new copy of the parent program at the time of fork. At that time, the parent's sum is 0 and stays that way.
There are several mechanisms to pass data from child to parent (the search term is interprocess communication, IPC).
exit() status
files
shared memory
pipes
signals
message queues
anything else I have missed
The issue here is the variable sum is not shared by the parent & child process, after fork() call the child will have its own copy of the variable sum.
Use shmget(),shmat() from POSIX api. Or use pthread which will share the same memory space for the newly created thread.
Update---
Added the shared memory to your code hopes this helps.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/shm.h>
int n;
int i;
pid_t pid;
int time = 1000;
int main(void) {
int shmid;
int *sum;
printf("n: ");
scanf("%d", &n);
/*request the shared memory from the OS using the shmget()*/
shmid = shmget(IPC_PRIVATE, sizeof(int), 0777|IPC_CREAT);
pid = fork();
if (pid < 0) {
printf("Fork Failed");
exit(-1);
} else if (pid == 0) {
//child
/* shmat() returns a char pointer which is typecast here
to int and the address is stored in the int pointer. */
sum = (int *) shmat(shmid, 0, 0);
for (i = 1; i <= n; i++) {
*sum += i;
}
printf("Sum of 1 to %d: %d\n", n, *sum); // this is ok
/* each process should "detach" itself from the
shared memory after it is used */
shmdt(sum);
} else {
// parent
wait(&time);
sum = (int *) shmat(shmid, 0, 0);
printf("Sum of 1 to %d: %d\n", n, *sum); // this always return 0;
shmdt(sum);
/*delete the cretaed shared memory*/
shmctl(shmid, IPC_RMID, 0);
}
return 0;
}
Refer for more info- https://man7.org/linux/man-pages/man2/shmget.2.html
As I am using the fork() function, I have my child process use the execlp() function. Because It doesn't work with a continuous while-loop. (I'm using a Linux environment)
So the child should be forked which is responsible for the exec() call, and the parent should be responsible for the loop and the input logic.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
int main(){
char *cmd[] = {"pwd", "ls", "date", "ps", "top"};
int i;
printf("0=pwd, 1=ls, 2=date, 3=ps, 4=top:\n");
printf("Please print your input: ");
scanf("%d", &i);
int The_fork = fork();
if(The_fork == 0){
execlp(cmd[i], cmd[i], NULL);
printf("command no found\n");
}else{
wait(0);
while(1){
int status;
waitpid(The_fork, &status, 0);
printf("\n");
char *cmd[] = {"pwd", "ls", "date", "ps", "top"};
int i;
printf("0=pwd, 1=ls, 2=date, 3=ps, 4=top:\n");
printf("Please print your input: ");
scanf("%d", &i);
//execlp(cmd[i], cmd[i], NULL);
}
return 1;
}
return 0;
}
Here is my output:
(The parent is printing continuously, but I can't figure out how to get the child to execute continuously after its first print.)
Thanks for everyone's comments I got it working.
Here's what I did.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
int main(){
while(1){
char *cmd[] = {"pwd", "ls", "date", "ps", "top"};
int i;
printf("0=pwd, 1=ls, 2=date, 3=ps, 4=top:\n");
printf("Please print your input: ");
scanf("%d", &i);
int The_fork = fork();
if(The_fork == 0){
execlp(cmd[i], cmd[i], NULL);
printf("command no found\n");
}else{
wait(0);
}
printf("\n");
}
return 0;
}
Running into strange error I'm totally failing to troubleshoot. I have a fork which loads an executable I know exists, but none of the code executes. It does not fail, which I know because I check exactly that, so I'm really baffled bu what's going on. Here is the code of the two processes:
Process 1(PipeC.c):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(){
int fd[2], B, C, D, numberRead, i, pipeReturn;
char *arg[3];
char charsRead [10000], fdNumberAsString[256];
pipeReturn = pipe(fd);
if(pipeReturn < 0){ printf("error creating pipe"); return;}
sprintf(fdNumberAsString, "%d", fd[0]);
arg[0] = fdNumberAsString;
//printf("%d\n", fdNumberAsString);
sprintf(fdNumberAsString, "%d", fd[1]);
//printf("%d\n", fdNumberAsString);
arg[1] = fdNumberAsString;
arg[2] = NULL;
printf("fd[0] = string: %s int: %d\n", arg[0], arg[0]);
printf("fd[1] = string: %s int: %d\n", arg[1], arg[1]);
//printf("fd[0] = %d, fd[1] = %d\n", fd[0], fd[1]);
B = fork();
if(B == 0){
execv("PipeW1", arg);
printf("Fork failed");
exit(1);
}
close(fd[1]);
numberRead = read(fd[0], charsRead, 5);
for(i = 0; i < 5; i++)printf("%c ", charsRead[numberRead]);
exit(0);
}
Process Two (PipeW1.c):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int x, char** args){
printf("here");
int fd[2], pipeReturn;
char num[256];
fd[0] = atoi(*args);
fd[1] = atoi(*(args+1));
printf("fd[0] = string: %s int: %d\n", fd[0], fd[0]);
printf("fd[1] = string: %s int: %d\n", fd[1], fd[1]);
close(fd[0]);
write(fd[1], "12345", 5);
exit(0);
}
The second process was even printing earlier... Very confused as I said, any ideas?
edit: output:
[myname#myschool Lab6]$ PipeC
PipeC - fd[0] = string: 4 int: -737006768
PipeC - fd[1] = string: 4 int: -737006768
here
[myname#myschool Lab6]$
I don't understand why scanf won't wait for input the second time in the loop. it only works in the first iteration. Also somewhat wait(&Status) won't print the correct Status.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
int x ;
int Status =-99;
char* cmds[5];
cmds[1] = "who";
cmds[2] = "ls";
cmds[3] = "date";
cmds[4] = "kldsfjflskdjf";
int i=10;
while (i--) {
printf("\nMenu:\n");
printf("1)who \n"); printf("2)ls \n");printf("3)date\n");
printf("choice :");
scanf("%d", &x);
int child = fork();
if (child != 0) {
execlp(cmds[x], cmds[x], NULL);
printf("\nERROR\n");
exit(99);
} else {
wait(&Status);
printf("Status : %d", Status);
}
}
}
Like the comment posted above says, there are two problems here:
You're running the command in the parent, rather than the child. See the fork manual.
wait does not give you the return code. It gives you an integer that you need to decode. See the wait manual.
Here's the corrected code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
int x ;
int Status =-99;
char* cmds[6];
cmds[1] = "who";
cmds[2] = "ls";
cmds[3] = "date";
cmds[4] = "kldsfjflskdjf";
int i=10;
while (i--) {
printf("\nMenu:\n");
printf("1)who \n"); printf("2)ls \n");printf("3)date\n");
printf("choice :");
scanf("%d", &x);
int child = fork();
if (child == 0) {
execlp(cmds[x], cmds[x], NULL);
printf("\nERROR\n");
exit(99);
} else {
wait(&Status);
printf("Status : %d", WEXITSTATUS(Status));
}
}
return 0;
}
I need to write a program that is creating a N amount of sub processes and every single one of them adds one to a shared memory variable. My idea is to use semaphores and shared memory, but the processes are not waiting for each other and the shared memory variable is also not working as I want it.
mydefs.h
#ifndef __MYDEFS__H__
#define __MYDEFS__H__
// Includes
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <memory.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/shm.h>
#endif // __MYDEFS__H__
main.c
#include "mydefs.h"
#define PROC_COUNT 3
#define INITAL_MARKER_VALUE 0
#define PID_LEN 32
char mypid[PID_LEN];
int main()
{
int i, shm_id;
sem_t mutex;
if(sem_init(&mutex,1,1) < 0)
{
perror("semaphore initilization");
exit(0);
}
shm_id = shmget(IPC_PRIVATE, 4*sizeof(int), IPC_CREAT | 0666);
if (shm_id < 0) {
printf("shmget error\n");
}
int *shmpointer = shmat(shm_id,0,0);
memset(mypid, 0, sizeof(mypid));
sprintf(mypid, "%06d", getpid());
for(i = 0; i < PROC_COUNT; i++)
{
if (fork() == 0)
{
while(sem_wait(&mutex)!=0);
execl("slaveproc", "slaveproc", mypid, (char *)0);
shmpointer += 1;
sem_post(&mutex);
perror("\n Can't exec slave program. Cause ");
exit(1);
}
}
sleep(1);
printf("%d\n", *shmpointer);
return 0;
}
slaveproc.c
#include "mydefs.h"
int marker; // Marker value
int main(int argc, char *argv[])
{
master_pid = atoi(argv[1]);
printf("\n --------------------------------------");
printf("\n I'm the slave proc!");
printf("\n My pid: %d", getpid());
printf("\n My master's pid: %d", master_pid);
printf("\n --------------------------------------");
for(;;) pause();
return 0;
}
The problem (or at least "a problem") is that mutex is not in shared memory: it's allocated on the stack. When you fork(), the new process will have a completely separate copy from the old process, so calling sem_wait(&mutex) on one process will not affect the other process's mutex at all.
You should put mutex in the shared memory:
int main()
{
int i, shm_id;
shm_id = shmget(IPC_PRIVATE, sizeof(sem_t) + 4*sizeof(int), IPC_CREAT | 0666);
if (shm_id < 0) {
printf("shmget error\n");
}
int *shmpointer = shmat(shm_id,0,0);
sem_t *mutex = shmpointer;
shmpointer = (void*)shmpointer + sizeof(sem_t);
if(sem_init(mutex,1,1) < 0)
{
perror("semaphore initilization");
exit(0);
}
memset(mypid, 0, sizeof(mypid));
sprintf(mypid, "%06d", getpid());
for(i = 0; i < PROC_COUNT; i++)
{
if (fork() == 0)
{
while(sem_wait(mutex)!=0);
execl("slaveproc", "slaveproc", mypid, (char *)0);
shmpointer += 1;
sem_post(mutex);
perror("\n Can't exec slave program. Cause ");
exit(1);
}
}
sleep(1);
printf("%d\n", *shmpointer);
return 0;
}
You're also never writing to the memory in shmpointer (perhaps you meant (*shmpointer) += 1?), but I'll let you figure that out on your own.