--- Begin Message ---
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
--- End Message ---