Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
check_alloc_pairing Namespace Reference

Functions

 norm (expr)
 

Variables

 ALIGNED_ALLOC = re.compile(r'\b(dt_alloc_align\w*|dt_calloc_align\w*|dt_alloc_perthread\w*|dt_realloc_align\w*)\s*\‍(')
 
 PLAIN_ALLOC = re.compile(r'(?<![_\w])(malloc|calloc|realloc|strdup|strndup|g_malloc\d*|g_try_malloc\d*|g_realloc|g_new\d*|g_strdup\w*|g_slice_new\w*)\s*\‍(')
 
 ALIGNED_FREE = re.compile(r'\bdt_free_align(?:_ptr)?\s*\‍(\s*([^,;)]*)')
 
 PLAIN_FREE = re.compile(r'(?<![_\w])(free|g_free|dt_free|dt_free_gpointer)\s*\‍(\s*([^,;)]*)')
 
 ASSIGN = re.compile(r'([A-Za-z_][\w\.\->\[\]\s]*?)\s*=\s*(?:\‍([^)]*\‍)\s*)*$')
 
list files = []
 
list findings = []
 
 lines
 
 path
 
 encoding
 
 errors
 
 A = collections.defaultdict(list)
 
 AF = collections.defaultdict(list)
 
 code = re.sub(r'//.*$', '', ln)
 
 st = code.strip()
 
 m = rx.search(code)
 
 a = ASSIGN.search(code[:m.start()])
 
 k = norm(a.group(1))
 
str quiet = "--quiet" in sys.argv
 

Detailed Description

Allocator/deallocator pairing: dt_alloc_align* must be freed by dt_free_align, and
nothing else may be.

WHY THIS EXISTS, and why a build cannot replace it. dt_alloc_align() is _aligned_malloc()
on Windows and posix_memalign() everywhere else; dt_free_align() is _aligned_free() on
Windows and g_free() everywhere else. So on Linux and macOS BOTH families end at free(),
every mismatch works perfectly, and no test, sanitizer or review on those platforms will
ever see one. On Windows the same code corrupts the heap, and it crashes somewhere else
entirely, later, in whatever unlucky code touches the heap next.

That is a bug class you cannot find by running the program on the machine you develop on,
which is what makes it worth a static check. Both directions are reported:

  * something from malloc/calloc/g_malloc/g_new/strdup freed with dt_free_align()
  * something from dt_alloc_align()/dt_calloc_align() freed with free()/g_free()/dt_free()

Scope: matches allocations and frees of the SAME expression within the SAME file. That is
deliberately narrow -- matching by name across files reports `data`, `buffer` and `img` in
unrelated translation units and buries the real findings. It cannot see a struct field
allocated in one file and freed in another; the generic-destructor case that produced the
original bug report is prevented in the API instead (see dt_cache_seed in caches/cache.h),
which is the better fix where it is available.

Usage:  python3 tools/check_alloc_pairing.py [--quiet]
Exits non-zero if any mismatch is found.

Function Documentation

◆ norm()

check_alloc_pairing.norm (   expr)

Definition at line 36 of file check_alloc_pairing.py.

Variable Documentation

◆ A

check_alloc_pairing.A = collections.defaultdict(list)

Definition at line 56 of file check_alloc_pairing.py.

◆ a

check_alloc_pairing.a = ASSIGN.search(code[:m.start()])

Definition at line 65 of file check_alloc_pairing.py.

◆ AF

check_alloc_pairing.AF = collections.defaultdict(list)

Definition at line 57 of file check_alloc_pairing.py.

◆ ALIGNED_ALLOC

check_alloc_pairing.ALIGNED_ALLOC = re.compile(r'\b(dt_alloc_align\w*|dt_calloc_align\w*|dt_alloc_perthread\w*|dt_realloc_align\w*)\s*\‍(')

Definition at line 30 of file check_alloc_pairing.py.

◆ ALIGNED_FREE

check_alloc_pairing.ALIGNED_FREE = re.compile(r'\bdt_free_align(?:_ptr)?\s*\‍(\s*([^,;)]*)')

Definition at line 32 of file check_alloc_pairing.py.

◆ ASSIGN

check_alloc_pairing.ASSIGN = re.compile(r'([A-Za-z_][\w\.\->\[\]\s]*?)\s*=\s*(?:\‍([^)]*\‍)\s*)*$')

Definition at line 34 of file check_alloc_pairing.py.

◆ code

check_alloc_pairing.code = re.sub(r'//.*$', '', ln)

Definition at line 59 of file check_alloc_pairing.py.

◆ encoding

check_alloc_pairing.encoding

Definition at line 54 of file check_alloc_pairing.py.

◆ errors

check_alloc_pairing.errors

Definition at line 54 of file check_alloc_pairing.py.

◆ files

list check_alloc_pairing.files = []

Definition at line 45 of file check_alloc_pairing.py.

◆ findings

list check_alloc_pairing.findings = []

Definition at line 51 of file check_alloc_pairing.py.

◆ k

check_alloc_pairing.k = norm(a.group(1))

Definition at line 67 of file check_alloc_pairing.py.

◆ lines

check_alloc_pairing.lines

Definition at line 54 of file check_alloc_pairing.py.

◆ m

check_alloc_pairing.m = rx.search(code)

Definition at line 63 of file check_alloc_pairing.py.

◆ path

check_alloc_pairing.path

Definition at line 54 of file check_alloc_pairing.py.

◆ PLAIN_ALLOC

check_alloc_pairing.PLAIN_ALLOC = re.compile(r'(?<![_\w])(malloc|calloc|realloc|strdup|strndup|g_malloc\d*|g_try_malloc\d*|g_realloc|g_new\d*|g_strdup\w*|g_slice_new\w*)\s*\‍(')

Definition at line 31 of file check_alloc_pairing.py.

◆ PLAIN_FREE

check_alloc_pairing.PLAIN_FREE = re.compile(r'(?<![_\w])(free|g_free|dt_free|dt_free_gpointer)\s*\‍(\s*([^,;)]*)')

Definition at line 33 of file check_alloc_pairing.py.

◆ quiet

str check_alloc_pairing.quiet = "--quiet" in sys.argv

Definition at line 82 of file check_alloc_pairing.py.

◆ st

check_alloc_pairing.st = code.strip()

Definition at line 60 of file check_alloc_pairing.py.