Is it possible to determine in Linux as a parent process how much time a child process sleeps, whenever it sleeps using the nanosleep() system call?
Thanks!
You can wrap glibc:
% gcc -fPIC -shared -o nanosleep.so nanosleep.c -ldl
% export LD_PRELOAD=/path/to/your/nanosleep.so /path/to/app/using/test
Wrapper code nanosleep.c:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int (*real_nanosleep)(const struct timespec *req, struct timespec *rem) = NULL;
/* wrapping nanosleep function call */
int nanosleep(const struct timespec *req, struct timespec *rem)
{
printf("How much %d used\n", req->tv_nsec);
/* Fetch the real nanosleep function from glibc */
real_nanosleep = dlsym(RTLD_NEXT, "nanosleep");
return real_nanosleep(req, rem);
}
Test program test.c:
#include <stdio.h>
#include <time.h>
int main () {
struct timespec req = {0}, rem = {0};
req.tv_sec = 2;
req.tv_nsec = 1000000000;
nanosleep(&req, &rem);
return(0);
}
Related
I need to write a module that creates a file and outputs an inscription with a certain frequency. I implemented it. But when this module is running, at some point the system crashes and no longer turns on.
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/timer.h>
MODULE_LICENSE("GPL");
#define BUF_LEN 255
#define TEXT "Hello from kernel mod\n"
int g_timer_interval = 10000;
static struct file *i_fp;
struct timer_list g_timer;
loff_t offset = 0;
char buff[BUF_LEN + 1] = TEXT;
void timer_rest(struct timer_list *timer)
{
mod_timer(&g_timer, jiffies + msecs_to_jiffies(g_timer_interval));
i_fp = filp_open("/home/hajol/Test.txt", O_RDWR | O_CREAT, 0644);
kernel_write(i_fp, buff, strlen(buff), &offset);
filp_close(i_fp, NULL);
}
static int __init kernel_init(void)
{
timer_setup(&g_timer, timer_rest, 0);
mod_timer(&g_timer, jiffies + msecs_to_jiffies(g_timer_interval));
return 0;
}
static void __exit kernel_exit(void)
{
pr_info("Ending");
del_timer(&g_timer);
}
module_init(kernel_init);
module_exit(kernel_exit);
When the system crashes, you should get a very detailed error message from the kernel, letting you know where and why this happened (the "oops" message):
Read that error message
Read it again
Understand what it means (this often requires starting over from step 1 a couple of times :-) )
One thing that jumps out at me is that you're not going any error checking on the return value of filp_open. So you could very well be feeding a NULL pointer (or error pointer) into kernel_write.
my vm system is ubuntu 16.04, and i have download the kernel header files,i have write the code,but don't know how to edit gcc code or Makefile
#include <linux/netdevice.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(){
struct net_device *dev = dev_base;
struct in_device *mydevice;
struct in_ifaddr *myifaddr;
while( dev != NULL ){
printf("dev name: %s\n", dev->name);
mydevice = dev->ip_ptr;
myifaddr = mydevice->ifa_list;
while(myifaddr != NULL){
printf("ip: %s\n", inet_ntoa((struct in_addr)(myifaddr->ifa_local)));
myifaddr = myifaddr->ifa_next;
}
dev = dev->next;
}
return 0;
}
if i use gcc test.c it will come out some error like this
yq#ubuntu:~/test$ gcc test.c
In file included from /usr/include/linux/netdevice.h:28:0,
from test.c:1:
/usr/include/linux/if.h:234:19: error: field ‘ifru_addr’ has incomplete type
struct sockaddr ifru_addr;
^
......
test.c: In function ‘main’:
test.c:8:27: error: ‘dev_base’ undeclared (first use in this function)
struct net_device *dev = dev_base;
I was reading about ptrace on the net and found that a process can request to trace another process by using PTRACE_ATTACH but apparently all the examples available involve the use of fork().
What I want is to have 2 programs - prg1.c and prg2.c where prg2.c should trace prg1.c. I tried using PTRACE_ATTACH in prg2.c but it seems that the call failed - prg2.c couldn't trace prg1.c . How does ptrace work ? Can anybody explain ?
Code for prg1.c :
#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("Hello world\n");
sleep(20);
execl("/bin/ls", "ls", NULL);
return 0;
}
Code for prg2.c :
#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc , char **argv)
{
int pid = atoi(argv[1]);
int status;
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
printf("ptrace attach failed!");
return 0;
}
wait(&status);
sleep(5);
ptrace(PTRACE_DETACH, pid, NULL, NULL);
return 0;
}
I have included a sleep() to get the pid of prg1's executable(during that time) using ps -af and give it as an input to the executable of prg2.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
int main()
{
int server_sockfd,client_sockfd;
int server_len,client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
create a new socket
unlink("server_socket");
server_sockfd=socket(AF_INET,SOCK_STREAM,0);
name it
server_address.sin_family=AF_INET;
server_address.sin_addr.s_addr=htonl(INADDR_ANY);
server_address.sin_port=htons(9734);
server_len=sizeof(server_address);
bind(server_sockfd,(struct sockaddr *)&server_address,server_len);
set block
int flags=fcntl(server_sockfd,F_GETFL,0);
if(flags&O_NONBLOCK==1){
printf("NONBLOCK");
}else{
printf("BLOCK");
}
flags=flags&~O_NONBLOCK;
fcntl(server_sockfd,F_SETFL,flags);
if(flags&O_NONBLOCK==1){
printf("NONBLOCK");
}else{
printf("BLOCK");
}
listen
listen(server_sockfd,5);
while(1){
char ch;
printf("server waiting\n");
client_len=sizeof(client_address);
client_sockfd=
accept(server_sockfd,(struct sockaddr*)&client_sockfd,&client_len);
it is blocked at first time
read(client_sockfd,&ch,1);
ch++;
write(client_sockfd,&ch,1);
close(client_sockfd);
}
}
when the client connected first,I work,but the next won't work
A mismatch may occurs between client_address and client_sockfd.
The man page of accept() says:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
The addrlen argument is a value-result argument: the caller must initialize it to
contain the size (in bytes) of the structure pointed to by addr; on return it
will contain the actual size of the peer address.
Try:
client_sockfd=
accept( server_sockfd, (struct sockaddr*)&client_address, &client_len );
#include <pthread.h>
#ifndef __linux__
#include <windows.h>// to include the windows.h library//
#endif
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
#include <sys/timeb.h>
void *PrintHello(void *threadid)
{
srand(time(NULL));
long tid,a;
tid = (long)threadid;
a=rand()%5;
printf("Hello World! It's me, thread #%ld!%ld\n", tid,a);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t,a;
srand(time(NULL));
for(t=0; t<NUM_THREADS; t++){
a=rand()%5;
printf("In main: creating thread %ld,%ld\n", t,a);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
Alright I have this simple code and when I compile it inside the main() the random numbers
are different from one another but when i try to generate random numbers inside the threads, all the numbers that are produced are the same.
Try seeding from outside the threads. The problem is that you get the same seed for each thread