为什么我的 Thrift (c_glib) 客户端失败并出现 "invalid pointer" 错误?
Why does my Thrift (c_glib) client fail with an "invalid pointer" error?
我正在用 C (g_lib) 创建一个简单的节俭 server/client 程序。
这是我的 thrift IDL 文件的样子:
namespace cpp tutorial
service Calculator {
void ping(),
binary getdata()
}
thrift 服务器上 getdata 的实现如下所示:
static gboolean
tutorial_calculator_handler_getdata (CalculatorIf *iface,
GByteArray *_return,
GError **error)
{
THRIFT_UNUSED_VAR (iface);
THRIFT_UNUSED_VAR (error);
puts ("getdata()");
GByteArray *gbarray;
gint i;
gbarray = g_byte_array_new ();
for (i = 0; i < 100; i++)
g_byte_array_append (gbarray, (guint8*) &i, 1);
*_return = *gbarray;
return TRUE;
}
现在,在客户端,我按如下方式调用 getdata:
....
....
GByteArray *data;
....
....
if (!error && calculator_if_getdata (client, &data, &error)) {
puts ("getdata()");
}
不幸的是,客户端在 calculator_if_getdata 调用中崩溃并显示以下消息:
*** Error in `./client': munmap_chunk(): invalid pointer: 0xb741742d ***
Aborted (core dumped)
这是将整数数组从服务器发送到 thrift 客户端的正确方法吗?我在这里做错了什么?
我发现您在这里所做的事情存在三个问题:
如果服务方法returns是复杂类型,传递给其处理函数的_return
参数将指向一个预分配 不应被破坏或重新创建的结构。您的代码应该将值附加到 _return
已经指向的 GByteArray
,而不是创建它自己的 GByteArray
。
尽管您不应该尝试修改 _return
的值,但是您的代码执行此操作的方式不正确,最终会破坏 [=10= 的数据结构] 点。这很可能解释了您看到的错误消息。
您的代码声明 i
一个三十二位整数,但仅将 i
的第一个字节附加到字节数组。这不会对每个机器架构产生您想要的效果。
我花了一些时间才弄明白,这是工作处理程序和客户端实现代码:
gboolean
tutorial_calculator_handler_getdata (CalculatorIf *iface,
GByteArray ** _return,
GError **error)
{
THRIFT_UNUSED_VAR (iface);
THRIFT_UNUSED_VAR (error);
GByteArray *thing = g_byte_array_new();
*_return = g_byte_array_new();
guint8 i;
for (i = 0; i < 10; i++){
g_byte_array_append (thing, (guint8*) &i, sizeof(guint8));
}
g_byte_array_append(*_return, (guint8*) thing->data, thing->len);
return TRUE;
}
客户端:
GByteArray *data = g_byte_array_new();
if (!error && calculator_if_getdata (client, &data, &error)) {
puts ("getdata()");
printf ("Data : %d\n", data);
guint8 i;
guint8 size = sizeof(guint8);
for(i=0;i<10;i++)
printf ("Data : %d\n", data->data[size*i]);
}
我正在用 C (g_lib) 创建一个简单的节俭 server/client 程序。 这是我的 thrift IDL 文件的样子:
namespace cpp tutorial
service Calculator {
void ping(),
binary getdata()
}
thrift 服务器上 getdata 的实现如下所示:
static gboolean
tutorial_calculator_handler_getdata (CalculatorIf *iface,
GByteArray *_return,
GError **error)
{
THRIFT_UNUSED_VAR (iface);
THRIFT_UNUSED_VAR (error);
puts ("getdata()");
GByteArray *gbarray;
gint i;
gbarray = g_byte_array_new ();
for (i = 0; i < 100; i++)
g_byte_array_append (gbarray, (guint8*) &i, 1);
*_return = *gbarray;
return TRUE;
}
现在,在客户端,我按如下方式调用 getdata:
....
....
GByteArray *data;
....
....
if (!error && calculator_if_getdata (client, &data, &error)) {
puts ("getdata()");
}
不幸的是,客户端在 calculator_if_getdata 调用中崩溃并显示以下消息:
*** Error in `./client': munmap_chunk(): invalid pointer: 0xb741742d ***
Aborted (core dumped)
这是将整数数组从服务器发送到 thrift 客户端的正确方法吗?我在这里做错了什么?
我发现您在这里所做的事情存在三个问题:
如果服务方法returns是复杂类型,传递给其处理函数的
_return
参数将指向一个预分配 不应被破坏或重新创建的结构。您的代码应该将值附加到_return
已经指向的GByteArray
,而不是创建它自己的GByteArray
。尽管您不应该尝试修改
_return
的值,但是您的代码执行此操作的方式不正确,最终会破坏 [=10= 的数据结构] 点。这很可能解释了您看到的错误消息。您的代码声明
i
一个三十二位整数,但仅将i
的第一个字节附加到字节数组。这不会对每个机器架构产生您想要的效果。
我花了一些时间才弄明白,这是工作处理程序和客户端实现代码:
gboolean
tutorial_calculator_handler_getdata (CalculatorIf *iface,
GByteArray ** _return,
GError **error)
{
THRIFT_UNUSED_VAR (iface);
THRIFT_UNUSED_VAR (error);
GByteArray *thing = g_byte_array_new();
*_return = g_byte_array_new();
guint8 i;
for (i = 0; i < 10; i++){
g_byte_array_append (thing, (guint8*) &i, sizeof(guint8));
}
g_byte_array_append(*_return, (guint8*) thing->data, thing->len);
return TRUE;
}
客户端:
GByteArray *data = g_byte_array_new();
if (!error && calculator_if_getdata (client, &data, &error)) {
puts ("getdata()");
printf ("Data : %d\n", data);
guint8 i;
guint8 size = sizeof(guint8);
for(i=0;i<10;i++)
printf ("Data : %d\n", data->data[size*i]);
}