Subject: | Ran into unknown state (hex char: 58) |
On modern Linux Proc::ProcessTable
occasionally gives following errors
(where occasionally is 1-2 times
out of 4000 runs with 10 seconds interval
on some average server; tested on 10 servers
with kernels 2.6.22 and 2.6.26):
1) Ran into unknown state (hex char: 58)
at /usr/local/bin/golem_process_queue.pl line 96.
and
2) Unknown data format type `3' returned from
OS_get_table at /usr/local/bin/golem_process_queue.pl line 96.
First problem is warning (perl program doesn't crash),
second problem is fatal (perl program crashes).
Second problem seems to depend on the first
(after fixing 1st I stopped seeing 2nd).
First problem comes from new process state
introduced in Linux since release of Proc::ProcessTable,
here's excerpt from fs/proc/array.c:
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char *task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"T (tracing stop)", /* 8 */
"Z (zombie)", /* 16 */
"X (dead)" /* 32 */
};
State code is 'X' which is exactly hex 58.
Attached patch adds 'X' processing and adds a bit
information to the "Unknown data format type" message
(which might aid debugging in the future
when second problem shows up).
Subject: | kohts-proc-processtable-dead-state.patch |
diff -ru Proc-ProcessTable-0.45.orig/ProcessTable.xs Proc-ProcessTable-0.45/ProcessTable.xs
--- Proc-ProcessTable-0.45.orig/ProcessTable.xs 2008-01-26 08:12:22.000000000 +0300
+++ Proc-ProcessTable-0.45/ProcessTable.xs 2010-02-10 13:08:24.000000000 +0300
@@ -146,7 +146,10 @@
}
myhash = newHV(); /* create a perl hash */
-
+
+ int j = 0;
+ char* format_start = format;
+
va_start(args, fields);
while( *format ){
key = *fields;
@@ -217,12 +220,13 @@
break;
default:
- croak("Unknown data format type `%c' returned from OS_get_table", *format);
+ croak("Unknown data format type `%c' returned from OS_get_table, position `%d'; string `%s'", *format, j, format_start);
va_end(args);
}
format++;
fields++;
+ j++;
}
/* objectify the hash */
diff -ru Proc-ProcessTable-0.45.orig/os/Linux.c Proc-ProcessTable-0.45/os/Linux.c
--- Proc-ProcessTable-0.45.orig/os/Linux.c 2008-09-08 19:10:41.000000000 +0400
+++ Proc-ProcessTable-0.45/os/Linux.c 2010-02-10 13:08:28.000000000 +0300
@@ -502,6 +502,9 @@
case 'T':
prs->state = get_string(STOP);
break;
+ case 'X':
+ prs->state = get_string(DEAD);
+ break;
/* unknown state, state is already set to NULL */
default:
ppt_warn("Ran into unknown state (hex char: %x)", (int) prs->state_c);
diff -ru Proc-ProcessTable-0.45.orig/os/Linux.h Proc-ProcessTable-0.45/os/Linux.h
--- Proc-ProcessTable-0.45.orig/os/Linux.h 2008-09-08 19:08:41.000000000 +0400
+++ Proc-ProcessTable-0.45/os/Linux.h 2010-02-10 13:08:26.000000000 +0300
@@ -56,6 +56,7 @@
DEFUNCT,
STOP,
UWAIT,
+ DEAD,
};
@@ -64,7 +65,7 @@
static const char strings[] =
{
/* process state */
- "sleep\0" "wait\0" "run\0" "idle\0" "defunct\0" "stop\0" "uwait\0"
+ "sleep\0" "wait\0" "run\0" "idle\0" "defunct\0" "stop\0" "uwait\0" "dead\0"
/* error messages */
"/proc unavailable\0"
"intilization failed\0"
@@ -116,55 +117,55 @@
static const size_t strings_index[] =
{
/* process status strings */
- 0, 6, 11, 15, 20, 28, 33,
+ 0, 6, 11, 15, 20, 28, 33, 39,
/* error messages */
- 39, 57,
+ 44, 62,
/* fields */
- 77,
- 81,
- 85,
- 89,
- 95,
- 100,
+ 82,
+ 86,
+ 90,
+ 94,
+ 99,
105,
110,
- 117,
- 123,
- 130,
- 138,
- 145,
- 153,
- 159,
- 165,
- 172,
- 179,
- 188,
- 194,
+ 115,
+ 122,
+ 128,
+ 135,
+ 143,
+ 150,
+ 158,
+ 164,
+ 170,
+ 177,
+ 184,
+ 193,
199,
- 203,
- 209,
+ 204,
+ 208,
214,
- 220,
- 226,
+ 219,
+ 225,
231,
236,
241,
246,
251,
256,
- 263,
- 270,
- 279,
+ 261,
+ 268,
+ 275,
284,
+ 289,
/* default format string (pre lower casing) */
- 288
+ 293
};
enum string_name {
/* NOTE: we start this enum at 7, so we can use still keep using the
* state enum, and have those correspond to the static strings */
/* error messages */
- STR_ERR_PROC_STATFS = 7,
+ STR_ERR_PROC_STATFS = 8,
STR_ERR_INIT,
/* fields */
STR_FIELD_UID,
@@ -250,41 +251,41 @@
static const char* const field_names[] =
{
- strings + 77,
- strings + 81,
- strings + 85,
- strings + 89,
- strings + 95,
+ strings + 82,
+ strings + 86,
+ strings + 90,
+ strings + 94,
strings + 100,
strings + 105,
strings + 110,
- strings + 117,
- strings + 123,
- strings + 130,
- strings + 138,
- strings + 145,
- strings + 153,
- strings + 159,
- strings + 165,
- strings + 172,
- strings + 179,
- strings + 188,
- strings + 194,
+ strings + 115,
+ strings + 122,
+ strings + 128,
+ strings + 135,
+ strings + 143,
+ strings + 150,
+ strings + 158,
+ strings + 164,
+ strings + 170,
+ strings + 177,
+ strings + 184,
+ strings + 193,
strings + 199,
- strings + 203,
- strings + 209,
+ strings + 204,
+ strings + 208,
strings + 214,
- strings + 220,
- strings + 226,
+ strings + 219,
+ strings + 225,
strings + 231,
strings + 236,
strings + 241,
strings + 246,
strings + 251,
strings + 256,
- strings + 263,
- strings + 270,
- strings + 279,
- strings + 284
+ strings + 261,
+ strings + 268,
+ strings + 275,
+ strings + 284,
+ strings + 289
};