top: sl_int data type will be truncated on 32-bit architecture
Hi,recently, while using the top command on a Linux system, I noticed abnormal %CPU data. This is because the data read from the /proc/stat is stored in a signed int data type and gets truncated. Take a look at the source code below, some larger numbers are assigned to sl_int (which only occupies 32 bits on a 32-bit architecture).
static struct {
SET_t setsfunc; // the actual result setting routine
#ifdef ITEMTABLE_DEBUG
int enumnumb; // enumerator (must match position!)
char *enum2str; // enumerator name as a char* string
#endif
QSR_t sortfunc; // sort cmp func for a specific type
char *type2str; // the result type as a string value
} Item_table[] = {
...
{ RS(TIC_SUM_DELTA_USER), QS(sl_int), TS(sl_int) },
{ RS(TIC_SUM_DELTA_SYSTEM), QS(sl_int), TS(sl_int) },
{ RS(TIC_SUM_DELTA_IDLE), QS(sl_int), TS(sl_int) },
{ RS(TIC_SUM_DELTA_BUSY), QS(sl_int), TS(sl_int) },
{ RS(TIC_SUM_DELTA_TOTAL), QS(sl_int), TS(sl_int) },
...
};
I found that these data are stored in a union structure, occupying the same memory, so is it possible to change them all to unsigned long long?
struct stat_result {
enum stat_item item;
union {
- signed int s_int;
- signed long long sl_int;
- unsigned long ul_int;
unsigned long long ull_int;
} result;
};
or
struct stat_result {
enum stat_item item;
union {
signed int s_int;
- signed long sl_int;
- unsigned long ul_int;
+ signed long long sll_int;
+ unsigned int ul_int;
unsigned long long ull_int;
} result;
};
Edited by Alfred Wang