I'm running a sort of "sandbox" in C on Ubuntu: it takes a program, and runs it safely under the user nobody
(and intercepts signals, etc). Also, it assigns memory and time limits, and measures time and memory usage.
(In case you're curious, it's for a sort of "online judge" to mark programs on test data)
Currently I've adapted the safeexec module from mooshak. Though most things work properly, the memory usage seems to be a problem. (It's highly inaccurate)
Now I've tried the advice here and parsed VM from /proc/pid/stat
, and now the accuracy problem is fixed. However, for programs that finish really quickly it doesn't work and just gives back 0.
The safeexec program seems to work like this:
fork()
sexecv()
in the child process to run the desired programwait4
, which happens to return CPU usage - but not memory?)/proc/../stat
of the child process (which has been replaced by the execv)So why is VM in /proc/child_pid/stat
sometimes equal to 0?
Is it because the execv() finishes too quickly, and /proc/child_pid/stat
just isn't available?
If so, is there some sort of other way to get the memory usage of the child?
(Since this is meant to judge programs under a time limit, I can't afford something with a performance penalty like valgrind)
Thanks in advance.
You can check memory of a process or a set of processes in human readable format (in KB or kilobytes) with pmap command. All you need is the PID of the processes you want to check memory usage of. As you can see, the total memory used by the process 917 is 516104 KB or kilobytes.
A child process is a process created by a parent process in operating system using a fork() system call. A child process may also be called a subprocess or a subtask. A child process is created as its parent process's copy and inherits most of its attributes.
We simply pipe a readable stream into a writable stream. Since the main process stdin is a readable stream, we can pipe that into a child process stdin stream. For example: const { spawn } = require('child_process'); const child = spawn('wc'); process.
Can you arrange for the child process to use your own version of malloc()
et al and have that log the HWM memory usage (perhaps using a handler registered with atexit()
)? Perhaps you'd use LD_PRELOAD to load your memory management library. This won't help with huge static arrays or huge automatic arrays.
Hmm, sounds interesting. Any way to track the static/automatic arrays, though?
Static memory can be analyzed with the 'size' command - more or less.
Automatic arrays are a problem - I'm not sure how you could handle those. Your memory allocation code could look at how much stack is in use when it is called (look at the address of a local variable). But there's no guarantee that the memory will be allocated when the maximum amount of local array is in use, so it gives at best a crude measure.
One other thought: perhaps you could use debugger technology - the ptrace()
system call - to control the child process, and in particular, to hold it up for long enough to be able to collect the memory usage statistics from /proc/...
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With