# Floating point exception in process status report



## sonyk (Sep 15, 2009)

Hi everybody, looking forward to receive a help regarding the problem below.
Recently 'ps' utility has crashed on one of servers that I work with. We are using custom BSD-based operating system, I'm not sure, but I think it's FreeBSD3 that our system is derived from. 

here is a part of code from ps/print.c:

```
double
getpmem(k)
	KINFO *k;
{
	static int failure;
	struct proc *p;
	struct eproc *e;
	double fracmem;
	int szptudot;

	if (!nlistread)
		failure = donlist();
	if (failure)
		return (0.0);

	p = KI_PROC(k);
	e = KI_EPROC(k);
	if ((p->p_flag & P_INMEM) == 0)
		return (0.0);
#ifndef NEWVM
	szptudot = UPAGES + clrnd(ctopt(p->p_dsize + p->p_ssize + e->e_xsize));
	fracmem = ((float)p->p_rssize + szptudot)/CLSIZE/mempages;
	if (p->p_textp && e->e_xccount)
		fracmem += ((float)e->e_xrssize)/CLSIZE/e->e_xccount/mempages;
#else
	/* XXX want pmap ptpages, segtab, etc. (per architecture) */
	szptudot = UPAGES;
	/* XXX don't have info about shared */
	fracmem = ((float)e->e_vm.vm_rssize + szptudot)/CLSIZE/mempages;
#endif
	return (100.0 * fracmem);
}
```

return (100.0 * fracmem); raised a floating point exception as I see in a crash dump, but I'm unable to see the value of fracmem and also I'm not a very proficient C programmer and I can't even suggest why floating point exception could have place here...

 getpmem(k) is called from pmem(k, ve):


```
void
pmem(k, ve)
	KINFO *k;
	VARENT *ve;
{
	VAR *v;

	v = ve->var;
	(void)printf("%*.1f", v->width, getpmem(k));
}
```

but pmem is called from ps/ps.c as a handler like it's described in ps/keyword.c:


```
VAR var[] = {
...
{"%mem", "%MEM", NULL, 0, pmem, 4},
...
}
```

I hope everything is described very precisely. Waiting for your comments, thanks in advance.


----------



## DutchDaemon (Sep 15, 2009)

This code is so old, it's not even funny 

This is the same code block in FreeBSD 8


```
static double
getpmem(KINFO *k)
static double
getpmem(KINFO *k)
{
        static int failure;
        double fracmem;

        if (!nlistread)
                failure = donlist();
        if (failure)
        if (failure)
                return (0.0);

        if ((k->ki_p->ki_flag & P_INMEM) == 0)
                return (0.0);
        /* XXX want pmap ptpages, segtab, etc. (per architecture) */
        /* XXX don't have info about shared */
        fracmem = ((float)k->ki_p->ki_rssize) / mempages;
        return (100.0 * fracmem);
}

void
pmem(KINFO *k, VARENT *ve)
{
        VAR *v;

        v = ve->var;
        (void)printf("%*.1f", v->width, getpmem(k));
}
```


----------



## sonyk (Sep 15, 2009)

Yes, I have already compared it with new one. But I still need answers. Why could floating point exception occur there? Is there a warranty that it will not occur in a newer version? It was a single occurrence, but in my case it is very undesirable to have a possibility of one occurrence. And if we are talking about how old my code is... Could you please tell about differences and difficulties that I may face if I upgrade only 'ps' utility? Since I'm not very familiar with all BSD changes from 3-8 and having in mind that it's fully impossible to upgrade whole system version.


----------



## DutchDaemon (Sep 15, 2009)

FreeBSD (which is an integral OS) can not be upgraded in parts due to severe library changes, and certainly not over 5 major versions. FreeBSD 3 is _severely_ EOL, so hop over to at least FreeBSD 7 or live with the consequences, I'm afraid.


----------



## sonyk (Sep 15, 2009)

So you mean it's impossible to prevent another occurrence without updating all libraries?


----------



## DutchDaemon (Sep 15, 2009)

Let's say I have no idea why your ps utility started crashing 'recently' on only one of your servers, because you make it sound like this configuration has been static since the FreeBSD 3 days. I've never experienced FPE errors with ps, ever. Must be something introduced on that system, and recently.


----------



## sonyk (Sep 15, 2009)

But talking about C. What could be there to cause FPE? I can't find anywhere on internet the reasons for FPE in C.


----------



## DutchDaemon (Sep 15, 2009)

You may have more luck at one of the mailing lists, where most of the actual developers are (http://lists.freebsd.org/mailman/listinfo).


----------



## sonyk (Sep 15, 2009)

Okay, thanks. I'll post a reply later if I receive any assistance from developers.


----------



## sonyk (Sep 21, 2009)

finally, thanks to my team-mate, we were able to reproduce the bug. "ps -u /var", "ps u /sbin" made utility to crash with message: 


```
USER       PID %CPU %MEM   VSZ  RSS  TT  STAT STARTED       TIME COMMAND
ps: nlist: can't find following symbols: _fscale _ccpu _avail_start _avail_end
Floating point exception (core dumped)
```

maybe someone knows in what ps utility version this was fixed and what is the root of the issue ?


----------



## SirDice (Sep 21, 2009)

I'm by no means a programmer so I could very well be wrong..

Reading this: http://www.freebsd.org/cgi/man.cgi?...ion=3&manpath=FreeBSD+3.0-RELEASE&format=html

There are several options an FPE could occur. 

```
#define fp_except_t int
#define FP_X_INV	 0x01	   /* invalid */
#define FP_X_OFL	 0x08	   /* overflow */
#define FP_X_UFL	 0x10	   /* underflow */
#define FP_X_DZ	 0x04	   /* divide-by-zero */
#define FP_X_IMP	 0x20	   /* loss of precision */
#define FP_X_DNML	 0x02	   /* denormal */
```

Looking at where the error happened it could be an overflow.


----------



## sonyk (Sep 21, 2009)

"-v" raises the same exception. Something with formatting...


----------



## DutchDaemon (Sep 21, 2009)

What is the purpose of [cmd=]ps -u /var[/cmd], or am I missing something here?


----------



## sonyk (Sep 21, 2009)

No matter what you put after "u" or "v", any existing path you enter makes utility crash


----------



## SirDice (Sep 21, 2009)

Don't do it then. Seriously, both the -v and -u option don't have any options.


----------



## sonyk (Sep 21, 2009)

I know that i can live without doing it, but end user - can't. So I need to find and remove a breakable place.


----------



## DutchDaemon (Sep 21, 2009)

I don't know why anyone would need 
	
	



```
$ ps -u /var
ps: illegal argument: /var
```
It's a nonsensical command.


----------



## sonyk (Sep 21, 2009)

I now have looked through open/net/free BSD repositories for a "ps: nlist: can't find following symbols:" phrase, and looks like the problem is actual for NetBSD. I will look for version differences now.


----------



## SirDice (Sep 21, 2009)

You could have a look at the source via cvsweb. It'll give you nice annotated output on the things that have changed between versions.

http://www.freebsd.org/cgi/cvsweb.cgi/src/bin/ps/?f=h;only_with_tag=RELENG_3#dirlist


----------

