【问题标题】:why is va_arg returning wrong data?为什么 va_arg 返回错误的数据?
【发布时间】:2014-08-08 14:11:41
【问题描述】:

我正在尝试将嵌入式操作系统移植到新平台,但文件系统组件遇到了一些问题。 我介入了代码以最终定位问题: 与我的案例相关的函数调用是

    // int64_t vnid = 1;
    // int32_t vid = 0;
    ...
    vnode = queue_lookup (& vnode_manager . vnode_list,
                vnode_id_inspector, vnid, vid);

这是 queue_lookup 声明:

    void * queue_lookup (queue_t * queue, queue_inspector_t inspector, ...)
    {
      bool result;
      va_list list, list_copy;
      queue_link_t * item = NULL;

      va_start (list, inspector);

      if (queue -> status != 0)
      {
        for (item = queue -> head; item != NULL; item = item -> next)
        {
          result = false;

          va_copy (list_copy, list);
          result = inspector (item, list_copy);
          va_end (list_copy);

          if (result) break;
        }
      }

      va_end (list);
      return item;
    }

最后,这是 vnode_id_inspector 声明:

    bool vnode_id_inspector (void * node, va_list list)
    {
      vnode_t vnode = node;
      int64_t vnid = va_arg (list, int64_t);
      int32_t vid = va_arg (list, int32_t);

      watch (bool)
      {
        ensure (vnode != NULL, false);
        return vnode -> id == vnid && vnode -> volume -> id == vid;
      }
    }

现在的问题是,当我使用 vnid=1 和 vid=0 调用 queue_lookup 时,我在 vnode_id_inspector 中得到 vnid=1 和 vid=1145248!

如何通过尽可能少的代码更改来解决此问题?

问候,

编辑:添加一些调试信息

    (gdb) p vnode_manager . vnode_list
    $44 = {lock = 1, head = 0x167770, tail = 0x167770, status = 1}
    (gdb) p vnode_manager . vnode_list ->head
    $45 = (queue_link_t *) 0x167770
    (gdb) p *(vnode_t)vnode_manager . vnode_list ->head
    $46 = {link = {next = 0x0}, id = 1, volume = 0x166370, destroy = false, 
      usage_counter = 1, data = 0x166430}
    (gdb) p *(volume_t)((vnode_t)vnode_manager . vnode_list ->head)->volume
    $47 = {link = {next = 0x0}, id = 0, root_vnid = 1, lock = 0, host_volume = 0x0, 
      host_vnid = -1, cmd = 0x13a768 <rootfs_cmd>, data = 0x1663d0}

【问题讨论】:

  • vid 和 vnid 的类型是否正确?
  • 是的类型是正确的!
  • 单独的问题:您在无效指针上调用 va_end(copy_list)。
  • 我认为您的问题可能出在其他地方,请尝试使用可变参数创建一个简单的测试。
  • 您应该将解决方案放在答案中,而不是编辑您的问题并将其添加到那里。允许回答您自己的问题。

标签: c operating-system filesystems embedded


【解决方案1】:

我解决了这个问题,堆栈对齐有问题。我通过在 cpu_context_switch.s 中进行一些调整以将堆栈对齐到 8bytes 而不是 4bytes 来修复它。

【讨论】:

    猜你喜欢
    • 2023-02-07
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多