This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

sd_ble_gatts_value_set causes a segmentation violation (SIGSEGV)

I'm trying to create a simple service that would just provide some data which could get updated internally (for example, via SPI bus). Data may be of a different size, so I'm trying to notify the device about the change in data buffer by calling sd_ble_gatts_value_set. However, I get a SIGSEGV when I call that function. Here's how I set up a service:

ble_uuid_t ble_uuid;

ble_gatts_char_md_t char_md;
ble_gatts_attr_md_t attr_md;
ble_gatts_attr_t attr_char_value;
...
char_md.char_props.read = 1;
char_md.char_props.write = 0;
char_md.char_props.notify = 0;

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = 0;
attr_md.wr_auth = 0;
attr_md.vlen = 1;

attr_char_value.p_uuid = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = 1;
attr_char_value.init_offs = 0;
attr_char_value.max_len = 256;
attr_char_value.p_value = data; // data is a pointer to the buffer

err_code = sd_ble_gatts_characteristic_add(
p_service->service_handle,
&char_md, &attr_char_value,
&p_service->char_handle
);

VERIFY_SUCCESS(err_code);

I tried setting attr_md.vloc to either BLE_GATTS_VLOC_STACK or BLE_GATTS_VLOC_USER, depending on whether I was allocating arrays on stack or on heap - I have tried both, with both using malloc and nrf_malloc.
Then I change a data in the buffer and I would like to update the length of the data:

ble_gatts_value_t value_md = {
.len = length, // length is passed to the function
.offset = 0,
.p_value = NULL
};
err_code = sd_ble_gatts_value_set(
BLE_CONN_HANDLE_INVALID,
p_service->char_handles.value_handle,
&value_md
);
VERIFY_SUCCESS(err_code);

return NRF_SUCCESS

I suspect I have some issues with allocating my buffers, or I don't understand something about what data exactly is in the Characteristic, because when I try to just change the first byte of the data array in the code after I have created the service and characteristics, I don't see an update in the nRF Connect app, but if I set it beforehand, I can see it.

Please tell me if I can provide any other code snippets or sdk configuration information if that would help you help me solve this problem. My SDK version is 7.0.1.

Thanks in advance for all suggestions.

  • Sorry, I've made a mistake in my post - I'm using a SoftDevice of version 7.0.1, not SDK; SDK is of version 15. I have updated SDK to version 16 and SoftDevice to the latest version - I acquired mine last fall, I can see that it was modified recently. There is no change - I still get a SIGSEGV with similar addresses and symptoms. 

    Also, I do not see any example other than one at `/examples/ble_central_and_peripheral/experimental/ble_app_att_mtu_throughput/` using sd_ble_gatts_value_set function.

  • Ok, good. 

    Softdevice version 7.0.1 is only used in SDK16.0.0, so I assume that was what you were using? If not, it is the one you should use, as this contains the correct softdevice headers for softdevice version 7.0.1

    I compiled your project with SDK16.0.0. I had to change the oberon library version to the one matching SDK16 in order to compile without any errors.

    Then I flashed the softdevice S132 from SDK16.0.0\components\softdevice\s132\hex

    And then I flashed the built application, and it looks like it is running here. LED1 on the DK is blinking as when it is advertising, and the log says:

    <debug> app: Service UUID: 0x1800
    
    <debug> app: Service UUID type: 0x02
    
    <debug> app: Service handle: 0x000E
    
    
    <debug> app: Characteristic value handle: 0x0010
    
    <debug> app: Characteristic user desc handle: 0x0000
    
    
    <info> app: Template example started.
    
    <info> app: Fast advertising.
    

    Do I have to do something to trigger the bug? 

    Can you try to check with Ozone (from segger) which takes the .out file to start a debug session. This is what I ued to check that it was in fact running, and that it didn't keep resetting.

    BR,

    Edvin

  • Yes, the strange thing is that the bug doesn't present itself during normal execution. I have set a break point on the `update_data_characteristic` function, then I execute it step by step and on `sd_ble_gatts_value_set` call I get a segfault.

    Unfortunately I don't have a Segger debugging device, I use SWD-compatible debugger and debug using GDB.

  • Edvin, I apologize for misinformation. I assumed  that with disabled optimizations GDB would at least step onto VERIFY_SUCCESS macro before throwing out SIGSEGV, but after I looked into the example I listed above and added a simple print for a err_code after the function call, it seems that `sd_ble_gatts_value_set` function returns with an error 0x10, which I assume is NRF_ERROR_INVALID_ADDR , which means, according to the function documentation, that I have supplied invalid pointer. I, however, don't know which one of the pointers is invalid. Could you please help me understand why my function call is wrong?

  • So it is update_data_characteristic() that returns NRF_ERROR_INVALID_ADDR, right?

    Again, I didn't get any errors when running your application, but I am not sure of the workflow in your application.

    A while ago, I modified the ble_app_uart example to use sd_ble_gatts_value_set() a while ago. I copied the function ble_nus_data_send() (copied and renamed it ble_nus_data_set).

    I suggest you check out the attached project. 

    I am not sure I approve your implementation of your service's initialization and update function. It may work, but it is very different from the examples. Perhaps you can check out the attached project. Unzip it next to the ble_app_uart example. The pca10040\s132\gcc project should compile without modifications.

    ble_app_uart_set.zip

Related