Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Export program state to procfs?

Can I create any file mappings in procfs to reflect the internal state of my program?

For example,

main.c:

char *message;

...

Assume the pid is 1200, is it possible to create a transient file /proc/1200/variables/message, which will reflect the message variable?

I guess I need to work with the proc fs, as there are /proc/.../{net, fd, task, etc.}, where should I start if I want to add another variables/ section in the proc fs?

like image 445
Xiè Jìléi Avatar asked Nov 19 '11 08:11

Xiè Jìléi


3 Answers

There are no tools to do what you want to accomplish.

There are some things that are close -- gdb(1) knows how to introspect programs that are running and show values of some variables (not all variables survive compilation -- though the debug -g flag help gdb(1) discover what optimizations may have done to your program).

The FUSE project makes it possible for userspace programs to provide a filesystem to other processes via the kernel. You could either use FUSE directly to export selected variables from your program or you could try something significantly more ambitious and write tools to encapsulate gdb(1)s introspection abilities with FUSE's publishing abilities, and provide this service for the world.

You could also look into using 9p from within your programs -- it is similar in spirit to FUSE, allowing programs to provide interfaces to their functionality via filesystem interfaces. (You can see it in use in the wmii window manager, where a surprising amount of control of the window manager is possible via filesystem interfaces, allowing for easy programming using whatever language you like.) You could, again, integrate this with gdb(1)'s introspection abilities to try to provide this.

I would expect such a project to be worthy of a senior project or grad school project -- not something that would be accomplished quickly.

like image 116
sarnold Avatar answered Oct 20 '22 04:10

sarnold


Generally speaking you can't do it just from user-space. procfs is the kernel reporting its process state out to you. So if you WANT to do something like this you'd

a) have to create a kernel module that allows you to communicate content back to it b) trigger that content retrieval through a signal of some sort.

So, if you REALLY want to do this. I would suggest the following path:

1) Write a kernel module that can communicate program state. Let's call it kpsmod for our discussion.

2) Have it communicate with the userspace have it communicate with user process via some mechanism (say net link) to initiate some registration process, that registers the variable addresses. The userspace program tells the module that its interested in "exporting" itself out on a signal (say SIGHUP or SIGUSR1); make this programmable too. Pass on the name, the address and the sizes to be read (with type information if needed). If the variable is on the stack, it should be rejected. Only globally accessible symbols should be allowed for this (for simplicity)

3) You can even think about accessing the ptrace stack for the process at the time of proc_read of the particular variable.

4) then the kernel module should create a /proc/kpsmod//vars* for every variable and when the variable is read

5) on read dump the memory content via proc (potentially formatted)

and voila :-) you have your desired effect.

like image 3
Ahmed Masud Avatar answered Oct 20 '22 02:10

Ahmed Masud


Instead of using /proc, you can use a named pipe.

Create a fifo using mkfifo, and have your program open it for write. Either in a dedicated thread or asynchronously your program will generate text when someone run cat your-pipe in the shell. cat opens the named pipe for reading, of course.

This essentially mimics the cat /proc/.... interface, but instead of having a kernel module implement the text generation, you have a program implementing it.

like image 3
Dan Aloni Avatar answered Oct 20 '22 03:10

Dan Aloni