glibc's, and tell the user if starting GDB failed for some reason.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@115
__attribute__ ((__noreturn__));
/* Get memory by anonymous mmap. */
-void* VG_(get_memory_from_mmap) ( Int nBytes );
+extern void* VG_(get_memory_from_mmap) ( Int nBytes );
+
+/* Crude stand-in for the glibc system() call. */
+extern Int VG_(system) ( Char* cmd );
+
/* Signal stuff. Note that these use the vk_ (kernel) structure
definitions, which are different in places from those that glibc
continue the program, though; to continue, quit GDB. */
extern void VG_(start_GDB_whilst_on_client_stack) ( void )
{
+ Int res;
UChar buf[100];
VG_(sprintf)(buf,
"/usr/bin/gdb -nw /proc/%d/exe %d",
VG_(getpid)(), VG_(getpid)());
- VG_(printf)("starting GDB with cmd: %s\n", buf);
- VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
- { /* HACK ALERT */
- extern int system ( const char * );
- system(buf);
- /* end of HACK ALERT */
+ VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
+ res = VG_(system)(buf);
+ if (res == 0) {
+ VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg,
+ "GDB has detached. Valgrind regains control. We continue.");
+ } else {
+ VG_(message)(Vg_UserMsg, "Apparently failed!");
+ VG_(message)(Vg_UserMsg, "");
}
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg,
- "GDB has detached. Valgrind regains control. We continue.");
}
return (1000000ULL * (ULong)(tv.tv_sec)) + (ULong)(tv.tv_usec);
}
+/* Return -1 if error, else 0. NOTE does not indicate return code of
+ child! */
+Int VG_(system) ( Char* cmd )
+{
+ Int pid, res;
+ void* environ[1] = { NULL };
+ if (cmd == NULL)
+ return 1;
+ pid = vg_do_syscall0(__NR_fork);
+ if (VG_(is_kerror)(pid))
+ return -1;
+ if (pid == 0) {
+ /* child */
+ Char* argv[4];
+ argv[0] = "/bin/sh";
+ argv[1] = "-c";
+ argv[2] = cmd;
+ argv[3] = 0;
+ (void)vg_do_syscall3(__NR_execve,
+ (UInt)"/bin/sh", (UInt)argv, (UInt)&environ);
+ /* If we're still alive here, execve failed. */
+ return -1;
+ } else {
+ /* parent */
+ res = vg_do_syscall3(__NR_waitpid, pid, (UInt)NULL, 0);
+ if (VG_(is_kerror)(res)) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+
/* ---------------------------------------------------------------------
Primitive support for bagging memory via mmap.
------------------------------------------------------------------ */
__attribute__ ((__noreturn__));
/* Get memory by anonymous mmap. */
-void* VG_(get_memory_from_mmap) ( Int nBytes );
+extern void* VG_(get_memory_from_mmap) ( Int nBytes );
+
+/* Crude stand-in for the glibc system() call. */
+extern Int VG_(system) ( Char* cmd );
+
/* Signal stuff. Note that these use the vk_ (kernel) structure
definitions, which are different in places from those that glibc
continue the program, though; to continue, quit GDB. */
extern void VG_(start_GDB_whilst_on_client_stack) ( void )
{
+ Int res;
UChar buf[100];
VG_(sprintf)(buf,
"/usr/bin/gdb -nw /proc/%d/exe %d",
VG_(getpid)(), VG_(getpid)());
- VG_(printf)("starting GDB with cmd: %s\n", buf);
- VG_(mash_LD_PRELOAD_string)(VG_(getenv)("LD_PRELOAD"));
- { /* HACK ALERT */
- extern int system ( const char * );
- system(buf);
- /* end of HACK ALERT */
+ VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
+ res = VG_(system)(buf);
+ if (res == 0) {
+ VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg,
+ "GDB has detached. Valgrind regains control. We continue.");
+ } else {
+ VG_(message)(Vg_UserMsg, "Apparently failed!");
+ VG_(message)(Vg_UserMsg, "");
}
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg,
- "GDB has detached. Valgrind regains control. We continue.");
}
return (1000000ULL * (ULong)(tv.tv_sec)) + (ULong)(tv.tv_usec);
}
+/* Return -1 if error, else 0. NOTE does not indicate return code of
+ child! */
+Int VG_(system) ( Char* cmd )
+{
+ Int pid, res;
+ void* environ[1] = { NULL };
+ if (cmd == NULL)
+ return 1;
+ pid = vg_do_syscall0(__NR_fork);
+ if (VG_(is_kerror)(pid))
+ return -1;
+ if (pid == 0) {
+ /* child */
+ Char* argv[4];
+ argv[0] = "/bin/sh";
+ argv[1] = "-c";
+ argv[2] = cmd;
+ argv[3] = 0;
+ (void)vg_do_syscall3(__NR_execve,
+ (UInt)"/bin/sh", (UInt)argv, (UInt)&environ);
+ /* If we're still alive here, execve failed. */
+ return -1;
+ } else {
+ /* parent */
+ res = vg_do_syscall3(__NR_waitpid, pid, (UInt)NULL, 0);
+ if (VG_(is_kerror)(res)) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+
/* ---------------------------------------------------------------------
Primitive support for bagging memory via mmap.
------------------------------------------------------------------ */