Segmentation fault when adding user metadata

Please provide complete information as applicable to your setup.

• Hardware Platform (Jetson / GPU): Jetson AGX Xavier
• DeepStream Version: 5.0
• JetPack Version (valid for Jetson only): 4.4.1
• TensorRT Version: 7.1.3
• NVIDIA GPU Driver Version (valid for GPU only)
• Issue Type( questions, new requirements, bugs): questions,

I refer to deepstream-user-metadata-test app to add metadata to each frame, bellow are the code extract:

/* {Attach metadata to frame API*/
#define NVDS_USER_FRAME_META_EXAMPLE (nvds_get_user_meta_type("NVIDIA.NVINFER.USER_META"))
#define USER_ARRAY_SIZE 16

void *set_metadata_ptr(void);
static gpointer copy_user_meta(gpointer data, gpointer user_data);
static void release_user_meta(gpointer data, gpointer user_data);

void *set_metadata_ptr()
{
  int i = 0;
  gchar *user_metadata = (gchar*)g_malloc0(USER_ARRAY_SIZE);

  g_print("\n**************** Setting user metadata array of 16 on nvinfer src pad\n");
  for(i = 0; i < USER_ARRAY_SIZE; i++) {
    user_metadata[i] = rand() % 255;
    g_print("user_meta_data [%d] = %d\n", i, user_metadata[i]);
  }
  return (void *)user_metadata;
}

/* copy function set by user. "data" holds a pointer to NvDsUserMeta*/
static gpointer copy_user_meta(gpointer data, gpointer user_data)
{
  NvDsUserMeta *user_meta = (NvDsUserMeta *)data;
  gchar *src_user_metadata = (gchar*)user_meta->user_meta_data;
  gchar *dst_user_metadata = (gchar*)g_malloc0(USER_ARRAY_SIZE);
  memcpy(dst_user_metadata, src_user_metadata, USER_ARRAY_SIZE);
  return (gpointer)dst_user_metadata;
}

/* release function set by user. "data" holds a pointer to NvDsUserMeta*/
static void release_user_meta(gpointer data, gpointer user_data)
{
  NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
  if(user_meta->user_meta_data) {
    g_free(user_meta->user_meta_data);
    user_meta->user_meta_data = NULL;
  }
}

static GstPadProbeReturn
attach_metadata_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer u_data)
{
  GstBuffer *buf = (GstBuffer *) info->data;
  NvDsMetaList * l_frame = NULL;
  NvDsUserMeta *user_meta = NULL;
  NvDsMetaType user_meta_type = NVDS_USER_FRAME_META_EXAMPLE;

  NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);

    for (l_frame = batch_meta->frame_meta_list; l_frame != NULL;
      l_frame = l_frame->next) {
        NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);

        /* Acquire NvDsUserMeta user meta from pool */
        user_meta = nvds_acquire_user_meta_from_pool(batch_meta);

        /* Set NvDsUserMeta below */
        user_meta->user_meta_data = (void *)set_metadata_ptr();
        user_meta->base_meta.meta_type = user_meta_type;
        user_meta->base_meta.copy_func = (NvDsMetaCopyFunc)copy_user_meta;
        user_meta->base_meta.release_func = (NvDsMetaReleaseFunc)release_user_meta;

        /* We want to add NvDsUserMeta to frame level */
        nvds_add_user_meta_to_frame(frame_meta, user_meta);
    }
    return GST_PAD_PROBE_OK;
}
/* Attach metadata to frame API} */ 

