diff -Naurp pcp-4.3.2.orig/qa/1820 pcp-4.3.2/qa/1820
--- pcp-4.3.2.orig/qa/1820 1970-01-01 10:00:00.000000000 +1000
+++ pcp-4.3.2/qa/1820 2020-11-04 11:14:36.844349843 +1100
@@ -0,0 +1,40 @@
+#!/bin/sh
+# PCP QA Test No. 1820
+# Exercise memory allocation bug in pcp-atopsar(1).
+#
+# Copyright (c) 2020 Red Hat. All Rights Reserved.
+#
+
+seq=`basename $0`
+if [ $# -eq 0 ]
+then
+ echo "QA output created by $seq"
+else
+ echo "QA output created by $seq $*"
+fi
+
+# get standard environment, filters and checks
+. ./common.product
+. ./common.filter
+. ./common.check
+
+[ -f $PCP_BINADM_DIR/pcp-atopsar ] || _notrun "system monitoring tools not installed"
+
+_cleanup()
+{
+ cd $here
+ $sudo rm -rf $tmp $tmp.*
+}
+
+status=1 # failure is the default!
+$sudo rm -rf $tmp $tmp.* $seq.full
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# real QA test starts here
+export PCP_HOSTZONE=1
+export PCP_ARCHIVE=$here/archives/pcp-atop-log
+$PCP_BINADM_DIR/pcp-atopsar -x -R 5 2 10
+
+# success, all done
+status=0
+exit
diff -Naurp pcp-4.3.2.orig/qa/1820.out pcp-4.3.2/qa/1820.out
--- pcp-4.3.2.orig/qa/1820.out 1970-01-01 10:00:00.000000000 +1000
+++ pcp-4.3.2/qa/1820.out 2020-11-04 11:14:36.844349843 +1100
@@ -0,0 +1,14 @@
+QA output created by 1820
+
+ 2020/07/20
+
+-------------------------- analysis date: 2013/09/26 --------------------------
+
+16:14:15 cpu %usr %nice %sys %irq %softirq %steal %guest %wait %idle _cpu_
+
+16:14:19 cpu %usr %nice %sys %irq %softirq %steal %guest %wait %idle _cpu_
+16:14:27 all 23 0 8 2 1 0 0 3 363
+ 0 5 3 1 4 4 3 3 4 75
+ 1 10 6 8 6 6 6 6 6 52
+ 2 11 6 8 6 6 6 6 6 51
+ 3 11 6 7 6 6 6 6 6 52
diff -Naurp pcp-4.3.2.orig/qa/group pcp-4.3.2/qa/group
--- pcp-4.3.2.orig/qa/group 2020-11-04 11:11:00.757951890 +1100
+++ pcp-4.3.2/qa/group 2020-11-04 11:14:57.290103639 +1100
@@ -1680,4 +1680,5 @@ BAD
1622 selinux local
1644 pmda.perfevent local
1671 multi-archive archive libpcp pmlogextract pmlogcheck pmdumplog local
+1820 atop local
4751 libpcp threads valgrind local pcp python
diff -Naurp pcp-4.3.2.orig/src/pcp/atop/deviate.c pcp-4.3.2/src/pcp/atop/deviate.c
--- pcp-4.3.2.orig/src/pcp/atop/deviate.c 2020-11-04 11:11:00.762951830 +1100
+++ pcp-4.3.2/src/pcp/atop/deviate.c 2020-11-04 11:14:36.846349819 +1100
@@ -7,7 +7,7 @@
** This source-file contains functions to calculate the differences for
** the system-level and process-level counters since the previous sample.
**
-** Copyright (C) 2015,2017,2019 Red Hat.
+** Copyright (C) 2015,2017,2019-2020 Red Hat.
** Copyright (C) 2000-2010 Gerlof Langeveld
**
** This program is free software; you can redistribute it and/or modify it
@@ -1220,6 +1220,7 @@ deviatsyst(struct sstat *cur, struct sst
pre->nfs.nfsmounts.nfsmnt[j].pagesmwrite);
}
+ dev->nfs.nfsmounts.nfsmnt[i].mountdev[0] = '\0';
dev->nfs.nfsmounts.nrmounts = cur->nfs.nfsmounts.nrmounts;
/*
@@ -1227,7 +1228,7 @@ deviatsyst(struct sstat *cur, struct sst
*/
if (cur->cfs.nrcontainer != dev->cfs.nrcontainer)
{
- size = (cur->cfs.nrcontainer + 1) * sizeof(struct percontainer);
+ size = cur->cfs.nrcontainer * sizeof(struct percontainer);
dev->cfs.cont = (struct percontainer *)realloc(dev->cfs.cont, size);
ptrverify(dev->cfs.cont, "deviatsyst cont [%ld]\n", (long)size);
}
@@ -1283,6 +1284,12 @@ deviatsyst(struct sstat *cur, struct sst
** application-specific counters
** calculate deviations for GPUs
*/
+ if (cur->gpu.nrgpus != dev->gpu.nrgpus)
+ {
+ size = cur->gpu.nrgpus * sizeof(struct pergpu);
+ dev->gpu.gpu = (struct pergpu *)realloc(dev->gpu.gpu, size);
+ ptrverify(dev->gpu.gpu, "deviatsyst gpu [%ld]\n", (long)size);
+ }
for (i=0; i < cur->gpu.nrgpus; i++)
{
dev->gpu.gpu[i].gpunr = i;
@@ -1325,6 +1332,12 @@ deviatsyst(struct sstat *cur, struct sst
/*
** calculate deviations for InfiniBand
*/
+ if (cur->ifb.nrports != dev->ifb.nrports)
+ {
+ size = (cur->ifb.nrports + 1) * sizeof(struct perifb);
+ dev->ifb.ifb = (struct perifb *)realloc(dev->ifb.ifb, size);
+ ptrverify(dev->ifb.ifb, "deviatsyst ifb [%ld]\n", (long)size);
+ }
for (i=0; i < cur->ifb.nrports; i++)
{
strcpy(dev->ifb.ifb[i].ibname, cur->ifb.ifb[i].ibname);
@@ -1343,6 +1356,7 @@ deviatsyst(struct sstat *cur, struct sst
pre->ifb.ifb[i].sndp;
}
+ dev->ifb.ifb[i].ibname[0] = '\0';
dev->ifb.nrports = cur->ifb.nrports;
/*
@@ -1374,6 +1388,7 @@ totalsyst(char category, struct sstat *n
{
register int i;
count_t *ctot, *cnew;
+ size_t size;
switch (category)
{
@@ -1393,6 +1408,13 @@ totalsyst(char category, struct sstat *n
tot->cpu.all.steal += new->cpu.all.steal;
tot->cpu.all.guest += new->cpu.all.guest;
+ if (tot->cpu.nrcpu < new->cpu.nrcpu || !tot->cpu.cpu)
+ {
+ size = new->cpu.nrcpu * sizeof(struct percpu);
+ tot->cpu.cpu = realloc(tot->cpu.cpu, size);
+ ptrverify(tot->cpu.cpu, "totalsyst cpus [%ld]", (long)size);
+ }
+
if (new->cpu.nrcpu == 1)
{
tot->cpu.cpu[0] = tot->cpu.all;
@@ -1537,6 +1559,13 @@ totalsyst(char category, struct sstat *n
tot->net.tcp.MaxConn = new->net.tcp.MaxConn;
tot->net.tcp.CurrEstab = new->net.tcp.CurrEstab;
+ if (tot->intf.nrintf < new->intf.nrintf || !tot->intf.intf)
+ {
+ size = (new->intf.nrintf + 1) * sizeof(struct perintf);
+ tot->intf.intf = realloc(tot->intf.intf, size);
+ ptrverify(tot->intf.intf, "totalsyst intfs [%ld]", (long)size);
+ }
+
for (i=0; new->intf.intf[i].name[0]; i++)
{
/*
@@ -1603,6 +1632,13 @@ totalsyst(char category, struct sstat *n
break;
case 'd': /* accumulate disk-related counters */
+ if (tot->dsk.ndsk < new->dsk.ndsk || !tot->dsk.dsk)
+ {
+ size = (new->dsk.ndsk + 1) * sizeof(struct perdsk);
+ tot->dsk.dsk = realloc(tot->dsk.dsk, size);
+ ptrverify(tot->dsk.dsk, "totalsyst disks [%ld]", (long)size);
+ }
+
for (i=0; new->dsk.dsk[i].name[0]; i++)
{
strcpy(tot->dsk.dsk[i].name, new->dsk.dsk[i].name);
@@ -1618,6 +1654,13 @@ totalsyst(char category, struct sstat *n
tot->dsk.dsk[i].name[0] = '\0';
tot->dsk.ndsk = i;
+ if (tot->dsk.nlvm < new->dsk.nlvm || !tot->dsk.lvm)
+ {
+ size = (new->dsk.nlvm + 1) * sizeof(struct perdsk);
+ tot->dsk.lvm = realloc(tot->dsk.lvm, size);
+ ptrverify(tot->dsk.lvm, "totalsyst LVs [%ld]", (long)size);
+ }
+
for (i=0; new->dsk.lvm[i].name[0]; i++)
{
strcpy(tot->dsk.lvm[i].name, new->dsk.lvm[i].name);
@@ -1633,6 +1676,13 @@ totalsyst(char category, struct sstat *n
tot->dsk.lvm[i].name[0] = '\0';
tot->dsk.nlvm = i;
+ if (tot->dsk.nmdd < new->dsk.nmdd || !tot->dsk.mdd)
+ {
+ size = (new->dsk.nmdd + 1) * sizeof(struct perdsk);
+ tot->dsk.mdd = realloc(tot->dsk.mdd, size);
+ ptrverify(tot->dsk.mdd, "totalsyst MDs [%ld]", (long)size);
+ }
+
for (i=0; new->dsk.mdd[i].name[0]; i++)
{
strcpy(tot->dsk.mdd[i].name, new->dsk.mdd[i].name);