#Maps halting the program only* when they are printed and when they contain pointers to other maps

1 messages · Page 1 of 1 (latest)

drowsy yarrow
#

Hello, maybe someone else has had this problem with maps halting the entire program, when are printed?

I have a map of unions, that have ptrs to more maps of the same type, however, this isn't a self-referential problem, I tested it & Odin simply stops printing after the first depth (I also have no way for maps to become self-referential)

The program only freezes when the top map has more maps. If it only has ints, strings or dynamic arrays, it used to print perfectly, now it gives a memory access violation, but the values inside are still perfectly accessible.

Also, when I try to deference the inner maps, I get a memory access violation, but the pointer (transmuted to ^int) is fine: 0x1358E799878
And also also accessing values inside of inner maps and printing them (unless they are a map) works perfectly.

I only create different kinds of maps in the same* function in different ways, which leads me to believe it's something with the initialization/types..?

I haven't been able to replicate it & make it into a manageable snippet and I'd rather not paste the whole file, so here are some, maybe related, snippets:

Table :: map[string]Type

Type :: union {
    ^Table,
    ^[dynamic]Type, 
    ... // other types aren't pointers
}
... // \/ initing top-most map   // This all happens in the same function:
tokens := make_map(Table)
top: ^Table = &tokens
section: ^Table = &tokens
... // \/ adding inner maps
top[nextnext] = new(Table)
section = top[nextnext].(^Table)
...
fmt.println(tokens["table"])
pastel cloud
#

If you aren't on windows you can use -sanitize:address and it might tell you about problems

#

You likely have a use after free, or are copying the map and adding/reading in multiple places (which makes the internal state go out of sync with the map you pass around)

drowsy yarrow
#

Welp, I'm on windows & tried the flag, didn't work :(
I also do not have a single free in my program, and wouldn't the println throw an access violation in that case???

And now it has gotten even more interesting:
the program works, if I consistently print the map, in the function's main for loop
(I also got rid of all the assignments of maps to not new(MyMapUnion))

pastel cloud
#

Yeah it doesn't work on windows at the moment

#

Use after free can also happen when you put something on the stack of a function, and store a pointer to it somewhere that is used after you leave the function

drowsy yarrow
#

Yep, I checked for that too, currently, if I remove this line, the program works again:
tokens[nextnext] = new_clone(make_map(Table))
I had it just as new(Table) previously & tried assigning to a dereference of that too...

drowsy yarrow
#

Alright, I've discovered some more magic:

Case 1:

logln("TOKENS:") // logln :: fmt.println (I tried using that too earlier)
logln(tokens)
if false && starts_with(nextnext, "{") {
    if key in section {     // type_of(section[key]) != ^Table 
        section[key] = new(Table)
        section = section[key].(^Table)
    }

    append_elem(&inline_table_path, key)
    to_skip += 2
    break
}
logln("TOKENS:")
logln(tokens)

Gives: ✅

TOKENS:
map[bigtest=&map[]]
TOKENS:
map[bigtest=&map[]]

:( - &map[e=test5""]

[Process exited 0]

Case 2:

// logln("TOKENS:")
// logln(tokens)
if false && starts_with(nextnext, "{") {
    if key in section {     // type_of(section[key]) != ^Table 
        section[key] = new(Table)
        section = section[key].(^Table) 
    }

    append_elem(&inline_table_path, key)
    to_skip += 2
    break
}
logln("TOKENS:")
logln(tokens)

Gives: ❌

TOKENS:

[Process exited -1073741571]

Case 3:

// logln("TOKENS:")
// logln(tokens)
// if false && starts_with(nextnext, "{") {
//     if key in section {     // type_of(section[key]) != ^Table 
//         section[key] = new(Table)
//         section = section[key].(^Table) // <--- bad line!
//     }
// 
//     append_elem(&inline_table_path, key)
//     to_skip += 2
//     break
// }
logln("TOKENS:")
logln(tokens)

Gives: ✅

TOKENS:
map[bigtest=&map[]]

:( - &map[e=test5""]

[Process exited 0]

This thing is (to my knowledge) single-threaded btw

terse viper
#

It's hard to say without more context. I suspect you're making an incorrect assumption somewhere. Could you share a repo? Or make a smaller version that would fit here that we could run.

drowsy yarrow
#

Oh yeah, I forgot to write it down here, but this seems to be a bug with fmt.print:
#bug-discussions message
Stack calls look like:

fmt_value - odin's guts.odin
fmt_named - ...
fmt_value
fmt_named
...

So, i guess, this thread can be considered solved ¯_(ツ)_/¯

atomic pivot
#

caused by the same issue i believe.
below will infinitely print out types causing a stack overflow.

Table :: map[string]^Table
fmt.println(typeid_of(Table))
Table :: map[string]Table
fmt.println(typeid_of(Table))
#

i'll put it here so its all in one place.

Table :: map[string]Table
tokens := make(Table)
fmt.println(tokens) // this print negates the hang.
tokens["table"] = make(Table)
fmt.println("Map:", tokens["table"])