// create live source bin
static GstElement *
create_live_source_bin(guint index, gboolean basler, pipeline_config p_config, latency_measure *latency_measure, gboolean add_probe)
{
    GstElement *bin = NULL,
               *source = NULL,
               *vidconv = NULL,
               *nvvidconv = NULL,
               *cap_filter1 = NULL,
               *cap_filter2 = NULL;
    GstPad *real_pad, *ghost_pad;
    GstCaps *caps1, *caps2 = NULL;

    /* Create a source GstBin to abstract this bin's content from the rest of the pipeline */
    gchar bin_name[16] = {};
    g_snprintf(bin_name, 15, "source-bin-%02d", index);
    bin = gst_bin_new(bin_name);

    /* Create elements in the bin */
    if (basler)
    {
        source = gst_element_factory_make("pylonsrc", "camera");
        if (!bin || !source)
        {
            g_printerr("One element in source bin could not be created.\n");
            return NULL;
        }

        g_object_set(G_OBJECT(source),
                     "camera", index,
                     "imageformat", "rgb8",
                     "width", p_config.camera_output_width,
                     "height", p_config.camera_output_height,
                     "continuous", p_config.basler_continuous,
                     NULL);
    }
    else
    {
        source = gst_element_factory_make("v4l2src", "camera");
        cap_filter1 = gst_element_factory_make("capsfilter", "cap_filter1");

        if (!bin || !source || !cap_filter1)
        {
            g_printerr("One element in source bin could not be created.\n");
            return NULL;
        }

        gchar device_name[16] = {};
        g_snprintf(device_name, 15, "/dev/video%d", index);
        g_object_set(G_OBJECT(source), "device", device_name, NULL);

        // we need this cap for v4l2src so that it capture video at our specified config
        caps1 = gst_caps_from_string("video/x-raw, width=640, height=480, framerate=30/1");
        g_object_set(G_OBJECT(cap_filter1), "caps", caps1, NULL);
        gst_caps_unref(caps1);
    }

    vidconv = gst_element_factory_make("videoconvert", "vidconv");
    nvvidconv = gst_element_factory_make("nvvideoconvert", "nvvidconv");
    cap_filter2 = gst_element_factory_make("capsfilter", "cap_filter2");

    if (!vidconv || !nvvidconv || !cap_filter2)
    {
        g_printerr("One element in source bin could not be created.\n");
        return NULL;
    }

    /* Set elements properties */
    g_object_set(G_OBJECT(nvvidconv), "nvbuf-memory-type", 0, NULL);

    caps2 = gst_caps_from_string("video/x-raw(memory:NVMM), format=NV12");
    g_object_set(G_OBJECT(cap_filter2), "caps", caps2, NULL);
    gst_caps_unref(caps2);

    if (basler)
    {
        /* Add elements to the bin */
        gst_bin_add_many(GST_BIN(bin), source, vidconv, nvvidconv, cap_filter2, NULL);

        /* Link elements in the bin*/
        if (!gst_element_link_many(source, vidconv, nvvidconv, cap_filter2, NULL))
        {
            g_printerr("One element in source bin could not be linked.\n");
            return NULL;
        }
    }
    else
    {
        /* Add elements to the bin */
        gst_bin_add_many(GST_BIN(bin), source, cap_filter1, vidconv, nvvidconv, cap_filter2, NULL);

        /* Link elements in the bin*/
        if (!gst_element_link_many(source, cap_filter1, vidconv, nvvidconv, cap_filter2, NULL))
        {
            g_printerr("One element in source bin could not be linked.\n");
            return NULL;
        }
    }

    // add user metadata probe
    if(add_probe){
        GstPad *start_probe_pad = gst_element_get_static_pad(source, "src");
        if (!start_probe_pad)
        {
            g_print("Unable to get source pad\n");
        }
        else
        {   
            gst_pad_add_probe(start_probe_pad, GST_PAD_PROBE_TYPE_BUFFER, attach_metadata_buffer_probe, NULL, NULL);
        }
        gst_object_unref(start_probe_pad);
    }

    /* We need to create a ghost pad for the bin, 
  since this is a source bin, the ghost pad acts as 
  a proxy of the source pad of the last element in the bin
  */
    real_pad = gst_element_get_static_pad(cap_filter2, "src");
    ghost_pad = gst_ghost_pad_new("src", real_pad);
    gst_pad_set_active(ghost_pad, TRUE);
    if (!gst_element_add_pad(bin, ghost_pad))
    {
        g_printerr("Failed to add ghost pad in source bin\n");
        return NULL;
    }
    gst_object_unref(real_pad);

    return bin;
}

// inside main()
     /* Set up source bins (must done this after streammux is added to the pipeline) */
    for (guint i = 0; i < num_sources; i++)
    {
        GstElement *source_bin = NULL;
        if (live_src)
        {
            source_bin = create_live_source_bin(i, basler, p_config, g_ptr_array_index(p_config.latency_measure, i), TRUE);
        }
        else if (image_src)
        {
            source_bin = create_multifile_source_bin(i);
        }
        else
        {
            g_printerr("Unsupported source. Exiting.\n");
        }

        if (!source_bin)
        {
            g_printerr("Failed to create source bin. Exiting.\n");
            return EXIT_FAILURE;
        }

        // add each source bin to the pipeline
        gst_bin_add(GST_BIN(pipeline), source_bin);

        // manually link streammux to each source bin
        GstPad *sinkpad, *srcpad;
        gchar pad_name[16] = {};
        g_snprintf(pad_name, 15, "sink_%u", i);
        sinkpad = gst_element_get_request_pad(streammux, pad_name);
        if (!sinkpad)
        {
            g_printerr("Streammux request sink pad failed. Exiting.\n");
            return EXIT_FAILURE;
        }

        srcpad = gst_element_get_static_pad(source_bin, "src");
        if (!srcpad)
        {
            g_printerr("Failed to get src pad of source bin. Exiting.\n");
            return EXIT_FAILURE;
        }

        if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK)
        {
            g_printerr("Failed to link source bin to stream muxer. Exiting.\n");
            return EXIT_FAILURE;
        }

        gst_object_unref(srcpad);
        gst_object_unref(sinkpad);
    }

image from dot file:

When I attached attach_metadata_buffer_probe to the src pad of the source element of each source bin, I got Segmentation fault (core dumped). Any advice on how to solve this error?

Hey, I think you should refer MetaData in the DeepStream SDK — DeepStream 5.1 Release documentation if you want to add user meta before nvstreammux