Package: conky
Version: 1.10.6-1.1bds
Severity: important
Tags: patch

This patch corrects a segfault (and general instability) associated with
CPU monitoring $cpugraph, $cpubar, and related load monitoring
directives that occurred when the kernel reports a non-sequential list
of CPU indices on an SMP system.

This is a new bug that arrived with the 'stretch' version of conky.

For example, "/sys/devices/system/cpu/present" for my AMD FX(tm)-6350
Six-Core Processor reports "0,3-7" (stock debian kernel 4.9.0-3-amd64 ).
I assume that chip is really an 8-core die with two cores disabled...
Presumably you could also get "0,3-4,6", and other combos too.

This bug and patch has also been reported upstream:
  https://github.com/brndnmtthws/conky/pull/416

This may be the same problem reported in Bug #863144: "conky: seqfaults"

-- Brad

-- System Information:
Debian Release: 9.1
  APT prefers stable
  APT policy: (900, 'stable'), (80, 'unstable'), (60, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.9.0-3-amd64 (SMP w/6 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)

Versions of packages conky depends on:
ii  conky-all  1.10.6-1

conky recommends no packages.

conky suggests no packages.

-- no debconf information
From d3065426868cdf63ccbbaf6afd917de64403ae49 Mon Sep 17 00:00:00 2001
From: Brad Sawatzky <brad+deb...@swatter.net>
Date: Sun, 27 Aug 2017 16:10:48 -0400
Subject: [PATCH] Fix segfault when kernel reports non-sequential SMP CPU
 indices

- For an AMD FX(tm)-6350 Six-Core Processor the file '/sys/.../present'
  reports "0,3-7".  I assume that chip is really an 8-core die with two
  cores disabled...  Presumably you could also get "0,3-4,6", and other
  combos too...
---
 src/linux.cc | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/linux.cc b/src/linux.cc
index 664ddf5e..5ebed315 100644
--- a/src/linux.cc
+++ b/src/linux.cc
@@ -801,8 +801,11 @@ void get_cpu_count(void)
 {
 	FILE *stat_fp;
 	static int rep = 0;
-	int highest_cpu_index;
 	char buf[256];
+	char *str1, *str2, *token, *subtoken;
+	char *saveptr1, *saveptr2;
+	int subtoken1=-1;
+	int subtoken2=-1;
 
 	if (info.cpu_usage) {
 		return;
@@ -819,11 +822,30 @@ void get_cpu_count(void)
 			break;
 		}
 
-		if (sscanf(buf, "%*d-%d", &highest_cpu_index) == 1) {
-			info.cpu_count = highest_cpu_index;
+		// Do some parsing here to handle skipped cpu numbers.  For example,
+		// for an AMD FX(tm)-6350 Six-Core Processor /sys/.../present reports
+		// "0,3-7".  I assume that chip is really an 8-core die with two cores
+		// disabled...  Presumably you could also get "0,3-4,6", and other
+		// combos too...
+		for (str1 = buf; ; str1 = NULL) {
+			token = strtok_r(str1, ",", &saveptr1);
+			if (token == NULL) break;
+			++info.cpu_count;
+
+			subtoken1=-1;
+			subtoken2=-1;
+			for (str2 = token; ; str2 = NULL) {
+				subtoken = strtok_r(str2, "-", &saveptr2);
+				if (subtoken == NULL) break;
+				if(subtoken1 < 0)
+					subtoken1=atoi(subtoken);
+				else
+					subtoken2=atoi(subtoken);
+			}
+			if(subtoken2 > 0)
+				info.cpu_count += subtoken2 - subtoken1;
 		}
 	}
-	++info.cpu_count;
 	info.cpu_usage = (float*)malloc((info.cpu_count + 1) * sizeof(float));
 
 	fclose(stat_fp);
@@ -896,7 +918,7 @@ int update_stat(void)
 		} else if (strncmp(buf, "cpu", 3) == 0) {
 			double delta;
 			if (isdigit(buf[3])) {
-				idx = atoi(&buf[3]) + 1;
+				idx++;  //just increment here since the CPU index can skip numbers
 			} else {
 				idx = 0;
 			}
-- 
2.11.0

Reply via email to