Facing C Compilation issue

I am upgrading C-SDK from 2.10.3 version to 3.2.4 version.

But I am getting the compilation errors post upgrade.

Code

lcb_install_callback3(instance, LCB_CALLBACK_PING, ping_callback);
void ping_callback(lcb_t, int, const lcb_RESPBASE *rb)
{
const lcb_RESPPING resp = (const lcb_RESPPING)rb;
int ii;
for (ii = 0; ii < resp->nservices; ii++) {
printf(“service: %s, status: %d, host: %s, latency: %lu nanoseconds\n”,
resp->services[ii].type == LCB_PINGSVC_KV ? “KV” : “N1QL”,
resp->services[ii].status,
resp->services[ii].server,
(unsigned long)resp->services[ii].latency);
}
}

Compilation Errors

code.c: In function ping_callback:
code.c:480:24: error: dereferencing pointer to incomplete type
for (ii = 0; ii < resp->nservices; ii++)

code.c:483:11: error: dereferencing pointer to incomplete type
resp->services[ii].type == LCB_PINGSVC_KV ? “KV” : “N1QL”,

code.c:483:34: error: LCB_PINGSVC_KV undeclared (first use in this function)
resp->services[ii].type == LCB_PINGSVC_KV ? “KV” : “N1QL”,

code.c:484:11: error: dereferencing pointer to incomplete type
resp->services[ii].status,

code.c:485:11: error: dereferencing pointer to incomplete type
resp->services[ii].server,

code.c:486:26: error: dereferencing pointer to incomplete type
(unsigned long)resp->services[ii].latency);

Hi, please make sure you are using correct API for libcouchbase 3.2.4.

In this particular case you should use lcb_respping_result_service:

What will be the replacement for below code as per the 3.2.4 C-SDK version

lcb_CMDPING cmd = { 0 };
void *fp;
cmd.services = LCB_PINGSVC_F_KV | LCB_PINGSVC_F_N1QL;
lcb_ping3(a, fp, &cmd);

I went through the above documentation and also checked the below C-SDK 3.2.4 API notes,

https://docs.couchbase.com/sdk-api/couchbase-c-client-3.2.4/group__lcb-ping.html

But I cannot find lcb_CMDPING and lcb_ping3 in 3.2.4 version.

You can use this example as a reference:

And replace lcb_cmdping_all(cmd) with

lcb_cmdping_kv(cmd, 1);
lcb_cmdping_query(cmd, 1);
1 Like

Will the following C-SDK 3.2.4 code be the correct replacement/alternative for 2.10.3 version ping_callback code ?

C-SDK 2.10.3 Code

void ping_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
{
    const lcb_RESPPING *resp = (const lcb_RESPPING*)rb;
    int ii;
    for (ii = 0; ii < resp->nservices; ii++) {
        printf("service: %s, status: %d, host: %s, latency: %lu nanoseconds\n",
            resp->services[ii].type == LCB_PINGSVC_KV ? "KV" : "N1QL",
            resp->services[ii].status,
            resp->services[ii].server,
            (unsigned long)resp->services[ii].latency);
    }
}

C-SDK 3.2.4 Code

void ping_callback(lcb_INSTANCE *instance, int cbtype, const lcb_RESPBASE *rb)
{
    const lcb_RESPPING *resp = (const lcb_RESPPING*)rb;

    size_t nservices, ii;
    lcb_PING_SERVICE *type;
    const char **address;
    size_t *address_len;
    uint64_t *latency;

    nservices = lcb_respping_result_size(resp);

    for (ii = 0; ii < nservices; ii++) {

        lcb_respping_result_service (resp, ii, type);
        lcb_respping_result_remote (resp, ii, address, address_len);
        lcb_respping_result_latency (resp, ii, latency);

        printf("service: %s, status: %d, host: %s, latency: %lu nanoseconds\n",
	    type == LCB_PINGSVC_KV ? "KV" : "N1QL",
            lcb_respping_result_status(resp, ii),
            address,
            (unsigned long)latency);
    }
}

This is not correct:

    const char **address;
    size_t *address_len;

The function takes pointer to pointer char, but you have to allocate pointer to char, and pass its address into the function. The same for the length. These two are output parameters.

Another suggestion: check the status codes of the functions.

The updated code is getting successfully compiled in C-SDK 3.2.4 version. But during runtime, its giving "Segmentation fault (core dumped)" error.

C-SDK 3.2.4 version Code :

#include<string.h>
#include <libcouchbase/couchbase.h>

void ping_callback(lcb_INSTANCE *instance, int cbtype, const lcb_RESPBASE *rb)
{
    const lcb_RESPPING *resp = (const lcb_RESPPING*)rb;

    size_t nservices, ii;
    lcb_PING_SERVICE *type;
    const char *address;
    size_t address_len;
    uint64_t *latency;

    nservices = lcb_respping_result_size(resp);

    for (ii = 0; ii < nservices; ii++) {

        lcb_respping_result_service (resp, ii, type);
        lcb_respping_result_remote (resp, ii, &address, &address_len);
        lcb_respping_result_latency (resp, ii, latency);

        printf("service: %s, status: %d, host: %s, latency: %lu nanoseconds\n",
	    type == LCB_PING_SERVICE_KV ? "KV" : "N1QL",
            lcb_respping_result_status(resp, ii),
            address,
            (unsigned long)latency);
    }
}

