lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Pall, Mike wrote:
> Solinsky, Jeff - PAL wrote:
> > It is crashing when main() returns, which I guess might mean
> > that there has been stack corruption?

> Umm, maybe. Or a special register (r2/r13) got corrupted?

> If it crashes for both a regular return from main() and for
> os.exit(), then this ought to be a problem in the process exit
> handling code in uClibc. Maybe set a breakpoint at the last
> instruction of main and step from then on. Not sure how much code
> follows.

exit() in uClibc directly calls 
  __uclibc_fini() calls the _rtld_fini function pointer
	(__rtld_fini)();

__rtld_fini is set as the last parameter passed to __uClibc_main() in crt1.S, which is a pointer passed from the linker apparently.  I printed the address being stored in rtld_fini when luajit starts, and I printed it again before it finally finally calls __rtld_fini.  The function address in __rtld_fini is the same as what it was when set to in __uClibc_main() on start.  

As previously stated, when jitted code is not executed it doesn't segfault when calling __rtld_fini() on exit, but after the jitter has run it segfaults.  I guess I need to put some more debug prints in the linker to see what that linker finish function is doing when it segfaults.  I'll post what I find, any guesses? 

In ld_so.c there is a function _dl_fini, which I think is the function passed to __uClibc_main().  It is a little harder for me to figure out from here since I can't sprinkle prints in the linker as it doesn't know about printf.  It may not help at all, but here is the dl_fini function from uClibc.

static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
{
  int i;
  struct elf_resolve * tpnt;

  for (i = 0; i < nlist; ++i) {
    tpnt = init_fini_list[i];
    if (tpnt->init_flag & FINI_FUNCS_CALLED)
      continue;
    tpnt->init_flag |= FINI_FUNCS_CALLED;
    _dl_run_fini_array(tpnt);
    if (tpnt->dynamic_info[DT_FINI]) {
	void (*dl_elf_func) (void);
      dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
      _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt >libname);
	DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
    }
  }
}

Tomorrow I will set the options to enable the _dl_if_debug_dprint() and sprinkle a bit of that to see what is going wrong.  I'm thinking more info is needed to make a good guess as to what is going wrong, as one of the addresses could have been clobbered; I wonder if the problem might still be related to the cache sync function in the kernel.  Would it do any good to post the powerpc assembly code I'm using to implement __kernel_sync_dicache()? It's basically a merge of what linux-2.6.29 was doing into the 2.6.20 kernel source we are using.

~ Jeff