当我调用函数

时间:2017-02-09 13:43:29

标签: c++ c linux gcc gdb

该功能的定义如下:

1 db_bool cm_text_equal(const cm_text_t *text1, const cm_text_t *text2, db_bool case_ins)

它会像这样调用:

cm_format_element_t * cm_fetch_fmt_element(cm_text_t * fmt)
{
    db_uint32 i;
    cm_text_t   cmp_text;

    CM_POINTER(fmt);

    cmp_text.str = fmt->str;

    for(i = 0; i < DATE_FORMAT_COUNT; i++)
    {
        cmp_text.len = g_fmt_elements[i].name.len;
        if(cmp_text.len > fmt->len)
        {
            continue;
        }
        //2 the problem happens here where the function be called
        if(cm_text_equal(&g_fmt_elements[i].name, &cmp_text, DB_TRUE))
        {
           fmt->str += cmp_text.len;
           fmt->len = (db_uint16)(fmt->len - cmp_text.len);
           return &g_fmt_elements[i];
         }
    }

    return NULL;
}

g_fmt_elements []的定义如下:

cm_format_element_t g_fmt_elements[DATE_FORMAT_COUNT] =
{
    {{1, (db_char *)" "}, FMT_SPACE_SPLIT, DB_TRUE},
    {{1, (db_char *)"-"}, FMT_MINUS_SPLIT, DB_TRUE},
   ...
}

typedef struct tagcm_format_element
{
   cm_text_t         name;
   db_uint16       id;
   db_bool         reverse_used;
}cm_format_element_t;

typedef struct tagcm_text
{
   db_uint32       len;
   db_char       * str;
}cm_text_t;

我通过gdb调试程序。所以在调用函数cm_text_equal之前。三个参数是:

&g_fmt_elements[i].name = (cm_text_t *) 0x7f24f8766890
&cmp_text=0x7f2553ef8790
DB_TRUE=1

当cm_fetch_fmt_element正在运行到&#34; // 2问题时......&#34;。 i = 30。变量g_fmt_elements是一个全局静态变量。 你可以在下面看到它的定义。

(gdb) p g_fmt_elements[30]
$57 = {name = {len = 4, str = 0x7f24f854a949 "YYYY"}, id = 226, reverse_used      = 1}
(gdb) p &g_fmt_elements[30]
$58 = (cm_format_element_t *) 0x7f24f8766890

然后我进入函数cm_text_equal,结果是:

(gdb) s
cm_text_equal (text1=0x7f256ec655d0, text2=0x7f2553ef8790, case_ins=1) at src/db_text.c:504

所以你可以看到,第一个参数从0x7f24f8766890变为0x7f256ec655d0,我检查了regesters:

(gdb) p/x $rdi
$52 = 0x7f256ec655d0
(gdb) p/x $rsi
$53 = 0x7f2553ef8790
(gdb) p/x $rdx
$54 = 0x1

你可以看到传入rdi的第一个参数真的发生了变化。有谁知道这是怎么回事?

我还检查了两个不同的地址。

(gdb) p *(cm_format_element_t*)0x7f256ec655d0
$55 = {name = {len = 4, str = 0x7f256ea6275c "YYYY"}, id = 226, reverse_used = 0}
(gdb) p *(cm_format_element_t*)0x7f24f8766890
$56 = {name = {len = 4, str = 0x7f24f854a949 "YYYY"}, id = 226, reverse_used = 1}

你知道,0x7f24f8766890是正确的地址,其值与定义相同。而另一个地址0x7f256ec655d0是错误的,但我不明白它的价值几乎与正确的相同。但是最后一个成员是错误的,这使我的程序运行异常。

以下是我后来发现的更多细节

谢谢大家的帮助。 我想我发现了哪里错了。 我花了两天时间弄清楚原因,我不擅长。哈哈。 但我仍然想为可能遇到同样问题的其他人解答。 好的,让我们开始吧。

因为我已重新启动程序,所以addr已更改。所以这一次 在进入功能之前。添加g_fmt_elements [30]是:

(gdb) p g_fmt_elements[30]
$6 = {name = {len = 4, str = 0x2ae97faa554e "YYYY"}, id = 226, reverse_used   = 1}
(gdb) p &g_fmt_elements[30]
 $7 = (cm_format_element_t *) 0x2ae97fcc34d0
(gdb) 

并且在进入函数之后,param text1变为:

(gdb)  cm_text_equal (text1=0x2ae90be468f0, text2=0x2ae926d85540, case_ins=1) at src/db_text.c:499

所以,你看,(cm_format_element_t *)0x2ae97fcc34d0似乎改为text1 = 0x2ae90be468f0,所以我也检查了这两个addr的上下文:

//-->the right one
(gdb)p *(cm_format_element_t*)0x2ae97fcc34d0 
{name = {len = 4, str = 0x2ae97faa554e "YYYY"}, id = 226, reverse_used = 1}
//-->the wrong one
(gdb)p *(cm_format_element_t*)0x2ae90be468f0 
{name = {len = 4, str = 0x2ae90bc432e6"YYYY"}, id = 226, reverse_used = 0}

这两个上下文几乎相同但是&#34; add的str&#34;和&#34; reverse_used&#34;。

那么,错误的地址0x2ae90be468f0到底是怎么回事,为什么上下文几乎一样?

所以,请查询程序的libs addr,找到addr 0x2ae90be468f0所属的lib。

0 个答案:

没有答案