I would like to measure the CPU and User time passed between starting a process and sending SIGINT signal using C times function.
However, on print I just get 0. Can't see the problem..
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/times.h>
#include <signal.h>
struct tms time_start;
struct tms time_end;
clock_t start;
clock_t end;
void handle() {
times(&time_end);
end = time_end.tms_stime;
}
int main(int argc, char *argv[]) {
signal(SIGINT, handle);
times(&time_start);
start = time_start.tms_utime;
pause();
printf("end: %ld, start: %ld\n", (long) end, (long) start);
return 0;
}
This is the output I get:
k#sc:dir$ ./my_time
^Cend: 0, start: 0
on print I just get 0. Can't see the problem..
The tms_stime is the CPU time spend in the kernel on behalf of the process. pause() is doing nothing, so it doesn't count for CPU time, signal and times are not computationally demanding functions - your program is doing nothing. Do some I/O operations, get that kernel to work to see some changes in times.
For example the following program reads 400000000 bytes from /dev/urandom:
#include <time.h>
#include <sys/times.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
struct tms time_end;
void handle() {
times(&time_end);
}
int main(int argc, char *argv[]) {
signal(SIGINT, handle);
// read from urandom so that kernel has to generate randomness
FILE *f = fopen("/dev/urandom", "r");
for (int i = 0; i < 20000000; ++i) {
char buf[20];
fread(buf, sizeof(buf), 1, f);
}
fclose(f);
pause();
printf("tms_stime = %ld\n", (long)time_end.tms_stime);
return 0;
}
Saved as 1.c file and executed on my system in shell outputs:
$ sh -c 'gcc 1.c ; ./a.out & child=$!; sleep 2; kill -INT $child ; wait'
tms_stime = 127
On linux there is also CLOCK_PROCESS_CPUTIME_ID you might be interested in.
Related
I am trying to accepts two integers (say low and high) as command line argument and in my main program is trying to call two other programs. program-1 should calculate the summation of all integers between (low, high) as sum_res and program-2 should evaluate whether sum_res is prime or not.
So I was trying to create two processes and I want to share a common variable between two processes but after execution I checked that only my main program is giving me segmentation fault.
I am new to this concept of execl please help:
My main program:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
int sum_res=0;
int main(int argc, char *argv[])
{
int low = atoi(argv[1]), high = atoi(argv[2]);
pid_t pid;
if((pid=vfork())==0)
{
execl("pro1","pro1", low, high, &sum_res, (char *)NULL);
exit(0);
}
else if(pid > 0)
{
wait(NULL);
execl("pro2","pro2", sum_res, (char *)NULL);
exit(0);
}
return 0;
}
My program-1 is: (Named prog1.c and compiled as gcc -g prog1.c -o prog1)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int n1 = atoi(argv[1]), n2 = atoi(argv[2]), i, sum_res = (int *)(argv[3]);
for(i=n1; i<=n2; i++)
{
(*sum_res)+=i;
}
printf("Sum is : %d\n", *sum_res);
return 0;
}
My program-2 is: (Named prog2.c and compiled as gcc -g prog2.c -o prog2 -lm)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int *main(int argc, char *argv[])
{
int sum_res = atoi(argv[1]), i, c=0;
for(i=2; i<=sqrt(sum_res); i++)
{
if(sum_res % i == 0)
{
c++;
break;
}
}
if(c==0)
{
printf("Prime \n");
}
else printf("Not Prime \n");
return 0;
}
Note: All 3 programs and their respective executables are present in the same current working directory.
If this is not possible then how will i get the summation result from program-1 into program-2 ?
It makes sense that you receive a segmentation fault. A pointer is a memory address inside a single process memory space. Each process memory space is completely independent and separated. This prevents one programs from accidentally breaking another program. When you try to read or write outside your process address space (the memory "segment" for your process) you receive a segmentation fault.
If you want to share memory space between two processes you need to use an IPC (Inter-process Communication) libraries to enable sharing memory space. One way is the shm_open function: https://www.geeksforgeeks.org/posix-shared-memory-api/
I made the following simple example to read memory from a child process using ptrace.
I want to see the value at a specific address, 0x601050, every second during the execution of a small matrix multiplication program. I use PTRACE_PEEKDATA followed by PTRACE_CONT and sleep for 1 second, in an infinite loop, to do so.
However, the matrix multiplication program never proceeds--it should print to stdout in the first instruction, but it never seems to execute. I understood that ptrace(PTRACE_CONT,pid) would signal the child to resume execution and that sleep(1) would allow it to execute for a second (until the next ptrace call), but that is not the case.
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/reg.h>
int read_mem(long *out, pid_t pid, long addr, size_t sz)
{
long tmp;
size_t copied = 0;
while(copied < sz)
{
tmp = ptrace(PTRACE_PEEKDATA, pid, addr+copied);
if(errno)
{
fprintf(stderr,"ptrace: error : %s\n",strerror(errno));
return copied;
}
memcpy(out,&tmp,sizeof(long));
copied += sizeof(long);
out++;
printf("ptrace: copied %d bytes\n",copied);
}
return copied;
}
int main()
{
pid_t child;
long result;
struct user_regs_struct regs;
int status;
long addr = 0x601050;
size_t sz = sizeof(double);
long *buf = (long*)malloc(sz);
child = fork();
if(child == 0)
{
ptrace(PTRACE_TRACEME);
execl("./matmul", "matmul", NULL);
}
else
{
ptrace(PTRACE_GETREGS, child, ®s);
printf("ptrace: regs.rip : 0x%lx\n", regs.rip);
while(1)
{
read_mem(buf, child, addr, sz);
printf("ptrace: read(0x%lx) : %f\n", addr, (double)(*buf));
ptrace(PTRACE_CONT, child);
sleep(1);
}
}
return 0;
}
You don't seem to set a PTRACE_O_TRACEEXEC option. Failing to do so results in SIGTRAP being sent to tracee upon a call to exec; if it is not prepared, the default action is a termination with a core dump.
All
I have a question about pthread_cond_wait().
In short, I create two POSIX thread in a process,
If I execute the following code, why is cpu utilization full?
I take experiments on it, if I remove comment mark before bool isNodeConnect3,
the program seems to be no probelm, CPU utilization is almost 0%, in other words,
theads will go to sleep and don't spend CPU resource, that's what I want.
Is it a data algnment probelm?
maybe, but I don't think so, because I bracket my struct by "#pragma pack(push,1) ... #pragma (pop)"
Could you give me suggestion??
Environment
Host OS is win7/intel 64 bit, guest OS is ubuntu 10.04LTS
Give "number of processor cores:4" to guest OS
The following is my test code, you can build and run it by
gcc -o program1 program1.c -pthread && ./program1
Get CPU utilization is 25%. Result depends on your setting.
Thanks a lot.
Code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <stdbool.h>
#pragma pack(push,1)
struct BUFF_TX{
pthread_mutex_t mutex_lock;
pthread_cond_t more;
};
struct AtreeNode{
struct BUFF_TX buff_tx;
bool isNodeConnect;
bool isNodeConnect1;
bool isNodeConnect2;
// bool isNodeConnect3; // important
pthread_t thrd_tx;
};
struct AtreeNode treeNode[2];
int tmp[2];
#pragma (pop)
void Thread_TX(int *nodeIdx)
{
int idx = *nodeIdx;
while(1)
{
printf("Thread %d enter mutex lock...\n", idx);
pthread_mutex_lock(&treeNode[idx].buff_tx.mutex_lock);
while(1)
{
if(idx==0)
{
printf("idx==0 wait...\n");
pthread_cond_wait(&(treeNode[0].buff_tx.more), &treeNode[idx].buff_tx.mutex_lock);
}
else if(idx==1)
{
printf("idx==1 wait...\n");
pthread_cond_wait(&(treeNode[1].buff_tx.more), &treeNode[idx].buff_tx.mutex_lock);
}
else
printf("err\n");
}
pthread_mutex_unlock(&treeNode[idx].buff_tx.mutex_lock);
printf("Thread %d leave mutex lock...\n", idx);
}
}
int main(int argc, char *argv[])
{
int i;
int ret;
tmp[0] = 0;
tmp[1] = 1;
for(i=0; i<2; i++)
{
if(pthread_cond_init(&treeNode[i].buff_tx.more, NULL) != 0)
{
printf("cond %d init fail.\n", i);
exit(EXIT_FAILURE);
}
if(pthread_mutex_init(&treeNode[i].buff_tx.mutex_lock, NULL) != 0)
{
printf("mutex lock %d init fail.\n", i);
exit(EXIT_FAILURE);
}
}
for(i=0; i<2; i++)
{
ret = pthread_create(&treeNode[i].thrd_tx, NULL, (void *)Thread_TX, (void *)(&tmp[i]));
if(ret)
{
printf("pthread_create thrd_tx %d err\n", i);
return false;
}
}
pthread_join(treeNode[0].thrd_tx, NULL);
pthread_join(treeNode[1].thrd_tx, NULL);
exit(EXIT_SUCCESS);
}
Remove #pragma pack(1) and forget you ever heard of it. Your problem is that you are passing an invalid pointer to pthread_cond_wait. pthread_cond_t has a particular alignment requirement and you are creating objects which are not necessarily aligned to that requirement, and thus their addresses are not valid to pass to pthread_cond_wait. See also https://sourceware.org/bugzilla/show_bug.cgi?id=16549 which was RESOLVED by being MOVED to a bug report against GCC for not catching the invalid pointer usage.
You should be able to confirm whether this is the actual cause of your issue by running your program under strace -f and seeing that the futex syscalls are failing with EINVAL or similar.
I'm attempting to write a C program in OSX that will change another program's execution flow, exactly like a debugger would. But before I put all of the "pieces" together, I need to test that each of them work individually first.
I've successfully used mach_vm_read_overwrite() and mach_vm_write() to read and write to the stack.
I've successfully used thread_get_state() and thread_set_state() to read and write to registers.
All that's left is to use thread_create_running() to create a thread in the task to execute my arbitrary function. However, whenever I create a thread, OSX completely crashes and automatically reboots my computer, lol. Can someone explain what is going on in more detail?
Here's my remote program, test.c:
#include <unistd.h>
#include <stdio.h>
void function1() {
printf("lol 1\n");
}
void function2() {
printf("lol 2\n");
}
void function3() {
printf("lol 3\n");
}
int main(int argc, char **argv) {
while(1) {
function1();
sleep(1);
function2();
sleep(1);
function3();
sleep(1);
}
return 0;
}
And here's my tiny debugger-in-progress:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdint.h>
#include <mach/mach_traps.h>
#include <mach/mach_init.h>
#include <mach/mach_error.h>
#include <mach/mach.h>
#include <mach/mach_types.h>
#include <mach/i386/thread_status.h>
void error(char *msg) {
printf("error: %s\n", msg);
exit(1);
}
int main(int argc, char **argv) {
pid_t pid;
mach_port_t eq_task;
kern_return_t err;
thread_act_port_array_t thread_list;
mach_msg_type_number_t thread_count;
x86_thread_state_t x86_state;
mach_msg_type_number_t sc = x86_THREAD_STATE_COUNT;
thread_act_t remoteThread;
// Make sure we have an argument
if (argc != 2)
error("requires a PID");
else
pid = (pid_t)atoi(argv[1]);
// Make sure we're root
if (getuid() && geteuid())
error("requires root");
// Get the task port
err = task_for_pid(mach_task_self(), pid, &eq_task);
if ((err != KERN_SUCCESS) || !MACH_PORT_VALID(eq_task))
error("getting eq task");
// Suspend the process
if(task_suspend(eq_task))
error("suspending the task");
// Get a list of threads from the port
if (task_threads(eq_task, &thread_list, &thread_count))
error("cannot get list of tasks");
// Get the registers
if (thread_get_state(thread_list[0], x86_THREAD_STATE, (thread_state_t)&x86_state, &sc))
error("getting state from thread");
// Create a new thread
err = thread_create_running(eq_task, x86_THREAD_STATE, (thread_state_t)&x86_state, x86_THREAD_STATE_COUNT, &remoteThread);
// BLACK SCREEN AND CRASH
// Resume the process again
if(task_resume(eq_task))
error("resuming the task");
}
I would assume that your trying to execute this in an XD bit, unless your running rocking an AMD instead of an intel. Then it would be NX opposed to XD. This would cause the application or even the entire computer to crash.
I've written a program which forks in a loop. The only thing children processes do is to increase a counter and exit, whereas a parent process waits for each of them.
My goal is to measure user and system time of parent process and all his children separately.
I've succeded with parent process using times() function and struct tms. Surprisingly, the same aproach to children processes isn't working. What is the mistake that I'm doing? How to measure those times?
I've also tried getrusage() and I/it failed.
My code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/times.h>
#include <time.h>
#ifndef COUNT
#define COUNT 100000
#endif
int counter;
int main(){
struct tms time1,time2;
times(&time1);
int count = COUNT;
pid_t pid;
while(count--){
if((pid=fork())<0){
printf("fork error\n");
} else if(pid==0){ /* child */
counter++;
_exit(0);
} else {
waitpid(pid,NULL,0); /*wait()*/
}
}
printf("COUNTER: %d\n",counter);
times(&time2);
long double clktck=sysconf(_SC_CLK_TCK);
double user=(time2.tms_utime-time1.tms_utime)/(double)clktck;
double system=(time2.tms_stime-time1.tms_stime)/(double)clktck;
double cuser=(time2.tms_cutime-time1.tms_cutime)/(double)clktck;
double csystem=(time2.tms_cstime-time1.tms_cstime)/(double)clktck;
printf("USER:%lf\nSYSTEM:%lf\n",user,system);
printf("CUSER:%lf\nCSYSTEM:%lf\n",cuser,csystem);
return 0;
}
I think the problem is that your children are executing too quickly; they don't take enough time to execute, so the sum of their time is plenty of zeros. To test this theory, I slightly changed your program:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/times.h>
#include <time.h>
#ifndef COUNT
#define COUNT 100
#endif
int counter;
int main(){
struct tms time1,time2;
times(&time1);
int count = COUNT;
pid_t pid;
while(count--){
if((pid=fork())<0){
printf("fork error\n");
} else if(pid==0){ /* child */
int i;
for (i=0; i<10000; i++) {
printf("in child %i\n", getpid());
}
exit(0);
} else {
waitpid(pid,NULL,0); /*wait()*/
}
}
printf("COUNTER: %d\n",counter);
times(&time2);
printf("%lu %lu %lu %lu\n", time2.tms_utime, time2.tms_stime, time2.tms_cutime, time2.tms_cstime);
long double clktck=sysconf(_SC_CLK_TCK);
double user=(time2.tms_utime-time1.tms_utime)/(double)clktck;
double system=(time2.tms_stime-time1.tms_stime)/(double)clktck;
double cuser=(time2.tms_cutime-time1.tms_cutime)/(double)clktck;
double csystem=(time2.tms_cstime-time1.tms_cstime)/(double)clktck;
printf("USER:%lf\nSYSTEM:%lf\n",user,system);
printf("CUSER:%lf\nCSYSTEM:%lf\n",cuser,csystem);
return 0;
}
You'll see that I drastically cut down on the number of children, and made the children do some real work; 10_000 printf(... getpid()) operations. Now the times amount to something:
$ time ./times
...
in child 16181
COUNTER: 0
1 0 24 95
USER:0.010000
SYSTEM:0.000000
CUSER:0.240000
CSYSTEM:0.950000
real 0m2.234s
user 0m0.250s
sys 0m0.950s
I'm afraid your children just didn't have enough work to do to amount to anything. (Odd, sounds like parenting advice.)
Each child is given their own address space. The code will not work because it will increment it's own local copy of counter and quit, leaving the version in the parent process/all other children untouched.
Also, you are very likely to get some errors with that many children.
Sorry I could only help with half the program :(.