views:

57

answers:

2

Hi,

I want to use clone to log the current status of my program. It has a lot of loops and I want to keep track of the process without printing the status in each loop iteration.

That's why I created this proof-of-concept:

#include <iostream>
#include <cstdlib>

unsigned int i;

int log(void*) {
  std::cout << "LOGGING START" << std::endl;
  while(true) {
    sleep(1);
    std::cout << i << std::endl;
  }
}

int main()  {
  void **child_stack = (void**)malloc(16384);
  i = 0;

  std::clog << "calling clone" << std::endl;
  clone(log, child_stack, CLONE_VM | CLONE_FILES, NULL);
  std::clog << "done" << std::endl;

  while(true) {
    ++i;
  }

  return 0;
}

When I run it without gdb it crashes with a segmentation fault at clone() but it works fine if I use gdb. Why?

Do you think this is a good practice or will I run into troubles sooner or later? And is there a better method to achieve this?

Cheers,

Manuel

+1  A: 

The stack argument to clone is a simple void*. Also, the stack grows down on most architectures, so the stack pointer should point to the end of the allocated memory.

In any case, you shouldn't use clone directly unless you really need to avoid any dependencies on external libraries. Use the pthreads library instead. It provides a much easier (and safer) API.

Frerich Raabe
pthreads is also more portable; `clone` is Linux specific.
Mike Seymour
Ok, but then I would have to create a mutex and lock it at the beginning of the for loop iteration and unlock it at the end?If so, this I think this would hurt the performance.
Manuel
I tried to use this, but the performace really breaks down strongly.Is there any other solution?
Manuel
@Manuel: In general, you would need to synchronize (e.g. using a mutex) with your current `clone`-based solution as well because the code is buggy as it is. In this particular example, you don't really need locking since you're just dumping an `int`. Your monitoring thread is sleeping every iteration, so you can actually miss some integers (the code doesn't necessarily print 1, 2, 3, 4 - it could print 1, 3, 4 as well).
Frerich Raabe
I know. And it should not print 1, 2, 3...I just want to keep track if there is process.The actual question is: if I read and write in one thread, is it safe to _only_ read in another thread?
Manuel
A: 

On intel processors, the child_stack argument should point to the top of the stack, not to the bottom.

Anyway, I think using clone is not a good idea. There are about three ways of calling clone, depending on architercture, all poorly documented. I'd suggest using the pthreads library (or, since we are in C++, Boost.Threads).

jpalecek