My Blender (3.3.0) did not crash but I would not be surprised if it would because you're doing things that you should not do.
You join objects (=remove them) while you loop over them. It's like sawing off the branch you're sitting on.
Accessing data of invalid objects can crash Blender. Even when Blender does not crash the script will not work as you might expect:
obj is <bpy_struct, Object invalid>
Error: Python: Traceback (most recent call last):
File "untitled.blend\Text", line 12, in <module>
ReferenceError: StructRNA of type Object has been removed
How to fix it
Better save the object name in a Python list first. This list will not change when you join objects and remove them from the collection and blend file. This way you can check if the object still exists before you process it and access its data.
Script
Here is the script with the changes and a few prints so you can see in the System Console window what happens.
import bpy
collection = bpy.context.collection
print ("------- START -------")
# create a name list of all objects in the collection
object_names = [obj.name for obj in collection.all_objects]
for objname in object_names:
print(f"objname is {objname}, retrieving the obj")
obj = bpy.data.objects.get(objname)
if obj:
print(f"- found obj, it's {obj.name}")
if "export" in obj:
print (f"- export flag found in {obj.name} - going to join some objects ...")
parent_name = obj.name
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects[obj.name].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects[obj.name]
bpy.ops.object.select_grouped(type='CHILDREN_RECURSIVE')
group_children = bpy.context.selected_objects
bpy.context.view_layer.objects.active = bpy.data.objects[group_children[0].name]
bpy.ops.object.join()
print (f"- some objects have been joined and are now gone!")
else:
print(f"- {objname} not found! (it got joined and no longer exists)")
print ("------- END -------")
Example collection and objects

System Console output
------- START -------
objname is Big Cube, retrieving the obj
- found obj, it's Big Cube
objname is Empty (Group A), retrieving the obj
- found obj, it's Empty (Group A)
- export flag found in Empty (Group A) - going to join some objects ...
- some objects have been joined and are now gone!!
objname is Little Cube, retrieving the obj
- found obj, it's Little Cube
objname is Empty (Group B), retrieving the obj
- found obj, it's Empty (Group B)
- export flag found in Empty (Group B) - going to join some objects ...
- some objects have been joined and are now gone!!
objname is Sphere, retrieving the obj
- Sphere not found! (it got joined and no longer exists)
objname is Torus, retrieving the obj
- Torus not found! (it got joined and no longer exists)
------- END -------