Skip to content

Commit

Permalink
[DEBUG-ONLY] Enhance jb->blocked assert in jnl_write.c to account for…
Browse files Browse the repository at this point in the history
… defunct processes

If the process id corresponding to jb->blocked was abnormally killed (e.g. kill -9), it is possible
the process is still alive but in a defunct state (when another process comes into jnl_write.c
after having salvaged crit etc.) if the parent process has not yet done a waitpid() on this abnormally
terminated child. In that case, the following assert would fail.

    266     assert((!jb->blocked) || (FALSE == is_proc_alive(jb->blocked, 0)));

This is now addressed by using the new is_defunct_pid() function in the assert.
  • Loading branch information
nars1 committed Jun 25, 2019
1 parent 286909e commit 6d1d010
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
9 changes: 7 additions & 2 deletions sr_port/jnl_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "buddy_list.h" /* needed for tp.h */
#include "hashtab_int4.h" /* needed for tp.h */
#include "tp.h"
#include "is_defunct_pid.h"
#endif

GBLREF uint4 process_id;
Expand Down Expand Up @@ -122,6 +123,7 @@ void jnl_write(jnl_private_control *jpc, enum jnl_record_type rectype, jnl_recor
char *mumps_node_ptr;
struct_jrec_align *align_rec;
uint4 end_freeaddr;
int4 blocking_pid;
# endif

assert(MAX_JNL_WRITE_RECURSION_DEPTH > jnl_write_recursion_depth++);
Expand Down Expand Up @@ -262,8 +264,11 @@ void jnl_write(jnl_private_control *jpc, enum jnl_record_type rectype, jnl_recor
ADJUST_CHECKSUM(checksum, csd->jnl_checksum, checksum);
SET_JREC_CHECKSUM(jnl_rec, rectype, checksum);
if (!in_phase2)
{
assert((!jb->blocked) || (FALSE == is_proc_alive(jb->blocked, 0)));
{ /* Check that the pid in jb->blocked is dead if it is not 0. The check handles the case that a pid could be dead
* but its parent could still have not gotten its exit status in which case it could be a defunct.
*/
DEBUG_ONLY(blocking_pid = jb->blocked);
assert(!blocking_pid || is_defunct_pid((uint4)blocking_pid) || (FALSE == is_proc_alive(blocking_pid, 0)));
jb->blocked = process_id;
}
jnl_fs_block_size = jb->fs_block_size;
Expand Down
63 changes: 63 additions & 0 deletions sr_unix/is_defunct_pid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/****************************************************************
* *
* Copyright (c) 2019 YottaDB LLC and/or its subsidiaries. *
* All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/

#include "mdef.h"

#include "gtm_stdio.h"

#include "is_defunct_pid.h"

#ifdef DEBUG
GBLREF uint4 process_id;
#endif

/* ----------------------------------------------
* Check if input pid is a defunct process (zombie)
*
* Arguments:
* pid - process ID
*
* Return:
* TRUE - If process is a defunct process (i.e. shows up as <defunct> in ps -ef listing)
* FALSE - Otherwise
* ----------------------------------------------
*/

boolean_t is_defunct_pid(int4 pid)
{
int status;
char procfilename[64];
boolean_t is_defunct;
FILE *fp;
char pidstate;

assert(0 != pid);
assert(process_id != pid);
is_defunct = FALSE; /* by default it is not a defunct process */
# ifdef __linux__
/* open the /proc/<pid>/stat file */
SNPRINTF(procfilename, sizeof(procfilename), "/proc/%d/stat", (int)pid);
fp = fopen(procfilename, "r");
if (NULL != fp)
{
fscanf(fp, "%*d %*s %c", &pidstate);
is_defunct = ('Z' == pidstate);
fclose(fp);
}
# else
/* This is likely MacOS or Cygwin. Those ports need to implement this functionality using other methods
* (maybe do a "system" call with a "ps -ef | grep defunct" if nothing else is possible).
*/
# error unsupported platform
# endif
return is_defunct;
}
18 changes: 18 additions & 0 deletions sr_unix/is_defunct_pid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/****************************************************************
* *
* Copyright (c) 2019 YottaDB LLC and/or its subsidiaries. *
* All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/

#ifndef IS_DEFUNCT_PID_INCLUDED
#define IS_DEFUNCT_PID_INCLUDED

boolean_t is_defunct_pid(int4 pid);

#endif /* IS_DEFUNCT_PID_INCLUDED */

0 comments on commit 6d1d010

Please sign in to comment.