Differences between revisions 1 and 2
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:

SEGV's are usually caused by

 1. Indexing out of the bounds of an array
 1. Using an uninitialized pointer

It is good practice, but often not followed, to NULL any pointer when the object it points to is freed. For this reason it is better to use one of the following rather than just call ''free''.

 1. ''freeAndNULL(&pointer)''
 1. ''free(pointer); pointer = NULL; ''
 1. ''{ type* pointer = <initialize the pointer> ...; ...; free(pointer); }''

'' ''We need but don't have such a function available,'' ''so we are writing this instead, which makes for tedious reading, or leaving dangerously dangling pointers available.

Parallel programming adds the further risk of multiple threads changing the array bounds, realloc'ing pointers, and other sharing problems.

The hardest problems to debug involve heap and other data structure corruptions that do not show up until a long time after the corruption happens, and which disappear or move between runs, when data structures are changed to add checking code, or when the code is run serially.

==== It is best to avoid such problems by having ====
A design that clearly decomposes the mesh into independent pieces. However the concepts of FACE and EDGE make this hard to do. Code executed in parallel should, where possible, partition the mesh into "mine, ours, yours" submeshes. "I" should not read "your" values, because you might be changing them. We can both read "ours", but if either of us are writing shared data, then either

 1. #pragma omp critical
 1. omp_set_lock et. al.

are needed. Fortunately omp reductions can often provide the locking implicitly.

==== When they occur ====
The first level of checking is to use Linux mcheck

Parent MorphoOptimizationProject

SEGV's are usually caused by

  1. Indexing out of the bounds of an array
  2. Using an uninitialized pointer

It is good practice, but often not followed, to NULL any pointer when the object it points to is freed. For this reason it is better to use one of the following rather than just call free.

  1. freeAndNULL(&pointer)

  2. free(pointer); pointer = NULL;

  3. { type* pointer = <initialize the pointer> ...; ...; free(pointer); }

We need but don't have such a function available, so we are writing this instead, which makes for tedious reading, or leaving dangerously dangling pointers available.

Parallel programming adds the further risk of multiple threads changing the array bounds, realloc'ing pointers, and other sharing problems.

The hardest problems to debug involve heap and other data structure corruptions that do not show up until a long time after the corruption happens, and which disappear or move between runs, when data structures are changed to add checking code, or when the code is run serially.

It is best to avoid such problems by having

A design that clearly decomposes the mesh into independent pieces. However the concepts of FACE and EDGE make this hard to do. Code executed in parallel should, where possible, partition the mesh into "mine, ours, yours" submeshes. "I" should not read "your" values, because you might be changing them. We can both read "ours", but if either of us are writing shared data, then either

  1. #pragma omp critical
  2. omp_set_lock et. al.

are needed. Fortunately omp reductions can often provide the locking implicitly.

When they occur

The first level of checking is to use Linux mcheck

MorphoOptimizationProject_DebuggingSegvs (last edited 2021-09-22 09:51:31 by DevaniCordero)