smcameron / space-nerds-in-space

Multi-player spaceship bridge simulator game. Captain your starship through adventures with your friends. See https://smcameron.github.io/space-nerds-in-space
GNU General Public License v2.0
724 stars 73 forks source link

Bug in show_demon_3d() #336

Closed smcameron closed 9 months ago

smcameron commented 1 year ago

In snis_client.c, in show_demon_3d(), there is a static variable, "initialized_materials", initially set to zero. If it's zero, it initializes several materials. The idea is obviously to initialize the materials once, then assign a non-zero value to "initialized_materials" so that the materials are initialized just once.

However, initialized_materials is never set to 1, so the materials are initialized each time, which is not that big a deal, really, but it should not be necessary. The obvious fix would be to set initialized_materials to 1 once the materials are initialized. However, doing so causes the program to crash:

diff --git a/snis_client.c b/snis_client.c
index 9ffb59b3..9f5ce67e 100644
--- a/snis_client.c
+++ b/snis_client.c
@@ -19643,6 +19643,7 @@ static void show_demon_3d(void)
                faction_material[1] = &yellow_material;
                faction_material[2] = &orangered_material;
                faction_material[3] = &amber_material;
+               initialized_materials = 1;
        }

        /* If in captain mode or follow mode, then set desired camera position/orientation accordingly */
Thread 1 "snis_client" received signal SIGSEGV, Segmentation fault.
graph_dev_entity_render_order (e=0x7fefa7746c50) at graph_dev_opengl.c:2331
2331        switch (e->material_ptr->type) {
(gdb) bt
#0  graph_dev_entity_render_order (e=0x7fefa7746c50) at graph_dev_opengl.c:2331
#1  0x000055b9a4940837 in render_entities (cx=0x55b9a8286f80) at entity.c:1009
#2  0x000055b9a49bcbfb in show_demon_3d () at snis_client.c:19962
#3  0x000055b9a49bd78b in show_demon () at snis_client.c:20131
#4  0x000055b9a49c0a5e in main_da_expose (window=0x55b9a8bdffb0) at snis_client.c:21369
#5  0x000055b9a49cad57 in main (argc=4, argv=0x7ffc7c99db68) at snis_client.c:24297
(gdb) list
2326        int does_blending = 0;
2327    
2328        if (!e->material_ptr)
2329            return GRAPH_DEV_RENDER_NEAR_TO_FAR;
2330    
2331        switch (e->material_ptr->type) {
2332        case MATERIAL_NEBULA:
2333        case MATERIAL_TEXTURED_PARTICLE:
2334        case MATERIAL_TEXTURED_PLANET_RING:
2335        case MATERIAL_TEXTURED_SHIELD:
(gdb) print e->material_ptr
$1 = (struct material *) 0x2000000
(gdb) print *e
$2 = {m = 0x55b9aca8f1d0, low_poly = 0x55b9aca8f1d0, high_poly = 0x55b9aca8f1d0, visible = 1, x = -203584.641, 
  y = -90329.1875, z = 198257.797, cx = 0, cy = 0, cz = 0, sx = -1, sy = -1, scale = {v = {x = 60, y = 60, 
      z = 60}, vec = {60, 60, 60}}, dist3dsqrd = 9.4626526e+11, emit_intensity = 1, color = 8, shadecolor = 0, 
  alpha = 0, render_style = 0, user_data = 0x55b9a4d1ce70 <go+301936>, orientation = {q = {q0 = 0.0358908623, 
      q1 = 0, q2 = 0.120216079, q3 = -0.99209547}, v = {w = 0.0358908623, x = 0, y = 0.120216079, 
      z = -0.99209547}, vec = {0.0358908623, 0, 0.120216079, -0.99209547}}, material_ptr = 0x2000000, e_pos = {
    v = {x = -203584.641, y = -90329.1875, z = 198257.797}, vec = {-203584.641, -90329.1875, 198257.797}}, 
  e_scale = {v = {x = 60, y = 60, z = 60}, vec = {60, 60, 60}}, e_orientation = {q = {q0 = 0.0358908623, 
      q1 = 0, q2 = 0.120216079, q3 = -0.99209547}, v = {w = 0.0358908623, x = 0, y = 0.120216079, 
      z = -0.99209547}, vec = {0.0358908623, 0, 0.120216079, -0.99209547}}, parent = 0x0, 
  entity_child_index = -1, in_shade = 0, e_visible = 1, onscreen = 0 '\000'}
(gdb) print *(struct snis_entity *) 0x55b9a4d1ce70
$3 = {id = 339, type = 1, x = -203584.640625, y = -90329.1875, z = 198257.796875, vx = -257.50702098041074, 
  vy = -14.782645565079292, vz = -4.3745712703967001, heading = 3.1329412061154516, alive = 1, 
  respawn_time = 0, tsd = {ship = {torpedoes = 0, fuel = 0, velocity = 0, yaw_velocity = 0, 
      pitch_velocity = 0, roll_velocity = 0, desired_velocity = 0, sci_heading = 0, sci_beam_width = 0, 
      sci_yaw_velocity = 0, sciball_orientation = {q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, x = 0, 
          y = 0, z = 0}, vec = {0, 0, 0, 0}}, sciball_o = {{q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, 
            x = 0, y = 0, z = 0}, vec = {0, 0, 0, 0}}, {q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, 
            x = 0, y = 0, z = 0}, vec = {0, 0, 0, 0}}, {q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, 
            x = 0, y = 0, z = 0}, vec = {0, 0, 0, 0}}, {q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, 
            x = 0, y = 0, z = 0}, vec = {0, 0, 0, 0}}}, sciball_yawvel = 0, sciball_pitchvel = 0, 
      sciball_rollvel = 0, weap_orientation = {q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, x = 0, y = 0, 
          z = 0}, vec = {0, 0, 0, 0}}, weap_o = {{q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, x = 0, 
            y = 0, z = 0}, vec = {0, 0, 0, 0}}, {q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, x = 0, 
            y = 0, z = 0}, vec = {0, 0, 0, 0}}, {q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, x = 0, 
            y = 0, z = 0}, vec = {0, 0, 0, 0}}, {q = {q0 = 0, q1 = 0, q2 = 0, q3 = 0}, v = {w = 0, x = 0, 
            y = 0, z = 0}, vec = {0, 0, 0, 0}}}, weap_yawvel = 0, weap_pitchvel = 0, 
      torpedoes_loaded = 0 '\000', torpedoes_loading = 0 '\000', torpedo_load_time = 0, 
      phaser_bank_charge = 0 '\000', rpm = 0 '\000', throttle = 0 '\000', temp = 0 '\000', oxygen = 0, 
      shiptype = 18 '\022', scizoom = 0 '\000', weapzoom = 0 '\000', navzoom = 0 '\000', mainzoom = 0 '\000', 
      warpdrive = 0 '\000', missile_count = 0 '\000', phaser_wavelength = 0 '\000', phaser_charge = 0 '\000', 
      warp_core_status = 0 '\000', reverse = 0 '\000', trident = 0 '\000', ai = {{ai_mode = 0 '\000', u = {
[... more omitted ...]

So, somehow e->material_ptr is getting clobbered unless the (supposedly static, constant) materials in show_demon_3d() are initialized each time, which shouldn't be the case.

In any case, this thing appears to be an OBJTYPE_NPCSHIP (type == 1) and the shiptype (not that it matters) is SHIP_CLASS_DREADKNIGHT (shiptype == 18).

smcameron commented 9 months ago

Fixed by 7f9edb3057560329f31c9bc215718a1ccadff21b : Only initialize static materials once in show_demon_3d()