OpenSolaris

Printable Version Enter a New Search
Bug ID 4743353
Synopsis libumem's module fails to load on idle targets
State 10-Fix Delivered (Fix available in build)
Category:Subcategory utility:mdb
Keywords
Responsible Engineer Jonathan Adams
Reported Against s10_17
Duplicate Of
Introduced In
Commit to Fix snv_36
Fixed In snv_36
Release Fixed solaris_nevada(snv_36)
Related Bugs 4720206
Submit Date 6-September-2002
Last Update Date 17-February-2007
Description
% cat a.c
int
main()
{
        return (0);
}
% cc -o a a.c -lumem
% /usr/bin/mdb a
mdb: failed to read max_ncpus: unknown object file name
mdb: libumem.so.1 module failed to initialize
Loading modules: [ libc.so.1 ]
> 

Here's the offending chunk of code:

#define UMEM_READVAR(var) \
            (umem_readvar(&(var), #var) == -1 && \
            ((void) mdb_warn("failed to read "#var), 1))

int
umem_init(void)
{
        size_t pagesize;

        if (UMEM_READVAR(max_ncpus))
                return (-1);
        if (UMEM_READVAR(umem_stack_depth))
                return (-1);
        if (UMEM_READVAR(pagesize))
                return (-1);

        umem_pagesize = pagesize;

        if (umem_stack_depth > UMEM_MAX_STACK_DEPTH) {
                mdb_warn("umem_stack_depth corrupted (%d > %d)\n",
                    umem_stack_depth, UMEM_MAX_STACK_DEPTH);
                umem_stack_depth = 0;
        }
        return (0);
}

Since the process hasn't been initialized yet, the vread fails.

----

Ooo.  There's actually a bunch of problems here.  The implementation above
was made to make an easy transition from the kernel.  Unfortunately, when
the user process can change underneath, all kinds of problems start falling
out of the woodwork.  This is one, but additionally, if you:

* stop process before first malloc() call.  
* Load the umem module.  
* run process past first malloc() call.  
* Stop process
* Use umem dcmds.  

The module will not function correctly -- umem_stack_depth and max_ncpus change
during initialization.  To detect this, I think I'm going to want another 
umem_init state (to cover the difference between all tunables fixed and all vmem 
arenas/umem caches initialized).  But I'll still be stuck calling a check
function at the top of _every_ dcmd and walk_init.  Seems bad.

What would be nice is some way to register either:
1. a "program stopped" callback, or 
2. a "first use of module since a program state change" callback.

Either would make it so that we're not filling the module with endlessly
repetitive code, and might come in handy for other state-caching situations 
(i.e. ::findleaks)
---
As part of 

6226887 kmdb should load dmods at boot

the kmem module was updated to use a state change callback (which was 
added as part of kmdb).  We can just use this, and re-read all of our
global variables from the state change handler.
Work Around
N/A
Comments
N/A