I am getting confusing output from valgrind when running the memory checker
on my pthread code.  Specifically, it seems to not like the use of
the pthread_attr_setstack() function.  I have reduced my problem to a small
example, pasted at the end of this message.  What I'm trying to do is:
1. Allocate a 64KB buffer for use as the thread stack
2. Call pthread_attr_setstack() to set the stack attributes
3. Call pthread_create(), let the thread run to completion, and then
pthread_join()
4. Clear out the threads stack via memset() to ensure I don't leave any
interesting data in the heap.
5. free() the thread stack

This all seems to work fine, but valgrind complains that the memset() in
step 4 is an invalid write.  An example of this error is here:
==26698== Invalid write of size 8
==26698==    at 0x4C3665A: memset (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26698==    by 0x108A4E: main (in /home/cteague/develop/hello/pthread_test)
==26698==  Address 0x545ae88 is 59,912 bytes inside a block of size 65,536
alloc'd
==26698==    at 0x4C2FB0F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26698==    by 0x1089B6: main (in /home/cteague/develop/hello/pthread_test)

I am very confused.  How can it be an invalid write inside my own block of
allocated memory? It looks to me like a problem with valgrind - but my
experience has been that valgrind is incorrect far less frequently than I
am!  My command line is this:
valgrind --leak-check=full ./pthread_test

And my test code is here below.  I would really appreciate any insight into
this problem.  A few notes:
- I thought the problem was the "stack guard" in pthread, but
using pthread_attr_setguardsize() to set it to 0 did not help.
- Yes, I do need to use pthread_attr_setstack().  I am on an embedded
platform where I need to specify from which memory the stack will live in.
- I have reproduced this on valgrind 3.10 and 3.13

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

static void* thread_start(void *arg)
{
  printf("thread running\n");
  return NULL;
}

int main(int argc, char **argv)
{
  pthread_t thd;
  pthread_attr_t thd_attr;
  size_t stack_size = 64*1024;
  void* p_stack;

  printf("start\n");

  p_stack = malloc(stack_size);
  if (NULL != p_stack) {
    if (0 == pthread_attr_init(&thd_attr)) {
      if (0 == pthread_attr_setstack(&thd_attr, p_stack, stack_size)) {
if (0 == pthread_create(&thd, &thd_attr, thread_start, NULL)) {
  printf("thread created\n");
  pthread_join(thd, NULL);
}
      }
      pthread_attr_destroy(&thd_attr);
    }
    memset(p_stack, 'A', stack_size);
    free(p_stack);
  }

  printf("done\n");
  return 0;
}
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to