rigol-ds: free memory that was allocated by SCPI get routines
authorGerhard Sittig <gerhard.sittig@gmx.net>
Sun, 16 May 2021 12:48:42 +0000 (14:48 +0200)
committerGerhard Sittig <gerhard.sittig@gmx.net>
Sat, 22 May 2021 06:06:58 +0000 (08:06 +0200)
The SCPI get routines may allocate memory for response data which
callers have to free after use.

The approach to release allocated memory is simlar or identical to the
corresponding parts of pull request 95, in an attempt to get the reported
leak fixes in, yet reduce the potential for conflicts where this commit
deviates from the PR. Most work was done by Ralf. Thank you!

This addresses part of bug #1683.

Submitted-By: Reported-By: Ralf <jr-oss@gmx.net>
Tested-By: Reported-By: Ralf <jr-oss@gmx.net>
src/hardware/rigol-ds/protocol.c

index 201e0a31b920d6761c6c7104e01a52e14e3431cd..6d6b28f23789615d2292ba7c3ef583c44dc8f0f5 100644 (file)
@@ -106,7 +106,7 @@ static void rigol_ds_set_wait_event(struct dev_context *devc, enum wait_events e
  */
 static int rigol_ds_event_wait(const struct sr_dev_inst *sdi, char status1, char status2)
 {
-       char *buf;
+       char *buf, c;
        struct dev_context *devc;
        time_t start;
 
@@ -133,7 +133,9 @@ static int rigol_ds_event_wait(const struct sr_dev_inst *sdi, char status1, char
 
                        if (sr_scpi_get_string(sdi->conn, ":TRIG:STAT?", &buf) != SR_OK)
                                return SR_ERR;
-               } while (buf[0] == status1 || buf[0] == status2);
+                       c = buf[0];
+                       g_free(buf);
+               } while (c == status1 || c == status2);
 
                devc->wait_status = 2;
        }
@@ -146,7 +148,9 @@ static int rigol_ds_event_wait(const struct sr_dev_inst *sdi, char status1, char
 
                        if (sr_scpi_get_string(sdi->conn, ":TRIG:STAT?", &buf) != SR_OK)
                                return SR_ERR;
-               } while (buf[0] != status1 && buf[0] != status2);
+                       c = buf[0];
+                       g_free(buf);
+               } while (c != status1 && c != status2);
 
                rigol_ds_set_wait_event(devc, WAIT_NONE);
        }
@@ -266,7 +270,7 @@ static int rigol_ds_block_wait(const struct sr_dev_inst *sdi)
        char *buf;
        struct dev_context *devc;
        time_t start;
-       int len;
+       int len, ret;
 
        if (!(devc = sdi->priv))
                return SR_ERR;
@@ -292,8 +296,9 @@ static int rigol_ds_block_wait(const struct sr_dev_inst *sdi)
                        /* "READ,nnnn" (still working) or "IDLE,nnnn" (finished) */
                        if (sr_scpi_get_string(sdi->conn, ":WAV:STAT?", &buf) != SR_OK)
                                return SR_ERR;
-
-                       if (parse_int(buf + 5, &len) != SR_OK)
+                       ret = parse_int(buf + 5, &len);
+                       g_free(buf);
+                       if (ret != SR_OK)
                                return SR_ERR;
                } while (buf[0] == 'R' && len < (1000 * 1000));
        }
@@ -334,6 +339,7 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi)
        gchar *trig_mode;
        unsigned int num_channels, i, j;
        int buffer_samples;
+       int ret;
 
        if (!(devc = sdi->priv))
                return SR_ERR;
@@ -366,7 +372,9 @@ SR_PRIV int rigol_ds_capture_start(const struct sr_dev_inst *sdi)
                                return SR_ERR;
                        if (sr_scpi_get_string(sdi->conn, ":TRIG:MODE?", &trig_mode) != SR_OK)
                                return SR_ERR;
-                       if (rigol_ds_config_set(sdi, ":TRIG:%s:SWE SING", trig_mode) != SR_OK)
+                       ret = rigol_ds_config_set(sdi, ":TRIG:%s:SWE SING", trig_mode);
+                       g_free(trig_mode);
+                       if (ret != SR_OK)
                                return SR_ERR;
                        if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
                                return SR_ERR;
@@ -935,6 +943,8 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi)
        /* Coupling. */
        for (i = 0; i < devc->model->analog_channels; i++) {
                cmd = g_strdup_printf(":CHAN%d:COUP?", i + 1);
+               g_free(devc->coupling[i]);
+               devc->coupling[i] = NULL;
                res = sr_scpi_get_string(sdi->conn, cmd, &devc->coupling[i]);
                g_free(cmd);
                if (res != SR_OK)
@@ -945,6 +955,8 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi)
                sr_dbg("CH%d %s", i + 1, devc->coupling[i]);
 
        /* Trigger source. */
+       g_free(devc->trigger_source);
+       devc->trigger_source = NULL;
        if (sr_scpi_get_string(sdi->conn, ":TRIG:EDGE:SOUR?", &devc->trigger_source) != SR_OK)
                return SR_ERR;
        sr_dbg("Current trigger source %s", devc->trigger_source);
@@ -956,6 +968,8 @@ SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi)
        sr_dbg("Current horizontal trigger position %g", devc->horiz_triggerpos);
 
        /* Trigger slope. */
+       g_free(devc->trigger_slope);
+       devc->trigger_slope = NULL;
        if (sr_scpi_get_string(sdi->conn, ":TRIG:EDGE:SLOP?", &devc->trigger_slope) != SR_OK)
                return SR_ERR;
        sr_dbg("Current trigger slope %s", devc->trigger_slope);