[SAOC 2024] - Fix Segmentation fault when compiling druntime Weekly update #3

Dennis dennis.onyeka.4 at gmail.com
Sun Oct 6 22:25:30 UTC 2024


## Fix Segmentation when Compiling druntime

### Task Accomplished
After moving the newScope function (which is a semantic import) 
from attrib.d to dsymbolsem.d, and turning it into a visitor. I 
encountered an error with the following description:
```make -C druntime
make[2]: Entering directory '/home/dencomac/DL/dmd/druntime'
../generated/linux/release/64/dmd -c -conf= -Isrc -Iimport -w -de 
-preview=dip1000 -preview=fieldwise -m64 -fPIC 
-preview=dtorfields -O -release -inline -version=Shared -fPIC 
-version=Shared -fPIC -I. -P=-I. src/core/stdc/errno.c 
-of../generated/linux/release/64/errno_c.o
make[2]: *** [Makefile:394: 
../generated/linux/release/64/errno_c.o] Segmentation fault
make[2]: Leaving directory '/home/dencomac/DL/dmd/druntime'
make[1]: *** [Makefile:89: druntime] Error 2
make[1]: Leaving directory '/home/dencomac/DL/dmd'
make: *** [posix.mak:8: all] Error 2
```
It became a challenge to me and to the reviewers.  It was a 
runtime error. Although the dmd compiler was built successfully, 
when druntime(core runtime library that provides essential 
low-level support for the D) was tested, it failed.
Druntime, in combination with the D standard library Phobos, 
provides a complete ecosystem for building D applications.

It was later found out that the DeprecatedDeclaration function 
was not properly type casted.
### What do I mean?
DeprecatedDeclaration inherits from StorageClassDeclaration. This 
allows the function to access properties or methods that are 
specific to StorageClassDeclaration.
**Error code:**
```
override void visit(DeprecatedDeclaration dpd) {
auto scx = (cast(StorageClassDeclaration)dpd).newScope(sc); // 
The enclosing scope is deprecated as well
  if (scx == sc)
  scx = sc.push();
scx.depdecl = dpd;
sc = scx;
}
```


The code above casts dpd (of type DeprecatedDeclaration) to 
StorageClassDeclaration and then tries to call newScope on it.  
The cast failed at runtime because dpd does not have a relation 
to StorageClassDeclaration. That resulted in a segfault.

**Modified code:**
```
override void visit(DeprecatedDeclaration dpd)
{
	auto oldsc = sc;
	visit((cast(StorageClassDeclaration)dpd));  // Delegates to the 
parent visit method
	auto scx = sc;
	sc = oldsc; // Restores the original scope

	// The enclosing scope is deprecated as well
	if (scx == sc)
     	scx = sc.push(); // Pushes a new scope if no changes have 
been made
	scx.depdecl = dpd;
	sc = scx;
}
```
sc is saved into oldsc before any changes are made. Thereafter, 
`visit((cast(StorageClassDeclaration)dpd))` calls the parent 
visit() method for `StorageClassDeclaration,` allowing for any 
scope adjustments associated with this type.
The updated scope is now stored in sc.
The main aim was to restore the scope where appropriate.

### Commit link
https://github.com/dlang/dmd/pull/16880)](
https://github.com/dlang/dmd/pull/16880)
[](https://github.com/dlang/dmd/pull/16880)


The error took most of my time and made me research a little on 
what segmentation error and type casting in D lang is, with the 
help of a youtube video from Mike shah[ **[Dlang Episode 47] D 
Language -  Casting with 
‘cast’**](https://www.youtube.com/watch?v=ZTK9FhAS-mM)

### Summary
In conclusion, segmentation fault occurs when a program tries to 
access memory that it is not authorized to access, or that does 
not exist. Some scenarios that can cause it is as follows: 
**Modifying a String Literal, Accessing an Address that is Freed, 
invalid cast OR Dereferencing Uninitialized.**

### Next on the task
Completely remove all other functions that depends on dsymbolsem 
in attrib.d and move to Cond.d refactoring although the previous 
PR has been merged but a lot a work needs to be done.



More information about the Digitalmars-d mailing list