On Mon, Aug 24, 2009 at 2:15 AM, James Carlson<carls...@workingcode.com> wrote: > Peter Teoh wrote: >> Thank you James for the tip. >> >> Following your advice, and following the similar getpcstack()'s usage >> as example at: >> >> uts/common/os/policy.c >> >> I coded thus: >> >> 23 int _init(void) >> 24 { >> 25 int i, depth, status; >> 26 pc_t mystack[1024]; >> 27 char *sym; >> 28 ulong_t off; >> 29 >> 30 status = mod_install(&modlinkage); >> 31 cmn_err(CE_NOTE,"me filed\n"); >> 32 depth = getpcstack(mystack, 10); >> 33 for (i = 0; i < depth; i++) { >> 34 sym = kobj_getsymname((uintptr_t)mystack[i], >> &off); >> 35 cmn_err(CE_NOTE, "sym=%s %x %d\n", sym, >> (uintptr_t) myst >> ack[i], off); >> 36 } >> 37 return status; >> 38 } >> >> Technically is there any problem with this piece of code? > > You probably can't call this from _init, and it's possible that 'sym' > might be NULL. > > But those are nits. The real problem is "why do you want to do this at > all?" Dtrace can give you this sort of information and it doesn't > require hacking around with undocumented kernel interfaces. > > Another -- possibly simpler -- way to do this would be to introduce an > intentional error, like this: > > int _init(void) > { > *(int *)0 = 0; > return 0; > } > > That way, the system will panic, and you can explore the stack contents > to your heart's content. > > But I think the real question is why you're attempting to do this ... > without knowing that, it's hard to give useful advice. >
Thank you everyone for the answer. I rewrote the program (in summary) and got into new problem: int _init(void) { int status; status = mod_install(&modlinkage); if (status==0) mystack_info(); cmn_err(CE_NOTE,"my first module\n"); return status; } char *mykobj_getsymname(uintptr_t value, ulong_t *offset); char *mykobj_getsymname(uintptr_t value, ulong_t *offset) { char *name = NULL; struct modctl *modp; struct modctl_list *lp; struct module *mp; //Loop through the primary kernel modules. for (lp = kobj_lm_lookup(KOBJ_LM_PRIMARY); lp; lp = lp->modl_next) { mp = mod(lp); if ((name = kobj_searchsym(mp, value, offset)) != NULL) return (name); } return NULL; } int mystack_info(void) { int i, depth, status; pc_t mystack[MYMAX_SYM]; char *sym = NULL; ulong_t off; depth = getpcstack(&mystack[0], MYMAX_SYM); for (i = 0; i < MIN(depth, MYMAX_SYM); i++) { cmn_err(CE_CONT, "sym=%s %lx %lx\n", sym ? sym:"?", (uintptr_t) mystack[i], off); } } int _info(struct modinfo *modinfop) { return (mod_info (&modlinkage, modinfop)); } int _fini(void) { int i; i = mod_remove(&modlinkage); return i; } Notice the mykobj_getsymname() function - which called several kernel functions. And noticed that it is not called by any function as well. During modloading I got the error: can't load module: Invalid argument which I take it as error arising from the kernel module ELF loading process - as it cannot matched the import table from the kernel module with the exported symbol from the kernel. But if I remove the entire chunk of function - which is dead code anyway, the module is modloaded and executed successfully. Now therefore the puzzle is how and where to find out what are all the symbols which can be recognized and resolved by the kernel loader? And moreover, kobj_getsymname() is resolved but CANNOT be called inside the _init(), as it will lead to system hang. But kobj_getsymvalue() can be called inside _init() and output its value into dmesg. I wished all these can be made more explicit, or automatic, if not at the modloading stage, then a bug check done inside kobj_getsymname() to make sure the necessary locks are held, to prevent unnecessary system hang. Just my 2cts suggestion :-). Or have I missed some other points? Thanks. -- Regards, Peter Teoh _______________________________________________ opensolaris-code mailing list opensolaris-code@opensolaris.org http://mail.opensolaris.org/mailman/listinfo/opensolaris-code