An `any` holding a named type, such as `main::Point`, showed only the
name of its type in lldb. `FindTypes` reads `main::Point` as `Point`
in a namespace `main`, but Odin's DWARF names the type `main::Point`
with no namespace, so the lookup found nothing. When `FindTypes` finds
nothing, look the name up in an index of each module's types, made
once per module.
Apple's lldb includes Swift, and `SBTarget.GetBasicType` may answer
from Swift's type system, such as `Swift.Int64` for `long long`. A
value made from such a type is empty, so in about half of all lldb
sessions an `any` holding a basic type, or a pointer or an array of
one, showed only the name of its type. Ask the `any`'s own type for
basic types instead, as it comes from the type system of Odin's
debug info.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Map keys of type `string16` used `default_hasher_string`, which reads
the length as a byte count; for a `string16` it counts u16 units, so
only the first half of the key was hashed. `cstring16` keys took the
same path and were read as a pointer and a length, which crashes.
Add `default_hasher_string16` and `default_hasher_cstring16` to the
runtime and use them for the generated key hashers, which are also
what the runtime and `intrinsics.type_hasher_proc` use.
An `any` holding a pointer, multi-pointer or fixed array printed raw,
as `{data = ..., id = ^int}`, since no debug type is named `^int` or
`[3]f32`. Build such types from their element, found by the rest of
the name, in both the gdb and lldb printers.
A non-nil `Maybe(^T)` or a #shared_nil union of pointers printed as
nothing, as gdb prints nothing for a pointer gdb.Value returned by a
printer's to_string. Return the pointer formatted as a string instead,
which is what the lldb summary already shows.
When a `context` is available, the `with_context` variant will be called
and the `context.assertion_failure_proc` will be called, instead of
forcibly trapping. This allows bounds check errors able to be handled by
custom assertion failure procs.
`base/runtime`: do not free the original block on a failed heap resize
The default heap allocator freed old_ptr when the underlying allocation
failed (allocated_mem == nil). On the realloc path (heap_resize) the original
block is left intact on failure, and on the copy/fresh path old_ptr has not
been copied or freed yet, so freeing it left the caller holding a dangling
pointer. A [dynamic] array whose resize failed therefore double-freed its
data on the next delete (reported as free(): invalid pointer / use-after-free).
Return .Out_Of_Memory without freeing anything; the caller retains ownership
of the original block.
Fixes#7262