void main()
{

lcb_INSTANCE *a;

    lcb_CREATEOPTS *create_options = NULL;
    lcb_createopts_create(&create_options, LCB_TYPE_BUCKET);
    lcb_createopts_connstr(create_options, "couchbase://localhost/Bucket-Name", strlen("couchbase://localhost/Bucket-Name"));
    lcb_createopts_credentials(create_options, "Username", strlen("Username"), "Password", strlen("Password"));
    lcb_STATUS err = lcb_create(&a, create_options);
    
    lcb_connect(a);
    lcb_wait(a,LCB_WAIT_DEFAULT);

lcb_CMDPING *cmd;
void *fp;

lcb_cmdping_create(&cmd);

// select services to ping
lcb_cmdping_kv(cmd, 1);
lcb_cmdping_query(cmd, 1);

lcb_install_callback(a, LCB_CALLBACK_PING, ping_callback);

lcb_ping(a, fp, cmd);
lcb_wait(a,LCB_WAIT_DEFAULT);

}

Console Output :

service: N1QL, status: 0, host: 10.132.72.69:11210, latency: 29156448 nanoseconds
service: N1QL, status: 0, host: 10.132.72.80:8093, latency: 29156448 nanoseconds
service: N1QL, status: 0, host: 10.132.72.68:8093, latency: 29156448 nanoseconds
service: N1QL, status: 0, host: 10.132.72.93:8093, latency: 29156448 nanoseconds
service: N1QL, status: 0, host: 10.132.72.81:11210, latency: 29156448 nanoseconds
service: N1QL, status: 0, host: 10.132.72.78:11210, latency: 29156448 nanoseconds
Segmentation fault (core dumped)

Have you tried running it under debugger? I don’t see how you check return values from lcb_* functions. Could you be more precise and tell on which line it crashes?

The code crashes at the line lcb_wait(a,LCB_WAIT_DEFAULT); (line no 56) after executing the ping_callback() function.

lcb_ping(a, fp, cmd);
lcb_wait(a,LCB_WAIT_DEFAULT); //Code crashes at this point in the above code snippet

GDB Console Output :

(gdb)
service: N1QL, status: 0, host: 10.132.72.69:11210, latency: 28780368 nanoseconds
service: N1QL, status: 0, host: 10.132.72.80:8093, latency: 28780368 nanoseconds
service: N1QL, status: 0, host: 10.132.72.68:8093, latency: 28780368 nanoseconds
service: N1QL, status: 0, host: 10.132.72.93:8093, latency: 28780368 nanoseconds
service: N1QL, status: 0, host: 10.132.72.81:11210, latency: 28780368 nanoseconds
service: N1QL, status: 0, host: 10.132.72.78:11210, latency: 28780368 nanoseconds

(gdb)
0x00007ffff77d7248 in invoke_ping_callback(lcb_st*, PingCookie*) () from /usr/lib64/libcouchbase.so.8

(gdb)
Single stepping until exit from function _ZL20invoke_ping_callbackP6lcb_stP10PingCookie,
which has no line number information.
0x00007ffff77d86b8 in handle_ping(mc_pipeline_st*, mc_packet_st*, lcb_CALLBACK_TYPE, lcb_STATUS, void const*) () from /usr/lib64/libcouchbase.so.8

(gdb)
Single stepping until exit from function _ZL11handle_pingP14mc_pipeline_stP12mc_packet_st17lcb_CALLBACK_TYPE10lcb_STATUSPKv,
which has no line number information.
0x00007ffff77835e4 in H_noop(mc_pipeline_st*, mc_packet_st*, lcb::MemcachedResponse*, lcb_STATUS) () from /usr/lib64/libcouchbase.so.8

(gdb)
Single stepping until exit from function _ZL6H_noopP14mc_pipeline_stP12mc_packet_stPN3lcb17MemcachedResponseE10lcb_STATUS,
which has no line number information.
0x00007ffff77868ed in mcreq_dispatch_response () from /usr/lib64/libcouchbase.so.8

(gdb)
Single stepping until exit from function mcreq_dispatch_response,
which has no line number information.
0x00007ffff779dbc2 in lcb::Server::try_read(lcbio_CTX*, rdb_IOROPE*) () from /usr/lib64/libcouchbase.so.8

(gdb)
Single stepping until exit from function _ZN3lcb6Server8try_readEP9lcbio_CTXP10rdb_IOROPE,
which has no line number information.
0x00007ffff779f537 in on_read(lcbio_CTX*, unsigned int) () from /usr/lib64/libcouchbase.so.8

(gdb)
Single stepping until exit from function _ZL7on_readP9lcbio_CTXj,
which has no line number information.
0x00007ffff77f4ce0 in lcb_maybe_breakout () from /usr/lib64/libcouchbase.so.8

(gdb)
Single stepping until exit from function lcb_maybe_breakout,
which has no line number information.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff77f4ca5 in has_pending(lcb_st*) () from /usr/lib64/libcouchbase.so.8

(gdb)
Single stepping until exit from function _ZL11has_pendingP6lcb_st,
which has no line number information.

Program terminated with signal SIGSEGV, Segmentation fault.

looks like your stack was corrupted. I don’t see where you allocate memory for latency. Oh, and why do you interpret this pointer as number of nanoseconds? I just realized that all you latencies basically the same value. Please check the signature, lcb_respping_result_latency expects pointer to some memory, that the caller has allocated (on stack or on heap), just like with address. Also the type passes variable instead of taking pointer of the memory your sample owns.

Thanks a lot @avsej.

Correcting the data types solved the issue and its working fine now.

1 Like