get _complete_ process name from pid - linux

I am in a kernel module and I want to have the whole process name
from a given pid. exactly: I want the line which is hold in /proc/PID/cmdline.
The problem is that task_struct->comm[] is only 15 bytes long and doesn't handle
if a program changes his argv[] manually or via setproctitle(3)...
Any ideas? :)

You could always look at how the kernel does it. You'll see the function:
proc_pid_cmdline(struct task_struct *task, char * buffer)
It's fairly easy to follow but once you have the task_struct for the process you are interested in you use access_process_vm() to slurp the bits you want from mm->arg_start.

What's wrong with opening the /proc/<pid>/cmdline file and just reading the contents?

Related

Full form of ttwu in the scheduling code of the linux kernel

I know this is kind of silly, but I tried to find out online, but couldnt.
What is the full-form of ttwu in the scheduler code of the linux kernel. It can be seen as a number of function prefixes, namely,
ttwu_do_wakeup
ttwu_do_activate
ttwu_queue_remote
ttwu_activate
.. and many more
I would assume it stands for try_to_wake_up. See for example the comment in kernel/sched/sched.h:
981 /* try_to_wake_up() stats */
982 unsigned int ttwu_count;
983 unsigned int ttwu_local;
yes in true *nix philosophy why waste time on extra characters (e.g. you want to know the current working directory? Use pwd for "print working directory") TTWU is indeed "Try To Wake Up" and implemented in the Linux scheduler code, eventually calling activate_task, which actually DOES NOT DO ANYTHING but put the task on the run queue of one of the CPUs. At some point in the future the _schedule function will make it activate (via switch_context.) Pretty cool stuff if you ask me.

How to find the current location of the program break

