diff --git a/CHANGELOG.md b/CHANGELOG.md index 9761830ee..7eccf6daa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed +- `tt coredump`: adjust Tarantool GDB-extention to avoid load failure if `main_cord` + symbol is `optimized out` in gdb session. + ## [2.11.0] - 2025-09-10 The release supports Tarantool Config Storage in `tt cluster failover` commands and diff --git a/cli/coredump/extensions/tarantool-gdb.py b/cli/coredump/extensions/tarantool-gdb.py index dc924af63..23d5fca18 100644 --- a/cli/coredump/extensions/tarantool-gdb.py +++ b/cli/coredump/extensions/tarantool-gdb.py @@ -1560,7 +1560,7 @@ def _init(cls): if not hasattr(cls, '_containers_map'): cls._containers_map = cls.__build_containers_map(cls._containers) - __symbol_re = re.compile('(\w+)(?:\s*\+\s*(\d+))?') + __symbol_re = re.compile(r'(\w+)(?:\s*\+\s*(\d+))?') @classmethod def lookup_entry_info(cls, address): @@ -2582,16 +2582,14 @@ def fiber(): class Cord(object): - __main_cord_fibers = gdb.parse_and_eval('main_cord.alive') - __list_entry_info = RlistLut.lookup_entry_info(__main_cord_fibers.address) - def __init__(self): self.__cord_ptr = cord() def fibers(self): fibers = self.__cord_ptr['alive'] fibers = Rlist(fibers.address) - fibers = map(lambda x: self.__class__.__list_entry_info.container_from_field(x), fibers) + list_entry_info = RlistLut.lookup_entry_info_by_container(ContainerFieldInfo("cord::alive")) + fibers = map(lambda x: list_entry_info.container_from_field(x), fibers) return itertools.chain(fibers, [self.__cord_ptr['sched'].address]) def fiber(self, fid): diff --git a/cli/replicaset/cartridge.go b/cli/replicaset/cartridge.go index 2350991eb..d1694eef6 100644 --- a/cli/replicaset/cartridge.go +++ b/cli/replicaset/cartridge.go @@ -245,6 +245,7 @@ func (c *CartridgeApplication) discovery() (Replicasets, error) { } if topology.IsBootstrapped { if newTopology.IsBootstrapped { + updateInstancesAliases(newTopology.Replicasets, topology.Replicasets) topology = newTopology } } else { @@ -252,7 +253,8 @@ func (c *CartridgeApplication) discovery() (Replicasets, error) { } // Stop if we already found a valid topology. - return topology.IsBootstrapped && !topology.IsCritical, nil + return topology.IsBootstrapped && !topology.IsCritical && + !hasMissingInstancesAliases(topology.Replicasets), nil }, )) if err != nil { @@ -271,6 +273,37 @@ func (c *CartridgeApplication) discovery() (Replicasets, error) { return recalculateMasters(replicasets), err } +// hasMissingInstancesAliases checks if any instance has empty alias. +func hasMissingInstancesAliases(replicasets []Replicaset) bool { + for _, rs := range replicasets { + for _, inst := range rs.Instances { + if len(inst.Alias) == 0 { + return true + } + } + } + return false +} + +// updateInstancesAliases tries to update missing instances aliases with another instances data. +func updateInstancesAliases(replicasets, other []Replicaset) { + instAliases := make(map[string]string, 0) + for _, rs := range other { + for _, inst := range rs.Instances { + instAliases[inst.UUID] = inst.Alias + } + } + for i, rs := range replicasets { + for ii, inst := range rs.Instances { + if len(inst.Alias) == 0 { + if alias, ok := instAliases[inst.UUID]; ok && len(alias) > 0 { + replicasets[i].Instances[ii].Alias = alias + } + } + } + } +} + // Promote promotes an instance in the cartridge application. func (c *CartridgeApplication) Promote(ctx PromoteCtx) error { replicasets, err := c.Discovery(UseCache)