Search code examples
cvalgrindpetsc

Why Valgrind reports an invalid write of size 8 on the assignment of a char* in PETSc?


I have a bad termination of my application in PETSc. I have checked what is going on with Valgrind, but I don't understand its report:

==97331== Invalid write of size 8
==97331==    at 0x10007FED5: PetscHeaderCreate_Private (inherit.c:40)
==97331==    by 0x1013EFE23: TSResilCreate (tsresil.c:525)
==97331==    by 0x10139A877: TSGetResil (ts.c:5252)
==97331==    by 0x10138D17E: TSSetFromOptions (ts.c:421)
==97331==    by 0x100011A47: SolveODE (in ./ex31)
==97331==    by 0x100012E98: main (in ./ex31)
==97331==  Address 0x102dde080 is 1,776 bytes inside a block of size 1,780 alloc'd
==97331==    at 0x100025EA1: malloc (vg_replace_malloc.c:303)
==97331==    by 0x10010E8C1: PetscMallocAlign (mal.c:34)
==97331==    by 0x10011063D: PetscTrMallocDefault (mtr.c:188)
==97331==    by 0x1013EFDA0: TSResilCreate (tsresil.c:525)
==97331==    by 0x10139A877: TSGetResil (ts.c:5252)
==97331==    by 0x10138D17E: TSSetFromOptions (ts.c:421)
==97331==    by 0x100011A47: SolveODE (in ./ex31)
==97331==    by 0x100012E98: main (in ./ex31)

In tsresil.c:525 (my implementation in PETSc):

ierr = PetscHeaderCreate(resil,TSRESIL_CLASSID,"TSResil","Time stepping resilience","TS",comm,TSResilDestroy,TSResilView);CHKERRQ(ierr);

In inherit.c:

 22: /*
 23:    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
 24:    in the default values.  Called by the macro PetscHeaderCreate().
 25: */
 26: PetscErrorCode  PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,const char class_name[],const char descr[],const char mansec[],
 27:                                           MPI_Comm comm,PetscObjectDestroyFunction destroy,PetscObjectViewFunction view)
 28: {
 29:   static PetscInt idcnt = 1;
 30:   PetscErrorCode  ierr;
 31: #if defined(PETSC_USE_LOG)
 32:   PetscObject     *newPetscObjects;
 33:   PetscInt         newPetscObjectsMaxCounts,i;
 34: #endif

 37:   h->classid               = classid;
 38:   h->type                  = 0;
 39:   h->class_name            = (char*)class_name;
 40:   h->description           = (char*)descr;
 41:   h->mansec                = (char*)mansec;

 ...

A PetscObject is a pointer to:

typedef struct _p_PetscObject {
  ...
  char                 *class_name;    /*  for example, "Vec" */
  char                 *description;
  ...

Consequently, it seems that the problem is related to the assignment of the char* descr, but I can't see why. Size 8 would inform that a pointer is wrong no?


Solution

  • It looks like Valgrind is complaining because you have only allocated 1780 bytes for the PetscObject, and this 8-byte write (starting at byte 1776) is enough to write into memory you didn't allocate.

    You'll need to either increase the size of the allocation, or increase the size of the structure, depending on the full definition and method of allocation.