vtable 中未对齐的地址

Unaligned address in vtable

我不知道在这里问这样的问题是否合适,所以如果需要请重定向我。

我正在研究嵌入式 MCU (STM32L5),遇到一些 C++ 代码因硬故障而崩溃的问题。经过进一步调查,我确定原因是分支到未对齐(即没有字对齐)的内存地址。经过更多挖掘,我发现这是在虚拟方法的分支上发生的。而且,据我所知,vtable 本身中的地址看起来是“无效的”(即,不是字对齐的)。这里有一些图片来说明我所看到的。

单步执行这三行(0x080349ce 到 0x080349d2)时,寄存器值如下:

我的问题是,我应该责怪编译器做了一些不应该做的事情,还是我的代码有什么问题会导致这种类型的问题?我正在使用 -Og 优化编译代码。

编辑

实际对象(我正在调用其虚拟方法)驻留在 lambda 中的堆栈中,如下所示:

[this, event, args...](){
    Event<ARGS...> e(event, args...);
    dispatch(&e);
}

其中 Event<> 是一个模板化的 class,它继承自我的抽象基础 class AbstractEvent 并实现了虚拟方法 clone().

dispatch() 函数接受一个 const AbstractEvent* 并在最终到达上面的汇编代码(即下面的 defer 方法)之前调用更多的方法。因此,在我尝试调用虚拟方法时,该对象应该仍在堆栈上。

bool defer(const AbstractEvent* e) {
    if ((e == nullptr) || (_deferQueue.full())) {
        return false;
    } else {
        AbstractEvent* clone = e->clone();
        _deferQueue.push(clone);

    return true;
}

作为参考,AbstractEvent和Event<>的实现如下:

class AbstractEvent {
public:
    AbstractEvent(int index) : _index(index) { }

    virtual ~AbstractEvent() = default;

    int event() const { return _index; }

    virtual AbstractEvent* clone() const = 0;

private:
    int _index;
};

template <typename... ARGS>
class Event : public AbstractEvent {
public:
    Event(int index, const ARGS&... args) :
        AbstractEvent(index),
        _values(args...)
    {

    }
    Event(const Event& other) = default;

    AbstractEvent* clone() const override { return new Event(*this); }

    template <unsigned int INDEX = 0>
    inline const auto& value() const {
        return std::get<INDEX>(_values);
    }

private:
    std::tuple<ARGS...> _values;
};

感谢@11c 指出我们关于“thumb”的说明。事实证明,我的问题实际上并不在我认为的位置,因此不是编译器问题。我认为是未对齐的地址实际上是处理器的正常行为。

参考如下: