Abortar en lugar de segfault con clara violación de memoria

Me encontré con este comportamiento extraño cuando se trata de cadenas en C. Este es un ejercicio del libro de K&R donde se suponía que escribiera una función que agrega una cadena al final de otra. Esto obviamente requiere que la cadena de destino tenga suficiente memoria asignada para que la cadena de origen se ajuste. Aquí está el código:

 /* strcat: Copies contents of source at the end of dest */
 char *strcat(char *dest, const char* source) {
  char *d = dest;
  // Move to the end of dest
  while (*dest != '\0') {
    dest++;
  } // *dest is now '\0'

  while (*source != '\0') {
    *dest++ = *source++;
  }
  *dest = '\0';
  return d;
}

Durante las pruebas, escribí lo siguiente, esperando que ocurriera un error de seguridad mientras el programa se está ejecutando:

int main() {
  char s1[] = "hello";
  char s2[] = "eheheheheheh"; 
  printf("%s\n", strcat(s1, s2));
}

Por lo que entiendo s1 obtiene una matriz de 6chars asignado y s2 una matriz de 13chars. Pensé que cuandostrcat intenta escribir en s1 en índices superiores a 6 que el programa segfault. En su lugar, todo funciona bien, pero el programa no se cierra limpiamente, sino que funciona:

helloeheheheheheh
zsh: abort      ./a.out

y sale con el código 134, que creo que simplemente significa abortar.

¿Por qué no obtengo una falla de seguridad (o sobrescribo s2 si las cadenas están asignadas en la pila)? ¿Dónde están estas cadenas en la memoria (la pila o el montón)?

Gracias por tu ayuda.