Package: gcc-4.1 Version: 4.1.2-13 Severity: important void do_pin_processes(int pids[], int n, char pin) { int i; for (i = 0; i < n; i++) { printf("%d\n", i); do_pin_process(pids[i], pin); } }
When I compile the attached program with the following flags the compiler generates a infinite loop in the function do_pin_processes (the i variable is not incremented): gcc -DHAVE_CONFIG_H -I. -I.. -I../include -pg -g -g -O2 -MT pin-main.o -MD -MP -MF .deps/pin-main.Tpo -c -o pin-main.o `test -f 'main.c' || echo './'`main.c mv -f .deps/pin-main.Tpo .deps/pin-main.Po gcc -DHAVE_CONFIG_H -I. -I.. -I../include -pg -g -g -O2 -MT pin-pin.o -MD -MP -MF .deps/pin-pin.Tpo -c -o pin-pin.o `test -f 'pin.c' || echo './'`pin.c mv -f .deps/pin-pin.Tpo .deps/pin-pin.Po gcc -DHAVE_CONFIG_H -I. -I.. -I../include -pg -g -g -O2 -MT pin-error.o -MD -MP -MF .deps/pin-error.Tpo -c -o pin-error.o `test -f 'error.c' || echo './'`error.c mv -f .deps/pin-error.Tpo .deps/pin-error.Po gcc -pg -g -g -O2 -pg -g -o pin pin-main.o pin-pin.o pin-error.o -lpopt However if I export the CFLAGS variable with -O0 it works properly. The arguments passed to the program and the obtained outputs are: (cmd line) $ ./pin -l "1 2 3" (output bad code) $ Pinning 1 (0): done 0 Pinning 1 (0): done 0 Pinning 1 (0): done 0 Pinning 1 (0): done 0 Pinning 1 (0): done ... (output correct code) $ 0 Pinning 1 (0): done 1 Pinning 2 (0): failed Permission denied 2 Pinning 3 (0): failed Permission denied I have the same problem if I use gcc-4.2. Thanks, Javi
#include <stdio.h> #include <errno.h> FILE * error_file; char err_debug_mode; __attribute__((constructor)) static void init_error() { error_file = stderr; err_debug_mode = 0; } __attribute__((destructor)) static void fini_error() { if (error_file != stderr) fclose(error_file); } int err_set_output_path(char * path) { int ret = 0; if (error_file != stderr) fclose(error_file); error_file = fopen(path, "a+"); if (!error_file) { error_file = stderr; ret = errno; } return ret; } int err_set_output_file(FILE * f) { int ret = 0; if (error_file != stderr) fclose(error_file); error_file = f; if (!error_file) { error_file = stderr; ret = errno; } return ret; }
/* pin - pin and unpin processes in memory Copyright (C) 2007 Javier Cabezas Rodriguez This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <stdio.h> #include <sys/types.h> #include <popt.h> #include "system.h" #include "pin.h" #include "error.h" #define EXIT_FAILURE 1 /* The name the program was run with, stripped of any leading path. */ char * program_name; typedef struct { char unpin; char all; char * pids; } t_cmd_args; t_cmd_args program_args; /* Option flags and variables */ static const struct poptOption program_options[] = { {"unpin", 'u', POPT_ARG_NONE, 0, 'u', "unpin the listed process/es"}, {"all", 'a', POPT_ARG_NONE, 0, 'a', "pin/unpin all the processes"}, {"list", 'l', POPT_ARG_STRING, &program_args.pids, 0, "pin/unpin the processes listed next", "PIDS"}, POPT_AUTOALIAS POPT_AUTOHELP POPT_TABLEEND }; static int parse_args(int argc, char ** argv); static int get_pids(int ** pids) { int i; char error[64]; char * copy; char * str_pid; char * end_pid; int pid, n = 0; copy = strdup(program_args.pids); str_pid = strtok(program_args.pids, " \f\n\r\t\v"); if (!program_args.pids) return 0; while (str_pid) { pid = strtol(str_pid, &end_pid, 10); str_pid = strtok(NULL, " \f\n\r\t\v"); if (pid) n++; } *pids = (int *) malloc(n * sizeof(int)); str_pid = strtok(copy, " \f\n\r\t\v"); i = 0; while (str_pid) { pid = strtol(str_pid, &end_pid, 10); if (!pid) { sprintf(error, "Error: %d is not a valid PID", pid); ERROR(error); str_pid = strtok(NULL, " \f\n\r\t\v"); continue; } (*pids)[i] = pid; str_pid = strtok(NULL, " \f\n\r\t\v"); i++; } free(copy); return n; } int main(int argc, char * argv[]) { int i; program_name = argv[0]; i = parse_args(argc, argv); /* do the work */ if (program_args.all) { do_pin_all(!program_args.unpin); } else { int *pids; int n = get_pids(&pids); do_pin_processes(pids, n, !program_args.unpin); free(pids); } if (program_args.pids) free(program_args.pids); return 0; } static int parse_args(int argc, char ** argv) { int option; poptContext context = poptGetContext( NULL, argc, (const char **) argv, program_options, 0); if (argc < 2) { poptPrintUsage(context, error_file, 0); poptFreeContext(context); exit(1); } while ((option = poptGetNextOpt(context)) >= 0) { switch (option) { case 'u': program_args.unpin = 1; break; case 'a': program_args.all = 1; break; default: poptPrintUsage(context, error_file, 0); exit(1); } } if (program_args.all && program_args.pids) { ERROR("Error: -l and -a flags are incompatible\n"); poptPrintUsage(context, error_file, 0); exit(1); } poptFreeContext(context); }
/* pin - pin and unpin processes in memory Copyright (C) 2007 Javier Cabezas Rodriguez This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <stdio.h> #include "error.h" static inline char is_pinned(int pid) { char path[32]; char error[64]; char pinned; char read; sprintf(path, "/proc/%d/pinned", pid); FILE * f = fopen(path, "r"); if (!f) { printf("failed\n"); STDERROR(); return; } read = fscanf(f, "%d", &pinned); if (!read || read == EOF) { printf("failed\n"); sprintf(error, "Error reading from %s", path); ERROR(error); fclose(f); return; } if (fclose(f) == EOF) { printf("failed\n"); STDERROR(); return; } } static void do_pin(int pid) { char path[32]; char error[64]; printf("Pinning %d (%d): ", pid, is_pinned(pid)); sprintf(path, "/proc/%d/pinned", pid); FILE * f = fopen(path, "a"); if (!f) { printf("failed\n"); STDERROR(); return; } if (fprintf(f, "1") <= 0) { printf("failed\n"); sprintf(error, "Error writing to %s", path); ERROR(error); fclose(f); return; } if (fclose(f) == EOF) { printf("failed\n"); STDERROR(); return; } printf("done\n"); } static void do_unpin(int pid) { char path[32]; char error[64]; printf("Unpinning %d (%d): ", pid, is_pinned(pid)); sprintf(path, "/proc/%d/pinned", pid); FILE * f = fopen(path, "a"); if (!f) { printf("failed\n"); STDERROR(); return; } if (fprintf(f, "0") <= 0) { printf("failed\n"); sprintf(error, "Error writing to %s", path); ERROR(error); fclose(f); return; } if (fclose(f) == EOF) { printf("failed\n"); STDERROR(); return; } printf("done\n"); } void do_pin_process(int pid, char pin) { if (pin) do_pin(pid); else do_unpin(pid); } void do_pin_processes(int pids[], int n, char pin) { int i; for (i = 0; i < n; i++) { printf("%d\n", i); do_pin_process(pids[i], pin); } } void do_pin_all(char pin) { }
signature.asc
Description: Esta parte del mensaje está firmada digitalmente