procps/ps/stacktrace.c
Jim Warner 629fa81b57 misc: eliminate all those remaining gcc -Wall warnings
Reference(s):
proc/readproc.c: In function 'statm2proc'
proc/readproc.c:627:9: warning: variable 'num' set but not used [-Wunused-but-set-variable]

ps/output.c: In function 'pr_context':
ps/output.c:1273:14: warning: unused variable 'tried_load' [-Wunused-variable]
ps/output.c:1272:16: warning: unused variable 'ps_is_selinux_enabled' [-Wunused-variable]
ps/output.c:1272:16: warning: 'ps_is_selinux_enabled' defined but not used [-Wunused-variable]
ps/output.c:1273:14: warning: 'tried_load' defined but not used [-Wunused-variable]
ps/output.c:1837:18: warning: 'shortsort_array_count' defined but not used [-Wunused-const-variable=]
ps/output.c:1803:18: warning: 'aix_array_count' defined but not used [-Wunused-const-variable=]

ps/parser.c: In function 'arg_type':
ps/parser.c:1098:3: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
ps/parser.c:1099:34: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the 'if'

ps/sortformat.c: In function 'format_parse':
ps/sortformat.c:241:1: warning: label 'out' defined but not used [-Wunused-label]

ps/stacktrace.c:176:13: warning: 'stack_trace_sigsegv' defined but not used [-Wunused-function]

watch.c: In function 'process_ansi':
watch.c:234:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
watch.c:237:2: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the 'if'

Signed-off-by: Jim Warner <james.warner@comcast.net>
2017-05-22 21:34:32 +10:00

190 lines
4.2 KiB
C

/*
* stacktrace.c - ps debugging additions
* Gnu debugger stack trace code provided by Peter Mattis
* <petm@CSUA.Berkeley.EDU> on Thu, 2 Nov 1995
*
* Modified for easy use by Albert Cahalan.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "common.h"
#define INTERACTIVE 0
#define STACK_TRACE 1
char *stored_prog_name = "you forgot to set \"program\"";
static int stack_trace_done;
/***********/
static void debug_stop(char **args){
execvp (args[0], args);
perror ("exec failed");
_exit (0);
}
/***********/
static void stack_trace_sigchld(int signum){
(void)signum;
stack_trace_done = 1;
}
/************/
static void stack_trace(char **args){
pid_t pid;
int in_fd[2];
int out_fd[2];
fd_set fdset;
fd_set readset;
struct timeval tv;
int sel, index, state;
char buffer[256];
char c;
stack_trace_done = 0;
signal(SIGCHLD, stack_trace_sigchld);
if((pipe (in_fd) == -1) || (pipe (out_fd) == -1)){
perror ("could open pipe");
_exit (0);
}
pid = fork ();
if (pid == 0){
close (0); dup (in_fd[0]); /* set the stdin to the in pipe */
close (1); dup (out_fd[1]); /* set the stdout to the out pipe */
close (2); dup (out_fd[1]); /* set the stderr to the out pipe */
execvp (args[0], args); /* exec gdb */
perror ("exec failed");
_exit (0);
} else {
if(pid == (pid_t) -1){
perror ("could not fork");
_exit (0);
}
}
FD_ZERO (&fdset);
FD_SET (out_fd[0], &fdset);
write (in_fd[1], "backtrace\n", 10);
write (in_fd[1], "p x = 0\n", 8);
write (in_fd[1], "quit\n", 5);
index = 0;
state = 0;
for(;;){
readset = fdset;
tv.tv_sec = 1;
tv.tv_usec = 0;
sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
if (sel == -1) break;
if((sel > 0) && (FD_ISSET (out_fd[0], &readset))){
if(read (out_fd[0], &c, 1)){
switch(state){
case 0:
if(c == '#'){
state = 1;
index = 0;
buffer[index++] = c;
}
break;
case 1:
buffer[index++] = c;
if((c == '\n') || (c == '\r')){
buffer[index] = 0;
fprintf (stderr, "%s", buffer);
state = 0;
index = 0;
}
break;
default:
break;
}
}
}
else if(stack_trace_done) break;
}
close (in_fd[0]);
close (in_fd[1]);
close (out_fd[0]);
close (out_fd[1]);
_exit (0);
}
/************/
void debug(int method, char *prog_name){
pid_t pid;
char buf[16];
char *args[4] = { "gdb", NULL, NULL, NULL };
int x;
snprintf (buf, sizeof(buf), "%d", getpid ());
args[1] = prog_name;
args[2] = buf;
pid = fork ();
if(pid == 0){
switch (method){
case INTERACTIVE:
fprintf (stderr, "debug_stop\n");
debug_stop(args);
break;
case STACK_TRACE:
fprintf (stderr, "stack_trace\n");
stack_trace(args);
break;
}
_exit(0);
} else if(pid == (pid_t) -1){
perror ("could not fork");
return;
}
x = 1;
while(x); /* wait for debugger? */
}
/************/
#if 0
static void stack_trace_sigsegv(int signum){
(void)signum;
debug(STACK_TRACE, stored_prog_name);
}
#endif
/************/
#ifdef DEBUG
void init_stack_trace(char *prog_name){
stored_prog_name = prog_name;
signal(SIGSEGV, stack_trace_sigsegv);
}
#endif