I tried adding this inside the brk system call function :
void *addr = sbrk(0);
printk("current-add-is-%p-\n", addr);
But it returned error during kernel compilation that implicit declaration of sbrk function. And I could not find where sbrk is defined!!
All I need to measure that whenever some user process tries to extended its program break address, I would know its current program break address, so that I can measure how much memory processes are requesting.
Thank you.
Looks like you are trying to do something wrong.
There is no 'sbrk' syscall, there is 'brk'. Except then it would be named sys_brk, but you have no reasons to call it. So if you want to find out how to learn the current break address, read brk's sources.
However, where exactly did you put this in if you did not happen to find brk's sources?
Add this line of code:
printf("Address of program break is %p\n", (void *)sbrk(0));
It will return a message to terminal with hex address of the program break.(e.g., 0x#### #### ####.)
If you want the address in other than hex, then use %u or similar. The use of sbrk(0) is documented in man pages (linux programmers manual).
To see documentation, type in command line: man sbrk and documentation will pop up.

(open + write) vs. (fopen + fwrite) to kernel /proc/

I have a very strange bug. If I do:
int fd = open("/proc/...", O_WRONLY);
write(fd, argv[1], strlen(argv[1]));
close(fd);
everything is working including for a very long string which length > 1024.
If I do:
FILE *fd = fopen("/proc/...", "wb");
fwrite(argv[1], 1, strlen(argv[1]), fd);
fclose(fd);
the string is cut around 1024 characters.
I'm running an ARM embedded device with a 3.4 kernel. I have debugged in the kernel and I see that the string is already cut when I reach the very early function vfs_write (I spotted this function with a WARN_ON instruction to get the stack).
The problem is the same with fputs vs. puts.
I can use fwrite for a very long string (>1024) if I write to a standard rootfs file. So the problem is really linked how the kernel handles /proc.
Any idea what's going on?
Probably the problem is with buffers.
The issue is that special files, such as those at /proc are, well..., special, they are not always simple stream of bytes, and have to be written to (or read from) with specific sizes and or offsets. You do not say what file you are writing to, so it is impossible to be sure.
Then, the call to fwrite() assumes that the output fd is a simple stream of bytes, so it does smart fancy things, such as buffering and splicing and copying the given data. In a regular file it will just work, but in a special file, funny things may happen.
Just to be sure, try to run strace with both versions of your program and compare the outputs. If you wish, post them for additional comments.

what happen when parent process and child process read the same file and write to the other same file?

#include <fcntl.h>
#include <stdlib.h>
int fdrd,fdwt;
char c;
void rdwrt();
main(int argc,char *argv[])
{
if(argc!=3)
exit(1);
if((fdrd=open(argv[1],O_RDONLY))==-1)
exit(1);
if((fdwt=creat(argv[2],0666))==01)
exit(1);
fork();
rdwrt();
exit(0);
}
void rdwrt()
{
for(;;)
{
if(read(fdrd,&c,1)!=1)
return;
write(fdwt,&c,1);
}
}
This program forks a child process,then parent process and child process try to read the same input file and write to the same output file.
Excute this program like this:
[root#localhost]./a.out input output
where content of input file is:
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
I thought the output file should have equal number of characters to the input file,though the character order probably not the same according to the competition of these two processes.
It turns out that the output file is:
abcdefghijklmnonqbcdefghijklwxyczdefjklpqrstuvwxyz
abcefgklmvwxefgklmnopqrstuvw
qrstuyz
abcdhijxyz
Actually,these tow files have different characters number:
[root#localhost]wc -m input output
162 input
98 output
Now I wonder why?
The contents of the output file will be difficult to predict because your program contains a race condition. Specifically, it depends on process scheduling.
Requested update:
This question is actually more interesting than it looked at first glance.
I'm going to make some predictions (tested successfully...)
On Unix-like systems1 ... then, yes, the number of characters will always be the same but the order will be difficult to predict.
You tagged your question linux unix, and in those systems, all of which1 properly implement the fork model, both children will share a single file position for both (forked) instances of fdrd, and they will share a second file position for both instances of fdwr.
If you could slow down time and watch the program run, at any point there are things you know and things you don't.
You don't know which child will win the race to do the next read, but you do know which character the winner will read, because they are always at the same file position. After the winner gets that next character, you still don't know who will read the following one, because the race is still on.
In fact, it is possible that the same process will win the race again, and again, because the scheduler probably won't want to run it for a very small time slice.
At any moment you also know that the next character will be written at EOF because, again, shared write position.
Now, you might ask, well then, if both processes are always at both the same input and output file positions, how does the file get cracked up?
Well, there is more than one race, one to the read and a second to the write. (Or one, kinda complicated race.) One child may have read its character but not written it when it gets time-sliced. So now it starts losing the race to the write statement and then probably to several iterations of read/write. So a character can get hung up in one child.
And finally, on merely-API-compatible C environments running over other operating systems, anything could happen. The OP's system appears to be one of these, or perhaps the test was flawed. My OSX system behaves as predicted.
1. "Real" UNIX, *BSD, OSX, or Linux.

How to tell which file was created first?

On a Linux system (the one in front of me is an Ubuntu 10.04, but that shouldn't matter), how can I tell which of two files created within the same second was created first? The process I control creates neither itself; in all other respects the ctime would, I think, do the trick, but the 1 second resolution is a problem.
For background, I'm trying to reliably determine whether a potentially stale pidfile refers to the current process with that pid. If there's a better way to do that, I'm all ears.
Actually, on modern Unices with modern filesystems, the file modification time is stored in a timespec. Details:
The standard says stat looks like this WRT times:
struct timespec st_atim Last data access timestamp.
struct timespec st_mtim Last data modification timestamp.
struct timespec st_ctim Last file status change timestamp.
And a timespec
time_t tv_sec seconds
long tv_nsec nanoseconds
So, doing a stat on my Linux 2.6.39:
Access: 2011-07-14 15:38:20.016666721 +0300
Modify: 2011-06-10 03:06:12.000000000 +0300
Change: 2011-06-17 11:01:35.416667110 +0300
In conclusion, I think you've got enough precision there if the hardware is supplying it.
You can try ls -rt to sort the files by time on the hope that the file header has more precision than the default list time format displays. But if the file system doesn't have the information, there is no way to do this.
Other options? You could add an ID to the file and always increment it but as soon as you try to load this ID from the file system (when you create a new process), you'll run into problems with locking.
So how can you make sure the PID file is not stale? Answer: Use the daemon script. It runs a process in the background and makes sure the PID file gets deleted as soon as the process exits.

Resources