#Unclear segmentation fault

1 messages · Page 1 of 1 (latest)

formal vigil
#

When I run my code, I get this error

Segmentation fault at address 0x1fac1670008
???:?:?: 0xee7c3fec3f in ??? (???)
C:\zig-windows-x86_64\lib\std\mem\Allocator.zig:313:26: 0xa283a4 in free__anon_4738 (mcexe.exe.obj)
    @memset(non_const_ptr[0..bytes_len], undefined);
                         ^
???:?:?: 0x1fac1670007 in ??? (???)
C:\zig-windows-x86_64\lib\std\hash_map.zig:403:13: 0xb4b197 in init (mcexe.exe.obj)
            return .{
            ^
F:\_Code\mcexe\src\interpreter.zig:453:20: 0xb071cf in summon (mcexe.exe.obj)
    std.debug.print("\n{s}\n", .{nbt}); //TMP
                   ^
???:?:?: 0x1fac1670007 in ??? (???)
???:?:?: 0x7 in ??? (???)

This happens only if I add code for a different function back to the project. Otherwise, the function that has the error runs fine.
What does this error mean exactly, I don't understand what causes this.

misty vigil
#

not sure. you'd have to show more code. but usually when i hear things like 'adding other code causes the issue' its due to a memory error, likely returning a pointer to a local from some fn. this article might give you some ideas if you're not familiar with the concept https://www.openmymind.net/Zig-Danling-Pointers/

formal vigil
#

The Thing is these two functions don't interact with each other. They also both return nothing, so there shouldn't be any dangling pointers.

quartz fjord
#

Your dangling pointer is elsewhere in the code. Calling any function with locals can alter memory in the stack that the dangling pointer is referring to.

formal vigil
#

The segfault is gone now but it still doesn't work and I think it has to do with this

#

I don't know why this happens

strange marsh
#

You need to provide code. Ideally a reproducible example. Failing that, access to the source and more detail then "it doesn't work". Does it crash? Is there a stack trace? What's it suposed to do?

formal vigil
# strange marsh You need to provide code. Ideally a reproducible example. Failing that, access t...

Sorry, I thought it was something obvious that I just don't get.
I try to give more info and code:

It does not crash or give segmentation faults anymore, now it only has problems with the hashmap. It seems it knows more than me. It should be a hash map with Entity Types but it tells me its values are InterpretedFuntions, which is weird as those two Types don't come near each other anywhere in my code.

This is the struct that holds the Hashmap:

const Status = struct {
    allocator: std.mem.Allocator,
    imports: ArrayList([]const u8),
    function_stack: ArrayList([]const u8),
    function_map: StringHashMap(InterpretedFunction),
    current_function: *InterpretedFunction,
    current_line: usize = 0,
    var_count: usize = 0,
    entity_map: StringHashMap(Entity),

    fn init(allocator: std.mem.Allocator) !Status {
        return Status {
            .allocator = allocator,
            .imports = ArrayList([]const u8).init(allocator),
            .function_stack = ArrayList([]const u8).init(allocator),
            .function_map = StringHashMap(InterpretedFunction).init(allocator),
            .current_function = undefined,
            .entity_map = StringHashMap(Entity).init(allocator),
        };
    }

    fn deinit(self: *Status) void {
        self.imports.deinit();
        self.function_stack.deinit();
        self.function_map.deinit();
        self.entity_map.deinit();
    }

  // Other code
  
  fn spawnEntity(self: *Status, entity: Entity) !void {
        if (self.entity_map.contains(entity.uuid)) return DatapackErrors.EntityAlreadyExists;
        std.debug.print("Spawning: {s}\n", .{entity.uuid}); //TEMP
        try self.entity_map.put(entity.uuid, entity);
    }
}

This is the Entity, which the Hashmap should use as values

pub const EntityType = enum {
    TextDisplay,

    fn idToEnum(id: []const u8) !EntityType {
        return if (std.mem.eql(u8, id, "text_display")) .TextDisplay
            else DatapackErrors.UnknownEntityType;
    }
};

pub const Entity = struct {
    allocator: std.mem.Allocator,
    entity_type: EntityType,
    uuid: []const u8,
    nbt: union(EntityType) {
        TextDisplay: struct {
            CustomName: []const u8,
            text: []const u8,
        }
    },

    pub fn init(allocator: std.mem.Allocator, entity: []const u8, nbt: []const u8) !Entity {
        const entity_type = try EntityType.idToEnum(entity);
        return Entity {
            .allocator = allocator,
            .entity_type = entity_type,
            .uuid = uuid_blk: {
                const uuid_str = getDataValue(nbt, "UUID:[I;", .array);
                break :uuid_blk try sanatizeUuid(allocator, uuid_str);
            },
            .nbt = switch (entity_type) {
                .TextDisplay => .{
                    .TextDisplay = .{
                        .CustomName = getDataValue(nbt, "CustomName:\"", .string),
                        .text = getDataValue(nbt, "text:\"", .string)
                    }
                }
            }
        };
    }

    pub fn deinit(self: *Entity) void {
        self.allocator.free(self.uuid);
    }
};

The InterpretedFunction struct:

const InterpretedFunction = struct {
    allocator: std.mem.Allocator,
    name: []const u8,
    returns: bool = false,
    top_vars: ArrayList([]const u8),
    code: ArrayList(u8),

    fn init(allocator: std.mem.Allocator, name: []const u8) InterpretedFunction {
        return InterpretedFunction {
            .allocator = allocator,
            .name = name,
            .top_vars = ArrayList([]const u8).init(allocator),
            .code = ArrayList(u8).init(allocator)
        };
    }

    fn deinit(self: *InterpretedFunction) void {
        self.allocator.free(self.name); // The memory for name was allocated by `file_collector.Function`
        self.top_vars.deinit();
        self.code.deinit();
    }

  // Other Code    

};

.

#

This function "spawns" the entity

fn spawnEntity(self: *Status, entity: Entity) !void {
    if (self.entity_map.contains(entity.uuid)) return DatapackErrors.EntityAlreadyExists;
    try self.entity_map.put(entity.uuid, entity);
}

and this is the one that "kills" it (deinit)

fn kill(context: []const u8) !void {
    var context_index: usize = 0;
    const selector_str = getNextArgument(context, &context_index, ' ').?;
    const selector = Selector.parse(selector_str);
    
    if (!std.mem.eql(u8, selector.selector_type, "@e")) return DatapackErrors.UnknownSelectorType;

    const uuid = try parse_helper.sanatizeUuid(status.allocator, getDataValue(selector.arguments.?.nbt, "UUID:[I;", .array));
    defer status.allocator.free(uuid);

    var entity = status.entity_map.get(uuid) orelse return; <= IT RETURNS HERE FOR WHATEVER REASON AS THERE SHOULD BE AN ENTIT IN THE MAP

    // Other Code
brave dragon
#

I’m not a Zig pro but it’s weird to me that getDataValue and sanitizeUUID seem to be returning slices instead of copying the UUID. This means it’s unclear where the UUID physically exists, since all the code you’ve shown uses pointers to it.

#

(If I were writing this, assuming your UUIDs are actually UUIDs, I would store them as a u128 and copy them where ever needed.)

formal vigil