# Scan using C client giving segmentation error after scanning bunch of records

**URL:** <https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175>\
**Category:** C Client Library\
**Tags:** scan\
**Created:** [April 28, 2023, 5:57am UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175 "2023-04-28T05:57:40Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mohd](https://avatars.discourse-cdn.com/v4/letter/m/57b2e6/32.png) [@mohd](https://discuss.aerospike.com/u/mohd)\
**Post date:** [April 28, 2023, 5:57am UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/1 "2023-04-28T05:57:41Z")

</div>

Hi Team, I am getting memory segmentation error while running scan (concurrent is False) after scanning subset of records . Scan abruptly fails after processing few records so not sure what is causing this issue.

Below is the high level steps for the implemented code.

1. connection to aerospike server is made in main function
2. aerospike\_scan\_foreach is call with cb and connection pointer
3. in callback first we read the list of map under the scanned record PK and then reinsert the same after applying the as\_hashmap\_sort\_flag to sort the list of map (this we do in overwrite mode)

**Note:** Failure is not specific to record it fails randomly. When we only scan then no issues but when we scan and perform read and write in callback then it fails after processing 150k records out of 200k.

Thanks

---

<div class="post-metadata">

**Author:** ![Brian](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/brian/32/2211_2.png) [@Brian](https://discuss.aerospike.com/u/Brian)\
**Post date:** [April 28, 2023, 5:42pm UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/2 "2023-04-28T17:42:32Z")

</div>

I would need to see your scan source code to help.

---

<div class="post-metadata">

**Author:** ![mohd](https://avatars.discourse-cdn.com/v4/letter/m/57b2e6/32.png) [@mohd](https://discuss.aerospike.com/u/mohd)\
**Post date:** [April 29, 2023, 8:50am UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/3 "2023-04-29T08:50:02Z")

</div>

Hi Brian, Now the code is working fine (updated code below) though unable to find the root cause behind failures (was getting segmentation error).

bool mpr\_cleanup\_cb(const as\_val\* p\_val, void\* udata) {

if (p\_val == NULL) { // scan is complete printf(“\n\nScan callback returned null - scan is complete”); return true; }

```
    as_bin* b;
    as_list* list_val;
    as_string* list_key_val;
    as_map* list_map;
    const char *name_token[2];
    as_record* updated_rec = NULL;
    aerospike *as_new = (aerospike*)udata;
    int j=0,i=0;
    uint32_t list_len;
    as_status ret;
    const char* key_val=NULL;
    as_error err;
    as_operations* ops = as_operations_new(2);
    as_key key;

    as_record* rec =NULL;
    rec=as_record_fromval(p_val);

    if (! rec) {
        //printf("scan callback returned non-as_record object");
        return false;
    }

    as_key_init_digest(&key, g_namespace, g_set, rec->key.digest.value);
	 list_val = as_record_get_list(rec,g_list_bin_nm);
            list_len = as_list_size(list_val);
            key_val=as_record_get_str(rec,g_list_key_nm);
            printf("\n printing list key value: %s ",key_val);

            as_arraylist *as_si_list = as_arraylist_new(list_len, 0);
            //itterate over the list
            for(j=0;j<list_len;j++)
            {
                    list_map = as_map_fromval((as_val*)as_list_get(list_val,j));
                    as_hashmap_set_flags((as_hashmap*)list_map, AS_MAP_KEY_ORDERED);
                    as_arraylist_append_map(as_si_list, (as_map*)list_map);

            }
                list_len = as_list_size((as_list*)as_si_list);
                if(list_len >0)
                {

                      as_operations_add_write(ops, g_list_bin_nm,(as_bin_value*)as_si_list);
                    ret=aerospike_key_operate((aerospike*)udata, &err, NULL, &key, ops, NULL);

                      if(ret!=AEROSPIKE_OK)
                      {
                        printf("\n Return code: AEROSPIKE_NOT_OK - %d for %s ",err.code,key_val);
                      }
                      else
                      {
                            printf("\n Return code: AEROSPIKE_OK - %d for %s ",err.code,key_val);
                            name_token[0]=g_list_bin_nm;
                            name_token[1]=NULL;
                            aerospike_key_select(as_new, &err, NULL,&key,name_token, &updated_rec);
                            as_list* updated_list_val = as_record_get_list(updated_rec,g_list_bin_nm);
                            uint32_t updated_list_len = as_list_size(updated_list_val);
                            printf("\n Updated list length: %d",updated_list_len);
                            //as_arraylist_destroy(as_si_list);

                            if(updated_list_len==list_len)
                            {
                            printf("\n Before and After list length for: %s is_matching",key_val);
                            }
                            else
                            {
                                    printf("\n Before and After list length for: %s is_not_matching",key_val);
                            }
                      }

                }
                else

                    {  
					
					    printf("\n List is empty for the scanned key %s",key_val);

                    }

```

as\_record\_destroy(rec); as\_record\_destroy(updated\_rec); as\_operations\_destroy(ops);

```
return true;

```

}

Below are the statements which have been removed and replaced with given statements. **removed:** list\_key\_val = (as\_string\*)as\_val\_reserve(as\_record\_get\_string(rec,g\_list\_key\_nm)); char\* key\_val = list\_key\_val-\>value; ret=aerospike\_key\_operate((aerospike\*)udata, &err, NULL, &key, &ops, &rec);

**replaced with :** key\_val=as\_record\_get\_str(rec,g\_list\_key\_nm); ret=aerospike\_key\_operate((aerospike\*)udata, &err, NULL, &key, &ops, NULL);

---

<div class="post-metadata">

**Author:** ![Brian](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/brian/32/2211_2.png) [@Brian](https://discuss.aerospike.com/u/Brian)\
**Post date:** [May 1, 2023, 8:21pm UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/4 "2023-05-01T20:21:27Z")

</div>

Do not call `as_record_destroy(rec)` in scan callbacks. The client does that for you when the callback completes.

---

<div class="post-metadata">

**Author:** ![mohd](https://avatars.discourse-cdn.com/v4/letter/m/57b2e6/32.png) [@mohd](https://discuss.aerospike.com/u/mohd)\
**Post date:** [May 2, 2023, 3:59am UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/5 "2023-05-02T03:59:03Z")

</div>

Hi Brian, I do see it fails when i put as\_operations\_destroy but not sure why. Do you see any challenge in provided code? Or everything looks fine?

---

<div class="post-metadata">

**Author:** ![Brian](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/brian/32/2211_2.png) [@Brian](https://discuss.aerospike.com/u/Brian)\
**Post date:** [May 2, 2023, 6:44pm UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/6 "2023-05-02T18:44:18Z")

</div>

If ops is created on the heap in the callback, then ops should be destroyed when done using ops.

---

<div class="post-metadata">

**Author:** ![mohd](https://avatars.discourse-cdn.com/v4/letter/m/57b2e6/32.png) [@mohd](https://discuss.aerospike.com/u/mohd)\
**Post date:** [May 5, 2023, 4:43am UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/7 "2023-05-05T04:43:13Z")

</div>

Hi Brian, yes we are creating ops with below statement. as\_operations\* ops = as\_operations\_new(2);

we are destroying ops using below command. as\_operations\_destroy(ops);

But it fails with memory fault issue not sure why.

---

<div class="post-metadata">

**Author:** ![Brian](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/brian/32/2211_2.png) [@Brian](https://discuss.aerospike.com/u/Brian)\
**Post date:** [May 5, 2023, 6:17pm UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/8 "2023-05-05T18:17:39Z")

</div>

aerospike\_key\_operate() sets the `as_record*` arg to NULL which is wrong. Instead, use the following code snippet.

```c
as_operations* ops = as_operations_new(1);
as_operations_add_write(ops, g_list_bin_nm,(as_bin_value*)as_si_list);

as_record* updated_rec = NULL;

ret=aerospike_key_operate((aerospike*)udata, &err, NULL, &key, ops, &updated_rec);

// process rec here.
as_record_destroy(updated_rec);
as_operations_destroy(ops);

```

---

<div class="post-metadata">

**Author:** ![mohd](https://avatars.discourse-cdn.com/v4/letter/m/57b2e6/32.png) [@mohd](https://discuss.aerospike.com/u/mohd)\
**Post date:** [May 5, 2023, 7:32pm UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/9 "2023-05-05T19:32:23Z")

</div>

Why do we need to pass updated\_rec in aerospike\_key\_operate API? In this we are performing write operation and not returning anything.

updated\_record we are using while doing select.

---

<div class="post-metadata">

**Author:** ![Brian](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/brian/32/2211_2.png) [@Brian](https://discuss.aerospike.com/u/Brian)\
**Post date:** [May 5, 2023, 8:05pm UTC](https://discuss.aerospike.com/t/scan-using-c-client-giving-segmentation-error-after-scanning-bunch-of-records/10175/10 "2023-05-05T20:05:30Z")

</div>

I stand corrected. When all operations are write operations, the as\_record argument can be NULL. You should still allocate ops closer to aerospike\_key\_operate() to avoid leaking when the function returns early.
