Hi! I'm doing a port of some custom OS to usermode (x86/linux), just as usermode linux, with one of goals to use valgrind on it. To make some things simplier and explicit, it doesn't link with host's libc at now, but have some minimal subset (of libc) builtin.
I've faced a problem when running on valgrind, stack is not original one and signal arrived: " Can't extend stack during signal delivery for thread", and it segfaults. What's strange, by simple run or gdb it perfrom normally. I reproduced it with small program. I also noticied, when program is linked with libc, everything goes ok. Example is attached. It's like so: $ make # build two versions, with libc and bare one $ make TARGET=valgrind_test vg # run bare version, it will sleeps until killed with SIGCHLD (17). On signal it segfaults $ gbd valgrind_test (gdb) r # on SIGCHILD it exits normally $ make TARGET=valgrind_test_libc vg # run libc version, sleeps until SIGCHLD and exit ok. I also attach logs of my run. Valgrind with more debugging info was used (patch attached) So, the question is, what mechanism can be used to make bare version act like libc one? I've tried to do STACK_REGISTER, but it brought no success. I've tried valgrind 3.8.1 and svn r13380, all the same. With best regards, Anton
debug.patch
Description: Binary data
Makefile
Description: Binary data
#include <valgrind/valgrind.h> #ifdef LIBC #include <unistd.h> #include <stdlib.h> #include <signal.h> #include <stdio.h> #else int main(void); void _start(void) { main(); } int syscall(int eax, int ebx, int ecx, int edx) { int ret; __asm__ __volatile__ ( "int $0x80\n\t" : "=a"(ret) : "a"(eax), "b"(ebx), "c"(ecx), "d"(edx) ); return ret; } int pause(void) { return syscall(29, 0, 0, 0); } int exit(int ret) { return syscall(1, 0, 0, 0); } typedef unsigned long sigset_t; struct host_sigaction { void (*sa_handler)(int); sigset_t sa_mask; unsigned long sa_flags; void (*sa_restorer)(void); }; #define HOST_SA_NODEFER 0x40000000 int host_sigaction(int signum, const struct host_sigaction *new, struct host_sigaction *old) { return syscall(67, signum, (int) new, (int) old); } int signal(int signum, void *hnd) { struct host_sigaction sigact = { .sa_handler = hnd, .sa_flags = HOST_SA_NODEFER, .sa_mask = 0, }, old; return host_sigaction(signum, &sigact, &old); } int write(int fd, void *buf, int len) { return syscall(4, fd, (int) buf, len); } #define SIGCHLD 17 #endif #define STACK_SZ 0x1000 char stack[STACK_SZ]; void noop(int sig) { } int main(void) { int esp = STACK_SZ - 4 + (int) stack; int stack_id = VALGRIND_STACK_REGISTER(stack, stack + STACK_SZ); VALGRIND_PRINTF("stack: id=%d, begin=%p, end=%p\n", stack_id, stack, stack + STACK_SZ); signal(SIGCHLD, noop); __asm__ __volatile__ ( "movl %0, %%esp\n\t" "movl %0, %%ebp\n\t" : : "a"(esp) :); pause(); exit(0); return 0; }
vg_test.log.gz
Description: GNU Zip compressed data
vg_test_libc.log.gz
Description: GNU Zip compressed data
------------------------------------------------------------------------------ Get 100% visibility into Java/.NET code with AppDynamics Lite It's a free troubleshooting tool designed for production Get down to code-level detail for bottlenecks, with <2% overhead. Download for free and get started troubleshooting in minutes. http://p.sf.net/sfu/appdyn_d2d_ap2
_______________________________________________ Valgrind-users mailing list Valgrind-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-users