new files -- part of HP merge.
This commit is contained in:
parent
7cada34aec
commit
8e260d5270
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,530 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
/**************************************************************************
|
||||
* TESTS :
|
||||
* function returning large structures, which go on the stack
|
||||
* functions returning varied sized structs which go on in the registers.
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/* A large structure (> 64 bits) used to test passing large structures as
|
||||
* parameters
|
||||
*/
|
||||
|
||||
struct array_rep_info_t {
|
||||
int next_index[10];
|
||||
int values[10];
|
||||
int head;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Small structures ( <= 64 bits). These are used to test passing small
|
||||
* structures as parameters and test argument size promotion.
|
||||
*****************************************************************************/
|
||||
|
||||
/* 64 bits
|
||||
*/
|
||||
struct small_rep_info_t {
|
||||
int value;
|
||||
int head;
|
||||
};
|
||||
|
||||
/* 6 bits : really fits in 8 bits and is promoted to 32 bits
|
||||
*/
|
||||
struct bit_flags_t {
|
||||
unsigned alpha :1;
|
||||
unsigned beta :1;
|
||||
unsigned gamma :1;
|
||||
unsigned delta :1;
|
||||
unsigned epsilon :1;
|
||||
unsigned omega :1;
|
||||
};
|
||||
|
||||
/* 22 bits : really fits in 40 bits and is promoted to 64 bits
|
||||
*/
|
||||
struct bit_flags_combo_t {
|
||||
unsigned alpha :1;
|
||||
unsigned beta :1;
|
||||
char ch1;
|
||||
unsigned gamma :1;
|
||||
unsigned delta :1;
|
||||
char ch2;
|
||||
unsigned epsilon :1;
|
||||
unsigned omega :1;
|
||||
};
|
||||
|
||||
/* 64 bits
|
||||
*/
|
||||
struct one_double_t {
|
||||
double double1;
|
||||
};
|
||||
|
||||
/* 64 bits
|
||||
*/
|
||||
struct two_floats_t {
|
||||
float float1;
|
||||
float float2;
|
||||
};
|
||||
|
||||
|
||||
/* 24 bits : promoted to 32 bits
|
||||
*/
|
||||
struct three_char_t {
|
||||
char ch1;
|
||||
char ch2;
|
||||
char ch3;
|
||||
};
|
||||
|
||||
/* 40 bits : promoted to 64 bits
|
||||
*/
|
||||
struct five_char_t {
|
||||
char ch1;
|
||||
char ch2;
|
||||
char ch3;
|
||||
char ch4;
|
||||
char ch5;
|
||||
};
|
||||
|
||||
/* 40 bits : promoted to 64 bits
|
||||
*/
|
||||
struct int_char_combo_t {
|
||||
int int1;
|
||||
char ch1;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
* LOOP_COUNT :
|
||||
* A do nothing function. Used to provide a point at which calls can be made.
|
||||
*****************************************************************/
|
||||
void loop_count () {
|
||||
|
||||
int index;
|
||||
|
||||
for (index=0; index<4; index++);
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_BIT_FLAGS :
|
||||
* Initializes a bit_flags_t structure. Can call this function see
|
||||
* the call command behavior when integer arguments do not fit into
|
||||
* registers and must be placed on the stack.
|
||||
* OUT struct bit_flags_t *bit_flags -- structure to be filled
|
||||
* IN unsigned a -- 0 or 1
|
||||
* IN unsigned b -- 0 or 1
|
||||
* IN unsigned g -- 0 or 1
|
||||
* IN unsigned d -- 0 or 1
|
||||
* IN unsigned e -- 0 or 1
|
||||
* IN unsigned o -- 0 or 1
|
||||
*****************************************************************/
|
||||
void init_bit_flags (bit_flags,a,b,g,d,e,o)
|
||||
struct bit_flags_t *bit_flags;
|
||||
unsigned a;
|
||||
unsigned b;
|
||||
unsigned g;
|
||||
unsigned d;
|
||||
unsigned e;
|
||||
unsigned o;
|
||||
{
|
||||
|
||||
bit_flags->alpha = a;
|
||||
bit_flags->beta = b;
|
||||
bit_flags->gamma = g;
|
||||
bit_flags->delta = d;
|
||||
bit_flags->epsilon = e;
|
||||
bit_flags->omega = o;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_BIT_FLAGS_COMBO :
|
||||
* Initializes a bit_flags_combo_t structure. Can call this function
|
||||
* to see the call command behavior when integer and character arguments
|
||||
* do not fit into registers and must be placed on the stack.
|
||||
* OUT struct bit_flags_combo_t *bit_flags_combo -- structure to fill
|
||||
* IN unsigned a -- 0 or 1
|
||||
* IN unsigned b -- 0 or 1
|
||||
* IN char ch1
|
||||
* IN unsigned g -- 0 or 1
|
||||
* IN unsigned d -- 0 or 1
|
||||
* IN char ch2
|
||||
* IN unsigned e -- 0 or 1
|
||||
* IN unsigned o -- 0 or 1
|
||||
*****************************************************************/
|
||||
void init_bit_flags_combo (bit_flags_combo, a, b, ch1, g, d, ch2, e, o)
|
||||
struct bit_flags_combo_t *bit_flags_combo;
|
||||
unsigned a;
|
||||
unsigned b;
|
||||
char ch1;
|
||||
unsigned g;
|
||||
unsigned d;
|
||||
char ch2;
|
||||
unsigned e;
|
||||
unsigned o;
|
||||
{
|
||||
|
||||
bit_flags_combo->alpha = a;
|
||||
bit_flags_combo->beta = b;
|
||||
bit_flags_combo->ch1 = ch1;
|
||||
bit_flags_combo->gamma = g;
|
||||
bit_flags_combo->delta = d;
|
||||
bit_flags_combo->ch2 = ch2;
|
||||
bit_flags_combo->epsilon = e;
|
||||
bit_flags_combo->omega = o;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_ONE_DOUBLE :
|
||||
* OUT struct one_double_t *one_double -- structure to fill
|
||||
* IN double init_val
|
||||
*****************************************************************/
|
||||
void init_one_double (one_double, init_val)
|
||||
struct one_double_t *one_double;
|
||||
double init_val;
|
||||
{
|
||||
|
||||
one_double->double1 = init_val;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_TWO_FLOATS :
|
||||
* OUT struct two_floats_t *two_floats -- structure to be filled
|
||||
* IN float init_val1
|
||||
* IN float init_val2
|
||||
*****************************************************************/
|
||||
void init_two_floats (two_floats, init_val1, init_val2)
|
||||
struct two_floats_t *two_floats;
|
||||
float init_val1;
|
||||
float init_val2;
|
||||
{
|
||||
|
||||
two_floats->float1 = init_val1;
|
||||
two_floats->float2 = init_val2;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_THREE_CHARS :
|
||||
* OUT struct three_char_t *three_char -- structure to be filled
|
||||
* IN char init_val1
|
||||
* IN char init_val2
|
||||
* IN char init_val3
|
||||
*****************************************************************/
|
||||
void init_three_chars ( three_char, init_val1, init_val2, init_val3)
|
||||
struct three_char_t *three_char;
|
||||
char init_val1;
|
||||
char init_val2;
|
||||
char init_val3;
|
||||
{
|
||||
|
||||
three_char->ch1 = init_val1;
|
||||
three_char->ch2 = init_val2;
|
||||
three_char->ch3 = init_val3;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_FIVE_CHARS :
|
||||
* OUT struct five_char_t *five_char -- structure to be filled
|
||||
* IN char init_val1
|
||||
* IN char init_val2
|
||||
* IN char init_val3
|
||||
* IN char init_val4
|
||||
* IN char init_val5
|
||||
*****************************************************************/
|
||||
void init_five_chars ( five_char, init_val1, init_val2, init_val3, init_val4, init_val5)
|
||||
struct five_char_t *five_char;
|
||||
char init_val1;
|
||||
char init_val2;
|
||||
char init_val3;
|
||||
char init_val4;
|
||||
char init_val5;
|
||||
{
|
||||
|
||||
five_char->ch1 = init_val1;
|
||||
five_char->ch2 = init_val2;
|
||||
five_char->ch3 = init_val3;
|
||||
five_char->ch4 = init_val4;
|
||||
five_char->ch5 = init_val5;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_INT_CHAR_COMBO :
|
||||
* OUT struct int_char_combo_t *combo -- structure to be filled
|
||||
* IN int init_val1
|
||||
* IN char init_val2
|
||||
*****************************************************************/
|
||||
void init_int_char_combo ( combo, init_val1, init_val2)
|
||||
struct int_char_combo_t *combo;
|
||||
int init_val1;
|
||||
char init_val2;
|
||||
{
|
||||
|
||||
combo->int1 = init_val1;
|
||||
combo->ch1 = init_val2;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_STRUCT_REP :
|
||||
* OUT struct small_rep_into_t *small_struct -- structure to be filled
|
||||
* IN int seed
|
||||
*****************************************************************/
|
||||
void init_struct_rep( small_struct, seed)
|
||||
struct small_rep_info_t *small_struct;
|
||||
int seed;
|
||||
|
||||
{
|
||||
|
||||
small_struct->value = 2 + (seed*2);
|
||||
small_struct->head = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* PRINT_BIT_FLAGS :
|
||||
* IN struct bit_flags_t bit_flags
|
||||
****************************************************************/
|
||||
struct bit_flags_t print_bit_flags ( bit_flags)
|
||||
struct bit_flags_t bit_flags;
|
||||
{
|
||||
|
||||
if (bit_flags.alpha) printf("alpha\n");
|
||||
if (bit_flags.beta) printf("beta\n");
|
||||
if (bit_flags.gamma) printf("gamma\n");
|
||||
if (bit_flags.delta) printf("delta\n");
|
||||
if (bit_flags.epsilon) printf("epsilon\n");
|
||||
if (bit_flags.omega) printf("omega\n");
|
||||
return bit_flags;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* PRINT_BIT_FLAGS_COMBO :
|
||||
* IN struct bit_flags_combo_t bit_flags_combo
|
||||
****************************************************************/
|
||||
struct bit_flags_combo_t print_bit_flags_combo ( bit_flags_combo )
|
||||
struct bit_flags_combo_t bit_flags_combo;
|
||||
{
|
||||
|
||||
if (bit_flags_combo.alpha) printf("alpha\n");
|
||||
if (bit_flags_combo.beta) printf("beta\n");
|
||||
if (bit_flags_combo.gamma) printf("gamma\n");
|
||||
if (bit_flags_combo.delta) printf("delta\n");
|
||||
if (bit_flags_combo.epsilon) printf("epsilon\n");
|
||||
if (bit_flags_combo.omega) printf("omega\n");
|
||||
printf("ch1: %c\tch2: %c\n", bit_flags_combo.ch1, bit_flags_combo.ch2);
|
||||
return bit_flags_combo;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* PRINT_ONE_DOUBLE :
|
||||
* IN struct one_double_t one_double
|
||||
****************************************************************/
|
||||
struct one_double_t print_one_double ( one_double )
|
||||
struct one_double_t one_double;
|
||||
{
|
||||
|
||||
printf("Contents of one_double_t: \n\n");
|
||||
printf("%f\n", one_double.double1);
|
||||
return one_double;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* PRINT_TWO_FLOATS :
|
||||
* IN struct two_floats_t two_floats
|
||||
****************************************************************/
|
||||
struct two_floats_t print_two_floats ( two_floats )
|
||||
struct two_floats_t two_floats;
|
||||
{
|
||||
|
||||
printf("Contents of two_floats_t: \n\n");
|
||||
printf("%f\t%f\n", two_floats.float1, two_floats.float2);
|
||||
return two_floats;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* PRINT_THREE_CHARS :
|
||||
* IN struct three_char_t three_char
|
||||
****************************************************************/
|
||||
struct three_char_t print_three_chars ( three_char )
|
||||
struct three_char_t three_char;
|
||||
{
|
||||
|
||||
printf("Contents of three_char_t: \n\n");
|
||||
printf("%c\t%c\t%c\n", three_char.ch1, three_char.ch2, three_char.ch3);
|
||||
return three_char;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* PRINT_FIVE_CHARS :
|
||||
* IN struct five_char_t five_char
|
||||
****************************************************************/
|
||||
struct five_char_t print_five_chars ( five_char )
|
||||
struct five_char_t five_char;
|
||||
{
|
||||
|
||||
printf("Contents of five_char_t: \n\n");
|
||||
printf("%c\t%c\t%c\t%c\t%c\n", five_char.ch1, five_char.ch2,
|
||||
five_char.ch3, five_char.ch4,
|
||||
five_char.ch5);
|
||||
return five_char;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* PRINT_INT_CHAR_COMBO :
|
||||
* IN struct int_char_combo_t int_char_combo
|
||||
****************************************************************/
|
||||
struct int_char_combo_t print_int_char_combo ( int_char_combo )
|
||||
struct int_char_combo_t int_char_combo;
|
||||
{
|
||||
|
||||
printf("Contents of int_char_combo_t: \n\n");
|
||||
printf("%d\t%c\n", int_char_combo.int1, int_char_combo.ch1);
|
||||
return int_char_combo;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* PRINT_STRUCT_REP :
|
||||
****************************************************************/
|
||||
struct small_rep_info_t print_struct_rep( struct1 )
|
||||
struct small_rep_info_t struct1;
|
||||
|
||||
{
|
||||
|
||||
printf("Contents of struct1: \n\n");
|
||||
printf("%10d%10d\n", struct1.value, struct1.head);
|
||||
struct1.value =+5;
|
||||
|
||||
return struct1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct array_rep_info_t print_one_large_struct( linked_list1 )
|
||||
struct array_rep_info_t linked_list1;
|
||||
{
|
||||
|
||||
|
||||
printf("%10d%10d\n", linked_list1.values[0],
|
||||
linked_list1.next_index[0]);
|
||||
|
||||
return linked_list1;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* INIT_ARRAY_REP :
|
||||
* IN struct array_rep_info_t *linked_list
|
||||
* IN int seed
|
||||
****************************************************************/
|
||||
void init_array_rep( linked_list, seed )
|
||||
struct array_rep_info_t *linked_list;
|
||||
int seed;
|
||||
|
||||
{
|
||||
|
||||
int index;
|
||||
|
||||
for (index = 0; index < 10; index++) {
|
||||
|
||||
linked_list->values[index] = (2*index) + (seed*2);
|
||||
linked_list->next_index[index] = index + 1;
|
||||
}
|
||||
linked_list->head = 0;
|
||||
}
|
||||
|
||||
|
||||
int main () {
|
||||
|
||||
/* variables for large structure testing
|
||||
*/
|
||||
int number = 10;
|
||||
struct array_rep_info_t *list1;
|
||||
|
||||
/* variables for testing a small structures and a very long argument list
|
||||
*/
|
||||
struct small_rep_info_t *struct1;
|
||||
struct bit_flags_t *flags;
|
||||
struct bit_flags_combo_t *flags_combo;
|
||||
struct three_char_t *three_char;
|
||||
struct five_char_t *five_char;
|
||||
struct int_char_combo_t *int_char_combo;
|
||||
struct one_double_t *d1;
|
||||
struct two_floats_t *f3;
|
||||
|
||||
|
||||
/* Allocate space for large structures
|
||||
*/
|
||||
list1 = (struct array_rep_info_t *)malloc(sizeof(struct array_rep_info_t));
|
||||
|
||||
/* Initialize large structures
|
||||
*/
|
||||
init_array_rep(list1, 2);
|
||||
|
||||
/* Print large structures
|
||||
*/
|
||||
print_one_large_struct(*list1);
|
||||
|
||||
/* Allocate space for small structures
|
||||
*/
|
||||
struct1 = (struct small_rep_info_t *)malloc(sizeof(struct small_rep_info_t));
|
||||
flags = (struct bit_flags_t *)malloc(sizeof(struct bit_flags_t));
|
||||
flags_combo = (struct bit_flags_combo_t *)malloc(sizeof(struct bit_flags_combo_t));
|
||||
three_char = (struct three_char_t *)malloc(sizeof(struct three_char_t));
|
||||
five_char = (struct five_char_t *)malloc(sizeof(struct five_char_t));
|
||||
int_char_combo = (struct int_char_combo_t *)malloc(sizeof(struct int_char_combo_t));
|
||||
|
||||
d1 = (struct one_double_t *)malloc(sizeof(struct one_double_t));
|
||||
f3 = (struct two_floats_t *)malloc(sizeof(struct two_floats_t));
|
||||
|
||||
/* Initialize small structures
|
||||
*/
|
||||
init_one_double ( d1, 1.11111);
|
||||
init_two_floats ( f3, -2.345, 1.0);
|
||||
init_bit_flags(flags, (unsigned)1, (unsigned)0, (unsigned)1,
|
||||
(unsigned)0, (unsigned)1, (unsigned)0 );
|
||||
init_bit_flags_combo(flags_combo, (unsigned)1, (unsigned)0, 'y',
|
||||
(unsigned)1, (unsigned)0, 'n',
|
||||
(unsigned)1, (unsigned)0 );
|
||||
init_three_chars(three_char, 'x', 'y', 'z');
|
||||
init_five_chars(five_char, 'h', 'e', 'l', 'l', 'o');
|
||||
init_int_char_combo(int_char_combo, 13, '!');
|
||||
init_struct_rep(struct1, 10);
|
||||
|
||||
|
||||
/* Print small structures
|
||||
*/
|
||||
print_one_double(*d1);
|
||||
print_two_floats(*f3);
|
||||
print_bit_flags(*flags);
|
||||
print_bit_flags_combo(*flags_combo);
|
||||
print_three_chars(*three_char);
|
||||
print_five_chars(*five_char);
|
||||
print_int_char_combo(*int_char_combo);
|
||||
print_struct_rep(*struct1);
|
||||
|
||||
loop_count();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#include <stdio.h>
|
||||
char buf[100];
|
||||
char bigbuf[1000];
|
||||
char * s;
|
||||
|
||||
char * str_func1(s1)
|
||||
char *s1;
|
||||
{
|
||||
printf("first string arg is: %s\n", s1);
|
||||
strcpy(bigbuf, s1);
|
||||
return bigbuf;
|
||||
}
|
||||
|
||||
char * str_func(s1,
|
||||
s2,
|
||||
s3,
|
||||
s4,
|
||||
s5,
|
||||
s6,
|
||||
s7)
|
||||
char * s1;
|
||||
char * s2;
|
||||
char * s3;
|
||||
char * s4;
|
||||
char * s5;
|
||||
char * s6;
|
||||
char * s7;
|
||||
{
|
||||
printf("first string arg is: %s\n", s1);
|
||||
printf("second string arg is: %s\n", s2);
|
||||
printf("third string arg is: %s\n", s3);
|
||||
printf("fourth string arg is: %s\n", s4);
|
||||
printf("fifth string arg is: %s\n", s5);
|
||||
printf("sixth string arg is: %s\n", s6);
|
||||
printf("seventh string arg is: %s\n", s7);
|
||||
strcpy(bigbuf, s1);
|
||||
strcat(bigbuf, s2);
|
||||
strcat(bigbuf, s3);
|
||||
strcat(bigbuf, s4);
|
||||
strcat(bigbuf, s5);
|
||||
strcat(bigbuf, s6);
|
||||
strcat(bigbuf, s7);
|
||||
return bigbuf;
|
||||
}
|
||||
|
||||
|
||||
main()
|
||||
{
|
||||
s = &buf[0];
|
||||
strcpy(buf, "test string");
|
||||
str_func("abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz12");
|
||||
str_func1("abcd");
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
/* Support program for testing gdb's ability to call functions
|
||||
in an inferior which doesn't itself call malloc, pass appropriate
|
||||
arguments to those functions, and get the returned result. */
|
||||
|
||||
#ifdef NO_PROTOTYPES
|
||||
#define PARAMS(paramlist) ()
|
||||
#else
|
||||
#define PARAMS(paramlist) paramlist
|
||||
#endif
|
||||
|
||||
char char_val1 = 'a';
|
||||
char char_val2 = 'b';
|
||||
|
||||
short short_val1 = 10;
|
||||
short short_val2 = -23;
|
||||
|
||||
int int_val1 = 87;
|
||||
int int_val2 = -26;
|
||||
|
||||
long long_val1 = 789;
|
||||
long long_val2 = -321;
|
||||
|
||||
float float_val1 = 3.14159;
|
||||
float float_val2 = -2.3765;
|
||||
|
||||
double double_val1 = 45.654;
|
||||
double double_val2 = -67.66;
|
||||
|
||||
#define DELTA (0.001)
|
||||
|
||||
char *string_val1 = "string 1";
|
||||
char *string_val2 = "string 2";
|
||||
|
||||
char char_array_val1[] = "carray 1";
|
||||
char char_array_val2[] = "carray 2";
|
||||
|
||||
struct struct1 {
|
||||
char c;
|
||||
short s;
|
||||
int i;
|
||||
long l;
|
||||
float f;
|
||||
double d;
|
||||
char a[4];
|
||||
} struct_val1 = { 'x', 87, 76, 51, 2.1234, 9.876, "foo" };
|
||||
|
||||
/* Some functions that can be passed as arguments to other test
|
||||
functions, or called directly. */
|
||||
|
||||
int add (a, b)
|
||||
int a, b;
|
||||
{
|
||||
return (a + b);
|
||||
}
|
||||
|
||||
int doubleit (a)
|
||||
int a;
|
||||
{
|
||||
return (a + a);
|
||||
}
|
||||
|
||||
int (*func_val1) PARAMS((int,int)) = add;
|
||||
int (*func_val2) PARAMS((int)) = doubleit;
|
||||
|
||||
/* An enumeration and functions that test for specific values. */
|
||||
|
||||
enum enumtype { enumval1, enumval2, enumval3 };
|
||||
enum enumtype enum_val1 = enumval1;
|
||||
enum enumtype enum_val2 = enumval2;
|
||||
enum enumtype enum_val3 = enumval3;
|
||||
|
||||
t_enum_value1 (enum_arg)
|
||||
enum enumtype enum_arg;
|
||||
{
|
||||
return (enum_arg == enum_val1);
|
||||
}
|
||||
|
||||
t_enum_value2 (enum_arg)
|
||||
enum enumtype enum_arg;
|
||||
{
|
||||
return (enum_arg == enum_val2);
|
||||
}
|
||||
|
||||
t_enum_value3 (enum_arg)
|
||||
enum enumtype enum_arg;
|
||||
{
|
||||
return (enum_arg == enum_val3);
|
||||
}
|
||||
|
||||
/* A function that takes a vector of integers (along with an explicit
|
||||
count) and returns their sum. */
|
||||
|
||||
int sum_args (argc, argv)
|
||||
int argc;
|
||||
int argv[];
|
||||
{
|
||||
int sumval = 0;
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < argc; idx++)
|
||||
{
|
||||
sumval += argv[idx];
|
||||
}
|
||||
return (sumval);
|
||||
}
|
||||
|
||||
/* Test that we can call functions that take structs and return
|
||||
members from that struct */
|
||||
|
||||
char t_structs_c (tstruct) struct struct1 tstruct; { return (tstruct.c); }
|
||||
short t_structs_s (tstruct) struct struct1 tstruct; { return (tstruct.s); }
|
||||
int t_structs_i (tstruct) struct struct1 tstruct; { return (tstruct.i); }
|
||||
long t_structs_l (tstruct) struct struct1 tstruct; { return (tstruct.l); }
|
||||
float t_structs_f (tstruct) struct struct1 tstruct; { return (tstruct.f); }
|
||||
double t_structs_d (tstruct) struct struct1 tstruct; { return (tstruct.d); }
|
||||
char *t_structs_a (tstruct) struct struct1 tstruct; { return (tstruct.a); }
|
||||
|
||||
/* Test that calling functions works if there are a lot of arguments. */
|
||||
int
|
||||
sum10 (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
|
||||
int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
|
||||
{
|
||||
return i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9;
|
||||
}
|
||||
|
||||
/* Gotta have a main to be able to generate a linked, runnable
|
||||
executable, and also provide a useful place to set a breakpoint. */
|
||||
|
||||
main ()
|
||||
{
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
t_structs_c(struct_val1);
|
||||
}
|
||||
|
||||
/* Functions that expect specific values to be passed and return
|
||||
either 0 or 1, depending upon whether the values were
|
||||
passed incorrectly or correctly, respectively. */
|
||||
|
||||
int t_char_values (char_arg1, char_arg2)
|
||||
char char_arg1, char_arg2;
|
||||
{
|
||||
return ((char_arg1 == char_val1) && (char_arg2 == char_val2));
|
||||
}
|
||||
|
||||
int
|
||||
#ifdef NO_PROTOTYPES
|
||||
t_small_values (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
||||
char arg1;
|
||||
short arg2;
|
||||
int arg3;
|
||||
char arg4;
|
||||
short arg5;
|
||||
char arg6;
|
||||
short arg7;
|
||||
int arg8;
|
||||
short arg9;
|
||||
short arg10;
|
||||
#else
|
||||
t_small_values (char arg1, short arg2, int arg3, char arg4, short arg5,
|
||||
char arg6, short arg7, int arg8, short arg9, short arg10)
|
||||
#endif
|
||||
{
|
||||
return arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10;
|
||||
}
|
||||
|
||||
int t_short_values (short_arg1, short_arg2)
|
||||
short short_arg1, short_arg2;
|
||||
{
|
||||
return ((short_arg1 == short_val1) && (short_arg2 == short_val2));
|
||||
}
|
||||
|
||||
int t_int_values (int_arg1, int_arg2)
|
||||
int int_arg1, int_arg2;
|
||||
{
|
||||
return ((int_arg1 == int_val1) && (int_arg2 == int_val2));
|
||||
}
|
||||
|
||||
int t_long_values (long_arg1, long_arg2)
|
||||
long long_arg1, long_arg2;
|
||||
{
|
||||
return ((long_arg1 == long_val1) && (long_arg2 == long_val2));
|
||||
}
|
||||
|
||||
int t_float_values (float_arg1, float_arg2)
|
||||
float float_arg1, float_arg2;
|
||||
{
|
||||
return ((float_arg1 - float_val1) < DELTA
|
||||
&& (float_arg1 - float_val1) > -DELTA
|
||||
&& (float_arg2 - float_val2) < DELTA
|
||||
&& (float_arg2 - float_val2) > -DELTA);
|
||||
}
|
||||
|
||||
int
|
||||
#ifdef NO_PROTOTYPES
|
||||
/* In this case we are just duplicating t_float_values, but that is the
|
||||
easiest way to deal with either ANSI or non-ANSI. */
|
||||
t_float_values2 (float_arg1, float_arg2)
|
||||
float float_arg1, float_arg2;
|
||||
#else
|
||||
t_float_values2 (float float_arg1, float float_arg2)
|
||||
#endif
|
||||
{
|
||||
return ((float_arg1 - float_val1) < DELTA
|
||||
&& (float_arg1 - float_val1) > -DELTA
|
||||
&& (float_arg2 - float_val2) < DELTA
|
||||
&& (float_arg2 - float_val2) > -DELTA);
|
||||
}
|
||||
|
||||
int t_double_values (double_arg1, double_arg2)
|
||||
double double_arg1, double_arg2;
|
||||
{
|
||||
return ((double_arg1 - double_val1) < DELTA
|
||||
&& (double_arg1 - double_val1) > -DELTA
|
||||
&& (double_arg2 - double_val2) < DELTA
|
||||
&& (double_arg2 - double_val2) > -DELTA);
|
||||
}
|
||||
|
||||
int t_string_values (string_arg1, string_arg2)
|
||||
char *string_arg1, *string_arg2;
|
||||
{
|
||||
return (!strcmp (string_arg1, string_val1) &&
|
||||
!strcmp (string_arg2, string_val2));
|
||||
}
|
||||
|
||||
int t_char_array_values (char_array_arg1, char_array_arg2)
|
||||
char char_array_arg1[], char_array_arg2[];
|
||||
{
|
||||
return (!strcmp (char_array_arg1, char_array_val1) &&
|
||||
!strcmp (char_array_arg2, char_array_val2));
|
||||
}
|
||||
|
||||
|
||||
/* This used to simply compare the function pointer arguments with
|
||||
known values for func_val1 and func_val2. Doing so is valid ANSI
|
||||
code, but on some machines (RS6000, HPPA, others?) it may fail when
|
||||
called directly by GDB.
|
||||
|
||||
In a nutshell, it's not possible for GDB to determine when the address
|
||||
of a function or the address of the function's stub/trampoline should
|
||||
be passed.
|
||||
|
||||
So, to avoid GDB lossage in the common case, we perform calls through the
|
||||
various function pointers and compare the return values. For the HPPA
|
||||
at least, this allows the common case to work.
|
||||
|
||||
If one wants to try something more complicated, pass the address of
|
||||
a function accepting a "double" as one of its first 4 arguments. Call
|
||||
that function indirectly through the function pointer. This would fail
|
||||
on the HPPA. */
|
||||
|
||||
int t_func_values (func_arg1, func_arg2)
|
||||
int (*func_arg1) PARAMS ((int, int));
|
||||
int (*func_arg2) PARAMS ((int));
|
||||
{
|
||||
return ((*func_arg1) (5,5) == (*func_val1) (5,5)
|
||||
&& (*func_arg2) (6) == (*func_val2) (6));
|
||||
}
|
||||
|
||||
int t_call_add (func_arg1, a, b)
|
||||
int (*func_arg1) PARAMS ((int, int));
|
||||
int a, b;
|
||||
{
|
||||
return ((*func_arg1)(a, b));
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
#ifdef vxworks
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
/* VxWorks does not supply atoi. */
|
||||
static int
|
||||
atoi (z)
|
||||
char *z;
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (*z >= '0' && *z <= '9')
|
||||
i = i * 10 + (*z++ - '0');
|
||||
return i;
|
||||
}
|
||||
|
||||
/* I don't know of any way to pass an array to VxWorks. This function
|
||||
can be called directly from gdb. */
|
||||
|
||||
vxmain (arg)
|
||||
char *arg;
|
||||
{
|
||||
char *argv[2];
|
||||
|
||||
argv[0] = "";
|
||||
argv[1] = arg;
|
||||
main (2, argv, (char **) 0);
|
||||
}
|
||||
|
||||
#else /* ! vxworks */
|
||||
# include <stdio.h>
|
||||
#endif /* ! vxworks */
|
||||
|
||||
/*
|
||||
* The following functions do nothing useful. They are included simply
|
||||
* as places to try setting breakpoints at. They are explicitly
|
||||
* "one-line functions" to verify that this case works (some versions
|
||||
* of gcc have or have had problems with this).
|
||||
*/
|
||||
|
||||
int marker1 () { return (0); }
|
||||
int marker2 (a) int a; { return (1); }
|
||||
void marker3 (a, b) char *a, *b; {}
|
||||
void marker4 (d) long d; {}
|
||||
|
||||
/*
|
||||
* This simple classical example of recursion is useful for
|
||||
* testing stack backtraces and such.
|
||||
*/
|
||||
|
||||
int
|
||||
main (argc, argv, envp)
|
||||
int argc;
|
||||
char *argv[], **envp;
|
||||
{
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
if (argc == 123456) {
|
||||
fprintf (stderr, "usage: factorial <number>\n");
|
||||
return 1;
|
||||
}
|
||||
printf ("%d\n", factorial (atoi ("6")));
|
||||
|
||||
marker1 ();
|
||||
marker2 (43);
|
||||
marker3 ("stack", "trace");
|
||||
marker4 (177601976L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int factorial (value)
|
||||
int value;
|
||||
{
|
||||
if (value > 1) {
|
||||
value *= factorial (value - 1);
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
void marker1 (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// misc. function params
|
||||
|
||||
int qux1 (const char cc, const char & ccr, const char * ccp, char * const cpc)
|
||||
{
|
||||
return 33;
|
||||
}
|
||||
|
||||
int qux2 (volatile unsigned char vuc, const volatile int cvi,
|
||||
volatile short & vsr, volatile long * vlp, float * volatile fpv,
|
||||
const volatile signed char * const volatile cvscpcv)
|
||||
{
|
||||
return 400;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char lave = 'B';
|
||||
unsigned char lavish = 10;
|
||||
short lax = 20;
|
||||
unsigned short lecherous = 30;
|
||||
long lechery = 40;
|
||||
unsigned long lectern = 50;
|
||||
float leeway = 60;
|
||||
double legacy = 70;
|
||||
signed char lemonade = 35;
|
||||
|
||||
const char laconic = 'A';
|
||||
const unsigned char laggard = 1;
|
||||
const short lagoon = 2;
|
||||
const unsigned short laity = 3;
|
||||
const long lambent = 4;
|
||||
const unsigned long laminated = 5;
|
||||
const float lampoon = 6;
|
||||
const double languid = 7;
|
||||
|
||||
// pointers to constant variables
|
||||
const char *legend = &lave;
|
||||
const unsigned char *legerdemain = &lavish;
|
||||
const short *leniency = &lax;
|
||||
const unsigned short *leonine = &lecherous;
|
||||
const long *lesion = &lechery;
|
||||
const unsigned long *lethal = &lectern;
|
||||
const float *lethargic = &leeway;
|
||||
const double *levity = &legacy;
|
||||
|
||||
// constant pointers to constant variables
|
||||
const char *const lewd = &laconic;
|
||||
const unsigned char *const lexicographer = &laggard;
|
||||
const short *const lexicon = &lagoon;
|
||||
const unsigned short *const liaison = &laity;
|
||||
const long *const libation = &lambent;
|
||||
const unsigned long *const libelous = &laminated;
|
||||
const float *const libertine = &lampoon;
|
||||
const double *const libidinous = &languid;
|
||||
|
||||
// this is the same as const char * legend ....
|
||||
char const *languish = &laconic;
|
||||
unsigned char const *languor = &laggard;
|
||||
short const *lank = &lagoon;
|
||||
unsigned short const *lapidary = &laity;
|
||||
long const *larceny = &lambent;
|
||||
unsigned long const *largess = &laminated;
|
||||
float const *lascivious = &lampoon;
|
||||
double const *lassitude = &languid;
|
||||
|
||||
// constant pointers to variable
|
||||
char *const lamprey = &lave;
|
||||
unsigned char *const lariat = &lavish;
|
||||
short *const laudanum = &lax;
|
||||
unsigned short *const lecithin = &lecherous;
|
||||
long *const leviathan = &lechery;
|
||||
unsigned long *const libretto = &lectern;
|
||||
float *const lissome = &leeway;
|
||||
double *const locust = &legacy;
|
||||
|
||||
// volatile variables
|
||||
|
||||
volatile char vox = 'X';
|
||||
volatile unsigned char victuals = 13;
|
||||
volatile short vixen = 200;
|
||||
volatile unsigned short vitriol = 300;
|
||||
volatile long vellum = 1000;
|
||||
volatile unsigned long valve = 2000;
|
||||
volatile float vacuity = 3.0;
|
||||
volatile double vertigo = 10.3;
|
||||
|
||||
// pointers to volatile variables
|
||||
|
||||
volatile char * vampire = &vox;
|
||||
volatile unsigned char * viper = &victuals;
|
||||
volatile short * vigour = &vixen;
|
||||
volatile unsigned short * vapour = &vitriol;
|
||||
volatile long * ventricle = &vellum;
|
||||
volatile unsigned long * vigintillion = &valve;
|
||||
volatile float * vocation = &vacuity;
|
||||
volatile double * veracity = &vertigo;
|
||||
|
||||
// volatile pointers to volatile variables
|
||||
|
||||
volatile char * volatile vapidity = &vox;
|
||||
volatile unsigned char * volatile velocity = &victuals;
|
||||
volatile short * volatile veneer = &vixen;
|
||||
volatile unsigned short * volatile video = &vitriol;
|
||||
volatile long * volatile vacuum = &vellum;
|
||||
volatile unsigned long * volatile veniality = &valve;
|
||||
volatile float * volatile vitality = &vacuity;
|
||||
volatile double * volatile voracity = &vertigo;
|
||||
|
||||
// const volatile vars
|
||||
|
||||
const volatile char victor = 'Y';
|
||||
const volatile unsigned char vicar = 11;
|
||||
|
||||
// pointers to const volatiles
|
||||
|
||||
const volatile char * victory = &victor;
|
||||
const volatile unsigned char * vicarage = &vicar;
|
||||
|
||||
// const pointers to volatile vars
|
||||
|
||||
volatile char * const vein = &vox;
|
||||
volatile unsigned char * const vogue = &victuals;
|
||||
|
||||
// const pointers to const volatile vars
|
||||
|
||||
const volatile char * const cavern = &victor;
|
||||
const volatile unsigned char * const coverlet = &vicar;
|
||||
|
||||
// volatile pointers to const vars
|
||||
|
||||
const char * volatile caveat = &laconic;
|
||||
const unsigned char * volatile covenant = &laggard;
|
||||
|
||||
// volatile pointers to const volatile vars
|
||||
|
||||
const volatile char * volatile vizier = &victor;
|
||||
const volatile unsigned char * volatile vanadium = &vicar;
|
||||
|
||||
// const volatile pointers
|
||||
|
||||
char * const volatile vane = &lave;
|
||||
unsigned char * const volatile veldt = &lavish;
|
||||
|
||||
// const volatile pointers to const vars
|
||||
|
||||
const char * const volatile cove = &laconic;
|
||||
const unsigned char * const volatile cavity = &laggard;
|
||||
|
||||
// const volatile pointers to volatile vars
|
||||
|
||||
volatile char * const volatile vagus = &vox;
|
||||
volatile unsigned char * const volatile vagrancy = &victuals;
|
||||
|
||||
// const volatile pointers to const volatile
|
||||
|
||||
const volatile char * const volatile vagary = &victor;
|
||||
const volatile unsigned char * const volatile vendor = &vicar;
|
||||
|
||||
// misc. references
|
||||
|
||||
const char & radiation = laconic;
|
||||
volatile signed char & remuneration = lemonade;
|
||||
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
marker1();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
void marker1 ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
char C, *pC, **ppC, ***pppC, ****ppppC, *****pppppC, ******ppppppC;
|
||||
unsigned char UC, *pUC;
|
||||
short S, *pS;
|
||||
unsigned short US, *pUS;
|
||||
int I, *pI;
|
||||
unsigned int UI, *pUI;
|
||||
long L, *pL;
|
||||
unsigned long UL, *pUL;
|
||||
float F, *pF;
|
||||
double D, *pD;
|
||||
C = 'A';
|
||||
UC = 21;
|
||||
S = -14;
|
||||
US = 7;
|
||||
I = 102;
|
||||
UI = 1002;
|
||||
L = -234;
|
||||
UL = 234;
|
||||
F = 1.25E10;
|
||||
D = -1.375E-123;
|
||||
pC = &C;
|
||||
ppC = &pC;
|
||||
pppC = &ppC;
|
||||
ppppC = &pppC;
|
||||
pppppC = &ppppC;
|
||||
ppppppC = &pppppC;
|
||||
pUC = &UC;
|
||||
pS = &S;
|
||||
pUS = &US;
|
||||
pI = &I;
|
||||
pUI = &UI;
|
||||
pL = &L;
|
||||
pUL = &UL;
|
||||
pF = &F;
|
||||
pD = &D;
|
||||
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
marker1();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/* A test */
|
||||
|
||||
#include "ss.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern int shr1();
|
||||
extern int shr2();
|
||||
extern float sg;
|
||||
|
||||
int eglob;
|
||||
|
||||
struct {
|
||||
int a;
|
||||
int b;
|
||||
} s;
|
||||
|
||||
int g;
|
||||
|
||||
int local_structarg(x)
|
||||
struct s x;
|
||||
{
|
||||
return x.b;
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
struct s y;
|
||||
g = 1;
|
||||
g = shr1(g);
|
||||
g = shr2(g);
|
||||
g = mainshr1(g);
|
||||
sg = 1.1;
|
||||
printf("address of sg is 0x%x\n", &sg);
|
||||
y.a = 3;
|
||||
y.b = 4;
|
||||
g = local_structarg(y);
|
||||
g = structarg(y);
|
||||
g = pstructarg(&y);
|
||||
}
|
||||
|
||||
int mainshr1(g)
|
||||
int g;
|
||||
{
|
||||
return 2*g;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/* This program is intended to be started outside of gdb, and then
|
||||
attached to by gdb. Thus, it simply spins in a loop. The loop
|
||||
is exited when & if the variable 'should_exit' is non-zero. (It
|
||||
is initialized to zero in this program, so the loop will never
|
||||
exit unless/until gdb sets the variable to non-zero.)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
int should_exit = 0;
|
||||
|
||||
main ()
|
||||
{
|
||||
int local_i = 0;
|
||||
|
||||
while (! should_exit)
|
||||
{
|
||||
local_i++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* This program is intended to be started outside of gdb, and then
|
||||
attached to by gdb. Thus, it simply spins in a loop. The loop
|
||||
is exited when & if the variable 'should_exit' is non-zero. (It
|
||||
is initialized to zero in this program, so the loop will never
|
||||
exit unless/until gdb sets the variable to non-zero.)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int should_exit = 0;
|
||||
|
||||
main ()
|
||||
{
|
||||
int local_i = 0;
|
||||
|
||||
sleep( 10 ); /* System call causes register fetch to fail */
|
||||
/* This is a known HPUX "feature" */
|
||||
while (! should_exit)
|
||||
{
|
||||
local_i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/* This is a sample program for the HP WDB debugger. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define num 10
|
||||
|
||||
static int my_list[num] = {3,4,2,0,2,1,8,3,6,7};
|
||||
|
||||
#ifdef __STDC__
|
||||
void print_average(int list[], int low, int high)
|
||||
#else
|
||||
void print_average(list, low, high)
|
||||
int list[], low, high;
|
||||
#endif
|
||||
{
|
||||
int total, num_elements, average;
|
||||
total = sum(list, low, high);
|
||||
num_elements = high - low; /* note this is an off-by-one bug */
|
||||
|
||||
average = total / num_elements;
|
||||
printf("%10.d\n", average);
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
int main(void)
|
||||
#else
|
||||
main ()
|
||||
#endif
|
||||
{
|
||||
char c;
|
||||
int first = 0;
|
||||
int last = num-1;
|
||||
|
||||
/* Try two test cases. */
|
||||
print_average (my_list, first, last);
|
||||
print_average (my_list, first, last - 3);
|
||||
foo:
|
||||
exit(0);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* Often the behavior of any particular test depends upon what compiler was
|
||||
used to compile the test. As each test is compiled, this file is
|
||||
preprocessed by the same compiler used to compile that specific test
|
||||
(different tests might be compiled by different compilers, particularly
|
||||
if compiled at different times), and used to generate a *.ci (compiler
|
||||
info) file for that test.
|
||||
|
||||
I.E., when callfuncs is compiled, a callfuncs.ci file will be generated,
|
||||
which can then be sourced by callfuncs.exp to give callfuncs.exp access
|
||||
to information about the compilation environment.
|
||||
|
||||
TODO: It might be a good idea to add expect code that tests each
|
||||
definition made with 'set" to see if one already exists, and if so
|
||||
warn about conflicts if it is being set to something else. */
|
||||
|
||||
/* This needs to be kept in sync with whatis.c and gdb.exp(get_compiler_info).
|
||||
If this ends up being hairy, we could use a common header file. */
|
||||
|
||||
#if defined (__STDC__) || defined (_AIX)
|
||||
set signed_keyword_not_used 0
|
||||
#else
|
||||
set signed_keyword_not_used 1
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__)
|
||||
set gcc_compiled __GNUC__
|
||||
#else
|
||||
set gcc_compiled 0
|
||||
#endif
|
||||
|
||||
return 0
|
|
@ -0,0 +1,34 @@
|
|||
/* Often the behavior of any particular test depends upon what compiler was
|
||||
used to compile the test. As each test is compiled, this file is
|
||||
preprocessed by the same compiler used to compile that specific test
|
||||
(different tests might be compiled by different compilers, particularly
|
||||
if compiled at different times), and used to generate a *.ci (compiler
|
||||
info) file for that test.
|
||||
|
||||
I.E., when callfuncs is compiled, a callfuncs.ci file will be generated,
|
||||
which can then be sourced by callfuncs.exp to give callfuncs.exp access
|
||||
to information about the compilation environment.
|
||||
|
||||
TODO: It might be a good idea to add expect code that tests each
|
||||
definition made with 'set" to see if one already exists, and if so
|
||||
warn about conflicts if it is being set to something else. */
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 6
|
||||
set supports_template_debugging 1
|
||||
#else
|
||||
set supports_template_debugging 0
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
set supports_template_debugging 1
|
||||
#else
|
||||
set supports_template_debugging 0
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__)
|
||||
set gcc_compiled __GNUC__
|
||||
#else
|
||||
set gcc_compiled 0
|
||||
#endif
|
||||
|
||||
return 0
|
|
@ -0,0 +1,28 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/* There is a global_i in follow_exec, which exec's us. We
|
||||
should not be able to see that other definition of global_i
|
||||
after we are exec'd.
|
||||
*/
|
||||
int global_i = 0;
|
||||
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char * argv[];
|
||||
{
|
||||
/* There is a local_j in follow_exec, which exec's us. We
|
||||
should not be able to see that other definition of local_j
|
||||
after we are exec'd.
|
||||
*/
|
||||
int local_j = argc;
|
||||
char * s;
|
||||
|
||||
printf ("Hello from execd_program...\n");
|
||||
if (argc != 2)
|
||||
{
|
||||
printf ("expected one string argument\n");
|
||||
exit (-1);
|
||||
}
|
||||
s = argv[1];
|
||||
printf ("argument received: %s\n", s);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int global_i = 100;
|
||||
|
||||
main ()
|
||||
{
|
||||
int local_j = global_i+1;
|
||||
int local_k = local_j+1;
|
||||
|
||||
printf ("follow-exec is about to execlp(execd-program)...\n");
|
||||
|
||||
execlp ("gdb.hp/execd-program",
|
||||
"gdb.hp/execd-program",
|
||||
"execlp arg1 from follow-exec",
|
||||
(char *)0);
|
||||
|
||||
printf ("follow-exec is about to execl(execd-program)...\n");
|
||||
|
||||
execl ("gdb.hp/execd-program",
|
||||
"gdb.hp/execd-program",
|
||||
"execl arg1 from follow-exec",
|
||||
"execl arg2 from follow-exec",
|
||||
(char *)0);
|
||||
|
||||
{
|
||||
static char * argv[] = {
|
||||
"gdb.hp/execd-program",
|
||||
"execv arg1 from follow-exec",
|
||||
0};
|
||||
|
||||
printf ("follow-exec is about to execv(execd-program)...\n");
|
||||
|
||||
execv ("gdb.hp/execd-program", argv);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void callee (i)
|
||||
int i;
|
||||
{
|
||||
printf("callee: %d\n", i);
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
int pid;
|
||||
int v = 5;
|
||||
|
||||
pid = fork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
v++;
|
||||
/* printf ("I'm the child!\n"); */
|
||||
}
|
||||
else
|
||||
{
|
||||
v--;
|
||||
/* printf ("I'm the proud parent of child #%d!\n", pid); */
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#include <stdio.h>
|
||||
|
||||
main ()
|
||||
{
|
||||
int pid;
|
||||
|
||||
pid = vfork ();
|
||||
if (pid == 0) {
|
||||
printf ("I'm the child!\n");
|
||||
execlp ("gdb.hp/vforked-program", "gdb.hp/vforked-program", (char *)0);
|
||||
}
|
||||
else {
|
||||
printf ("I'm the proud parent of child #%d!\n", pid);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,514 @@
|
|||
// Test various -*- C++ -*- things.
|
||||
|
||||
typedef struct fleep fleep;
|
||||
struct fleep { int a; } s;
|
||||
|
||||
// ====================== simple class structures =======================
|
||||
|
||||
struct default_public_struct {
|
||||
// defaults to public:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
struct explicit_public_struct {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
struct protected_struct {
|
||||
protected:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
struct private_struct {
|
||||
private:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
struct mixed_protection_struct {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
private:
|
||||
int c;
|
||||
int d;
|
||||
protected:
|
||||
int e;
|
||||
int f;
|
||||
public:
|
||||
int g;
|
||||
private:
|
||||
int h;
|
||||
protected:
|
||||
int i;
|
||||
};
|
||||
|
||||
class public_class {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
class protected_class {
|
||||
protected:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
class default_private_class {
|
||||
// defaults to private:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
class explicit_private_class {
|
||||
private:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
class mixed_protection_class {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
private:
|
||||
int c;
|
||||
int d;
|
||||
protected:
|
||||
int e;
|
||||
int f;
|
||||
public:
|
||||
int g;
|
||||
private:
|
||||
int h;
|
||||
protected:
|
||||
int i;
|
||||
};
|
||||
|
||||
class const_vol_method_class {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
int foo (int &) const;
|
||||
int bar (int &) volatile;
|
||||
int baz (int &) const volatile;
|
||||
};
|
||||
|
||||
int const_vol_method_class::foo (int & ir) const
|
||||
{
|
||||
return ir + 3;
|
||||
}
|
||||
int const_vol_method_class::bar (int & ir) volatile
|
||||
{
|
||||
return ir + 4;
|
||||
}
|
||||
int const_vol_method_class::baz (int & ir) const volatile
|
||||
{
|
||||
return ir + 5;
|
||||
}
|
||||
|
||||
// ========================= simple inheritance ==========================
|
||||
|
||||
class A {
|
||||
public:
|
||||
int a;
|
||||
int x;
|
||||
};
|
||||
|
||||
A g_A;
|
||||
|
||||
class B : public A {
|
||||
public:
|
||||
int b;
|
||||
int x;
|
||||
};
|
||||
|
||||
B g_B;
|
||||
|
||||
class C : public A {
|
||||
public:
|
||||
int c;
|
||||
int x;
|
||||
};
|
||||
|
||||
C g_C;
|
||||
|
||||
class D : public B, public C {
|
||||
public:
|
||||
int d;
|
||||
int x;
|
||||
};
|
||||
|
||||
D g_D;
|
||||
|
||||
class E : public D {
|
||||
public:
|
||||
int e;
|
||||
int x;
|
||||
};
|
||||
|
||||
E g_E;
|
||||
|
||||
class class_with_anon_union
|
||||
{
|
||||
public:
|
||||
int one;
|
||||
union
|
||||
{
|
||||
int a;
|
||||
long b;
|
||||
};
|
||||
};
|
||||
|
||||
class_with_anon_union g_anon_union;
|
||||
|
||||
void inheritance2 (void)
|
||||
{
|
||||
}
|
||||
|
||||
void inheritance1 (void)
|
||||
{
|
||||
int ival;
|
||||
int *intp;
|
||||
|
||||
// {A::a, A::x}
|
||||
|
||||
g_A.A::a = 1;
|
||||
g_A.A::x = 2;
|
||||
|
||||
// {{A::a,A::x},B::b,B::x}
|
||||
|
||||
g_B.A::a = 3;
|
||||
g_B.A::x = 4;
|
||||
g_B.B::b = 5;
|
||||
g_B.B::x = 6;
|
||||
|
||||
// {{A::a,A::x},C::c,C::x}
|
||||
|
||||
g_C.A::a = 7;
|
||||
g_C.A::x = 8;
|
||||
g_C.C::c = 9;
|
||||
g_C.C::x = 10;
|
||||
|
||||
// {{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}
|
||||
|
||||
// The following initialization code is non-portable, but allows us
|
||||
// to initialize all members of g_D until we can fill in the missing
|
||||
// initialization code with legal C++ code.
|
||||
|
||||
for (intp = (int *) &g_D, ival = 11;
|
||||
intp < ((int *) &g_D + sizeof (g_D) / sizeof (int));
|
||||
intp++, ival++)
|
||||
{
|
||||
*intp = ival;
|
||||
}
|
||||
|
||||
// Overlay the nonportable initialization with legal initialization.
|
||||
|
||||
// ????? = 11; (g_D.A::a = 11; is ambiguous)
|
||||
// ????? = 12; (g_D.A::x = 12; is ambiguous)
|
||||
g_D.B::b = 13;
|
||||
g_D.B::x = 14;
|
||||
// ????? = 15;
|
||||
// ????? = 16;
|
||||
g_D.C::c = 17;
|
||||
g_D.C::x = 18;
|
||||
g_D.D::d = 19;
|
||||
g_D.D::x = 20;
|
||||
|
||||
|
||||
// {{{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}},E::e,E::x}
|
||||
|
||||
// The following initialization code is non-portable, but allows us
|
||||
// to initialize all members of g_D until we can fill in the missing
|
||||
// initialization code with legal C++ code.
|
||||
|
||||
for (intp = (int *) &g_E, ival = 21;
|
||||
intp < ((int *) &g_E + sizeof (g_E) / sizeof (int));
|
||||
intp++, ival++)
|
||||
{
|
||||
*intp = ival;
|
||||
}
|
||||
|
||||
// Overlay the nonportable initialization with legal initialization.
|
||||
|
||||
// ????? = 21; (g_E.A::a = 21; is ambiguous)
|
||||
// ????? = 22; (g_E.A::x = 22; is ambiguous)
|
||||
g_E.B::b = 23;
|
||||
g_E.B::x = 24;
|
||||
// ????? = 25;
|
||||
// ????? = 26;
|
||||
g_E.C::c = 27;
|
||||
g_E.C::x = 28;
|
||||
g_E.D::d = 29;
|
||||
g_E.D::x = 30;
|
||||
g_E.E::e = 31;
|
||||
g_E.E::x = 32;
|
||||
|
||||
g_anon_union.one = 1;
|
||||
g_anon_union.a = 2;
|
||||
|
||||
inheritance2 ();
|
||||
}
|
||||
|
||||
// ======================== virtual base classes=========================
|
||||
|
||||
class vA {
|
||||
public:
|
||||
int va;
|
||||
int vx;
|
||||
};
|
||||
|
||||
vA g_vA;
|
||||
|
||||
class vB : public virtual vA {
|
||||
public:
|
||||
int vb;
|
||||
int vx;
|
||||
};
|
||||
|
||||
vB g_vB;
|
||||
|
||||
class vC : public virtual vA {
|
||||
public:
|
||||
int vc;
|
||||
int vx;
|
||||
};
|
||||
|
||||
vC g_vC;
|
||||
|
||||
class vD : public virtual vB, public virtual vC {
|
||||
public:
|
||||
int vd;
|
||||
int vx;
|
||||
};
|
||||
|
||||
vD g_vD;
|
||||
|
||||
class vE : public virtual vD {
|
||||
public:
|
||||
int ve;
|
||||
int vx;
|
||||
};
|
||||
|
||||
vE g_vE;
|
||||
|
||||
void inheritance4 (void)
|
||||
{
|
||||
}
|
||||
|
||||
void inheritance3 (void)
|
||||
{
|
||||
int ival;
|
||||
int *intp;
|
||||
|
||||
// {vA::va, vA::vx}
|
||||
|
||||
g_vA.vA::va = 1;
|
||||
g_vA.vA::vx = 2;
|
||||
|
||||
// {{vA::va, vA::vx}, vB::vb, vB::vx}
|
||||
|
||||
g_vB.vA::va = 3;
|
||||
g_vB.vA::vx = 4;
|
||||
g_vB.vB::vb = 5;
|
||||
g_vB.vB::vx = 6;
|
||||
|
||||
// {{vA::va, vA::vx}, vC::vc, vC::vx}
|
||||
|
||||
g_vC.vA::va = 7;
|
||||
g_vC.vA::vx = 8;
|
||||
g_vC.vC::vc = 9;
|
||||
g_vC.vC::vx = 10;
|
||||
|
||||
// {{{{vA::va, vA::vx}, vB::vb, vB::vx}, vC::vc, vC::vx}, vD::vd,vD::vx}
|
||||
|
||||
g_vD.vA::va = 11;
|
||||
g_vD.vA::vx = 12;
|
||||
g_vD.vB::vb = 13;
|
||||
g_vD.vB::vx = 14;
|
||||
g_vD.vC::vc = 15;
|
||||
g_vD.vC::vx = 16;
|
||||
g_vD.vD::vd = 17;
|
||||
g_vD.vD::vx = 18;
|
||||
|
||||
|
||||
// {{{{{vA::va,vA::vx},vB::vb,vB::vx},vC::vc,vC::vx},vD::vd,vD::vx},vE::ve,vE::vx}
|
||||
|
||||
g_vD.vA::va = 19;
|
||||
g_vD.vA::vx = 20;
|
||||
g_vD.vB::vb = 21;
|
||||
g_vD.vB::vx = 22;
|
||||
g_vD.vC::vc = 23;
|
||||
g_vD.vC::vx = 24;
|
||||
g_vD.vD::vd = 25;
|
||||
g_vD.vD::vx = 26;
|
||||
g_vE.vE::ve = 27;
|
||||
g_vE.vE::vx = 28;
|
||||
|
||||
inheritance4 ();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Base1 {
|
||||
public:
|
||||
int x;
|
||||
Base1(int i) { x = i; }
|
||||
};
|
||||
|
||||
class Foo
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
int y;
|
||||
static int st;
|
||||
Foo (int i, int j) { x = i; y = j; }
|
||||
int operator! ();
|
||||
operator int ();
|
||||
int times (int y);
|
||||
};
|
||||
|
||||
class Bar : public Base1, public Foo {
|
||||
public:
|
||||
int z;
|
||||
Bar (int i, int j, int k) : Base1 (10*k), Foo (i, j) { z = k; }
|
||||
};
|
||||
|
||||
class ClassWithEnum {
|
||||
public:
|
||||
enum PrivEnum { red, green, blue, yellow = 42 };
|
||||
PrivEnum priv_enum;
|
||||
int x;
|
||||
};
|
||||
|
||||
int Foo::operator! () { return !x; }
|
||||
|
||||
int Foo::times (int y) { return x * y; }
|
||||
|
||||
int Foo::st = 100;
|
||||
|
||||
Foo::operator int() { return x; }
|
||||
|
||||
Foo foo(10, 11);
|
||||
Bar bar(20, 21, 22);
|
||||
|
||||
class Contains_static_instance
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
int y;
|
||||
Contains_static_instance (int i, int j) { x = i; y = j; }
|
||||
static Contains_static_instance null;
|
||||
};
|
||||
|
||||
Contains_static_instance Contains_static_instance::null(0,0);
|
||||
Contains_static_instance csi(10,20);
|
||||
|
||||
class Contains_nested_static_instance
|
||||
{
|
||||
public:
|
||||
class Nested
|
||||
{
|
||||
public:
|
||||
Nested(int i) : z(i) {}
|
||||
int z;
|
||||
static Contains_nested_static_instance xx;
|
||||
};
|
||||
|
||||
Contains_nested_static_instance(int i, int j) : x(i), y(j) {}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
|
||||
static Contains_nested_static_instance null;
|
||||
static Nested yy;
|
||||
};
|
||||
|
||||
Contains_nested_static_instance Contains_nested_static_instance::null(0, 0);
|
||||
Contains_nested_static_instance::Nested Contains_nested_static_instance::yy(5);
|
||||
Contains_nested_static_instance
|
||||
Contains_nested_static_instance::Nested::xx(1,2);
|
||||
Contains_nested_static_instance cnsi(30,40);
|
||||
|
||||
typedef struct {
|
||||
int one;
|
||||
int two;
|
||||
} tagless_struct;
|
||||
tagless_struct v_tagless;
|
||||
|
||||
/* Try to get the compiler to allocate a class in a register. */
|
||||
class small {
|
||||
public:
|
||||
int x;
|
||||
int method ();
|
||||
};
|
||||
int small::method ()
|
||||
{
|
||||
return x + 5;
|
||||
}
|
||||
void marker_reg1 () {}
|
||||
|
||||
int
|
||||
register_class ()
|
||||
{
|
||||
/* We don't call any methods for v, so gcc version cygnus-2.3.3-930220
|
||||
might put this variable in a register. This is a lose, though, because
|
||||
it means that GDB can't call any methods for that variable. */
|
||||
register small v;
|
||||
|
||||
int i;
|
||||
|
||||
/* Perform a computation sufficiently complicated that optimizing compilers
|
||||
won't optimized out the variable. If some compiler constant-folds this
|
||||
whole loop, maybe using a parameter to this function here would help. */
|
||||
v.x = 0;
|
||||
for (i = 0; i < 13; ++i)
|
||||
v.x += i;
|
||||
--v.x; /* v.x is now 77 */
|
||||
marker_reg1 ();
|
||||
return v.x + 5;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
inheritance1 ();
|
||||
inheritance3 ();
|
||||
register_class ();
|
||||
|
||||
/* FIXME: pmi gets optimized out. Need to do some more computation with
|
||||
it or something. (No one notices, because the test is xfail'd anyway,
|
||||
but that probably won't always be true...). */
|
||||
int Foo::* pmi = &Foo::y;
|
||||
|
||||
/* Make sure the AIX linker doesn't remove the variable. */
|
||||
v_tagless.one = 5;
|
||||
|
||||
/* Class with enumeration inside it */
|
||||
ClassWithEnum obj_with_enum;
|
||||
obj_with_enum.priv_enum = ClassWithEnum::green;
|
||||
|
||||
return foo.*pmi;
|
||||
}
|
||||
|
||||
/* Create an instance for some classes, otherwise they get optimized away. */
|
||||
|
||||
default_public_struct default_public_s;
|
||||
explicit_public_struct explicit_public_s;
|
||||
protected_struct protected_s;
|
||||
private_struct private_s;
|
||||
mixed_protection_struct mixed_protection_s;
|
||||
public_class public_c;
|
||||
protected_class protected_c;
|
||||
default_private_class default_private_c;
|
||||
explicit_private_class explicit_private_c;
|
||||
mixed_protection_class mixed_protection_c;
|
|
@ -0,0 +1,140 @@
|
|||
/* BeginSourceFile more_steps.c
|
||||
|
||||
This file creates a lot of threads which then execute
|
||||
in parallel, so that wdb can be tested on handling
|
||||
simultaneous thread events.
|
||||
|
||||
To compile:
|
||||
|
||||
cc -Ae +DA1.0 -g -o more_steps -lpthread more_steps.c
|
||||
|
||||
To run:
|
||||
|
||||
more_threads
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define N_THREADS 3
|
||||
#define PHASES 3
|
||||
|
||||
typedef enum {
|
||||
ZERO,
|
||||
ONE,
|
||||
TWO,
|
||||
THREE
|
||||
} phase_t;
|
||||
|
||||
/* Uncomment to turn on debugging output */
|
||||
/* #define DEBUG */
|
||||
|
||||
/* Locks.
|
||||
*/
|
||||
int lock_one; /* Main W, others R */
|
||||
int lock_two; /* ditto */
|
||||
int lock_end[ N_THREADS ]; /* Main R, others R[i] */
|
||||
int phase[ N_THREADS ];
|
||||
|
||||
/* Routine for each thread to run.
|
||||
*/
|
||||
void *spin( vp )
|
||||
void * vp;
|
||||
{
|
||||
int me = (int) vp;
|
||||
int i;
|
||||
|
||||
lock_end[ me ] = TRUE;
|
||||
|
||||
phase[ me ] = ONE;
|
||||
|
||||
while( lock_one );
|
||||
|
||||
phase[ me ] = TWO;
|
||||
|
||||
while( lock_two );
|
||||
|
||||
phase[ me ] = THREE;
|
||||
|
||||
lock_end[ me ] = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
do_pass()
|
||||
{
|
||||
int i;
|
||||
pthread_t t[ N_THREADS ];
|
||||
int err;
|
||||
int done;
|
||||
|
||||
/* Start N_THREADS threads, then join them so
|
||||
* that they are terminated.
|
||||
*/
|
||||
for( i = 0; i < N_THREADS; i++ ) {
|
||||
err = pthread_create( &t[i], NULL, spin, (void *)i );
|
||||
if( err != 0 ) {
|
||||
printf( "== Start/stop, error in thread %d create\n", i );
|
||||
}
|
||||
}
|
||||
|
||||
/* Do phase 1.
|
||||
*/
|
||||
lock_one = FALSE;
|
||||
|
||||
/* Do phase 2.
|
||||
*/
|
||||
lock_two = FALSE;
|
||||
|
||||
/* Be done.
|
||||
*/
|
||||
done = 0;
|
||||
while( !done ) {
|
||||
|
||||
/* Be optimistic.
|
||||
*/
|
||||
done = 1;
|
||||
for( i = 0; i < N_THREADS; i++ ) {
|
||||
if( lock_end[i] ) {
|
||||
/* Thread "i" is not ready yet.
|
||||
*/
|
||||
done = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish up
|
||||
*/
|
||||
for( i = 0; i < N_THREADS; i++ ) {
|
||||
err = pthread_join(t[i], NULL ); /* Line 105 */
|
||||
if( err != 0 ) { /* Line 106 */
|
||||
printf( "== Start/stop, error in thread %d join\n", i );
|
||||
}
|
||||
}
|
||||
|
||||
i = 10; /* Line 109. Null line for setting bpts on. */
|
||||
}
|
||||
|
||||
main( argc, argv )
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Init
|
||||
*/
|
||||
lock_one = TRUE;
|
||||
lock_two = TRUE;
|
||||
for( i = 0; i < N_THREADS; i++ ) {
|
||||
lock_end[i] = TRUE;
|
||||
phase[i] = ZERO;
|
||||
}
|
||||
|
||||
do_pass();
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/* Source for debugging optimimzed code test.
|
||||
|
||||
cc -g -O -o optimize optimize.c
|
||||
*/
|
||||
int callee();
|
||||
int test_opt;
|
||||
|
||||
int main()
|
||||
{
|
||||
int a,b,c,d,e,f,g,h;
|
||||
|
||||
a = 10;;
|
||||
|
||||
/* Value propagate
|
||||
*/
|
||||
b = 2 * a + 1;
|
||||
c = 3 * b + 2;
|
||||
|
||||
/* Re-use expressions
|
||||
*/
|
||||
d = (2 * a + 1) * (3 * b + 2);
|
||||
e = (2 * a + 1) * (3 * b + 2);
|
||||
|
||||
/* Create dead stores--do lines still exist?
|
||||
*/
|
||||
d = (2 * a + 1) * (3 * b + 2);
|
||||
e = (2 * a + 1) * (3 * b + 2);
|
||||
d = (2 * a + 1) * (3 * b + 2);
|
||||
e = (2 * a + 1) * (3 * b + 2);
|
||||
|
||||
/* Alpha and psi motion
|
||||
*/
|
||||
if( test_opt ) {
|
||||
f = e - d;
|
||||
f = f--;
|
||||
}
|
||||
else {
|
||||
f = e - d;
|
||||
f = f + d * e;
|
||||
}
|
||||
|
||||
/* Chi and Rho motion
|
||||
*/
|
||||
h = 0;
|
||||
do {
|
||||
h++;
|
||||
a = b * c + d * e; /* Chi */
|
||||
f = f + d * e;
|
||||
g = f + d * e; /* Rho */
|
||||
callee( g+1 );
|
||||
test_opt = (test_opt != 1); /* Cycles */
|
||||
} while( g && h < 10);
|
||||
|
||||
/* Opps for tail recursion, unrolling,
|
||||
* folding, evaporating
|
||||
*/
|
||||
for( a = 0; a < 100; a++ ) {
|
||||
callee( callee ( callee( a )));
|
||||
callee( callee ( callee( a )));
|
||||
callee( callee ( callee( a )));
|
||||
}
|
||||
|
||||
return callee( test_opt );
|
||||
}
|
||||
|
||||
/* defined late to keep line numbers the same
|
||||
*/
|
||||
int callee( x )
|
||||
int x; /* not used! */
|
||||
{
|
||||
test_opt++; /* side effect */
|
||||
|
||||
return test_opt;
|
||||
}
|
||||
|
||||
/* end */
|
|
@ -0,0 +1,284 @@
|
|||
/* BeginSourceFile quicksort.c
|
||||
|
||||
This file is take from the DDE test system. It spawns six
|
||||
threads to do a sort of an array of random numbers.
|
||||
|
||||
The locations marked "quick N" are used in the test "quicksort.exp".
|
||||
|
||||
The locations marked "att N" are used in the test "attach.exp".
|
||||
|
||||
To compile:
|
||||
|
||||
cc -Ae +DA1.0 -g -o quicksort -lpthread quicksort.c
|
||||
|
||||
To run:
|
||||
|
||||
quicksort --normal run
|
||||
quicksort 1 --waits before starting to allow attach
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define SORTSET 100000
|
||||
|
||||
/* Uncomment to turn on debugging output */
|
||||
/* #define QUICK_DEBUG */
|
||||
|
||||
/* Uncomment to turn on wait on each thread create */
|
||||
/* #define THREAD_WAIT */
|
||||
|
||||
/* Fewer than SORT_DIRECT items are sorted with an insertion sort. */
|
||||
#define SORT_DIRECT 20
|
||||
|
||||
/* Work at this depth or less generates a separate work item. */
|
||||
#define DEFER_DEPTH 6
|
||||
|
||||
/* Workpile controller */
|
||||
typedef void (*work_proc_t)(void *);
|
||||
|
||||
typedef struct workpile_struct {
|
||||
pthread_mutex_t lock; /* mutex for this structure */
|
||||
pthread_cond_t work_wait; /* workers waiting for work */
|
||||
pthread_cond_t finish_wait; /* to wait for workers to finish */
|
||||
int max_pile; /* length of workpile array */
|
||||
work_proc_t worker_proc; /* work procedure */
|
||||
int n_working; /* number of workers working */
|
||||
int n_waiting; /* number of workers waiting for work */
|
||||
int n_pile; /* number of pointers in the workpile */
|
||||
int inp; /* FIFO input pointer */
|
||||
int outp; /* FIFO output pointer */
|
||||
void *pile[1]; /* array of pointers - the workpile */
|
||||
} *workpile_t;
|
||||
|
||||
typedef struct {
|
||||
float *data; /* Array to sort */
|
||||
int n; /* Number of elements in the array */
|
||||
int depth; /* Depth of recursion */
|
||||
workpile_t wp; /* Workpile to use */
|
||||
} quick_sort_args;
|
||||
|
||||
/* True if waiting for attach.
|
||||
*/
|
||||
int wait_here = FALSE;
|
||||
|
||||
static workpile_t quick_sort_workpile = NULL;
|
||||
|
||||
void *worker(void * wptr);
|
||||
|
||||
/* Allocates and initializes a workpile that holds max_pile entries.
|
||||
* worker_proc is called to process each work item on the queue.
|
||||
*/
|
||||
workpile_t
|
||||
work_init(int max_pile, work_proc_t worker_proc, int n_threads)
|
||||
{
|
||||
int err;
|
||||
pthread_t t;
|
||||
workpile_t wp = (workpile_t)
|
||||
malloc(sizeof (struct workpile_struct) +
|
||||
(max_pile * sizeof (void *)));
|
||||
|
||||
if (wp != NULL) {
|
||||
pthread_mutex_init(&wp->lock, NULL);
|
||||
pthread_cond_init(&wp->work_wait, NULL);
|
||||
pthread_cond_init(&wp->finish_wait, NULL);
|
||||
wp->max_pile = max_pile;
|
||||
wp->worker_proc = worker_proc;
|
||||
wp->n_working = wp->n_waiting = wp->n_pile = 0;
|
||||
wp->inp = wp->outp = 0;
|
||||
while (n_threads--) {
|
||||
err = pthread_create(&t, NULL,
|
||||
worker, (void *)&wp);
|
||||
#ifdef QUICK_DEBUG
|
||||
printf( "== Quicksort: created new thread\n" );
|
||||
#ifdef THREAD_WAIT
|
||||
if( n_threads > 0 ) {
|
||||
int i;
|
||||
printf( "== Quicksort: waiting on user input of an integer\n" );
|
||||
scanf( "%d", &i );
|
||||
printf( "== Quicksort: continuing with quicksort\n" );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
assert(err == 0); /* quick 1 */
|
||||
}
|
||||
/* All the threads have now been created.
|
||||
*/
|
||||
assert( n_threads == -1 ); /* att 1 */
|
||||
if( wait_here ) {
|
||||
#ifdef QUICK_DEBUG
|
||||
printf( "== Quicksort: waiting for attach\n" );
|
||||
#endif
|
||||
sleep( 25 );
|
||||
}
|
||||
wait_here = 99; /* att 2, otherwise useless */
|
||||
}
|
||||
return (wp); /* quick 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Worker thread routine. Continuously looks for work, calls the
|
||||
* worker_proc associated with the workpile to do work.
|
||||
*/
|
||||
void *
|
||||
worker(void * wptr)
|
||||
{
|
||||
workpile_t wp;
|
||||
void *ptr;
|
||||
|
||||
wp = * (workpile_t *) wptr;
|
||||
|
||||
pthread_mutex_lock(&wp->lock);
|
||||
wp->n_working++;
|
||||
for (;;) {
|
||||
while (wp->n_pile == 0) { /* wait for new work */
|
||||
if (--wp->n_working == 0)
|
||||
pthread_cond_signal(&wp->finish_wait);
|
||||
wp->n_waiting++;
|
||||
pthread_cond_wait(&wp->work_wait, &wp->lock);
|
||||
wp->n_waiting--; /* quick 3 */
|
||||
wp->n_working++;
|
||||
}
|
||||
wp->n_pile--;
|
||||
ptr = wp->pile[wp->outp];
|
||||
wp->outp = (wp->outp + 1) % wp->max_pile;
|
||||
pthread_mutex_unlock(&wp->lock);
|
||||
/* Call application worker routine. */
|
||||
(*wp->worker_proc)(ptr);
|
||||
pthread_mutex_lock(&wp->lock); /* quick 4 */
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* Puts ptr in workpile. Called at the outset, or within a worker. */
|
||||
void
|
||||
work_put(workpile_t wp, void *ptr)
|
||||
{
|
||||
pthread_mutex_lock(&wp->lock);
|
||||
if (wp->n_waiting) {
|
||||
/* idle workers to be awakened */
|
||||
pthread_cond_signal(&wp->work_wait);
|
||||
}
|
||||
assert(wp->n_pile != wp->max_pile); /* check for room */
|
||||
wp->n_pile++;
|
||||
wp->pile[wp->inp] = ptr;
|
||||
wp->inp = (wp->inp + 1) % wp->max_pile;
|
||||
pthread_mutex_unlock(&wp->lock);
|
||||
}
|
||||
|
||||
|
||||
/* Wait until all work is done and workers quiesce. */
|
||||
void
|
||||
work_wait(workpile_t wp)
|
||||
{
|
||||
pthread_mutex_lock(&wp->lock);
|
||||
while(wp->n_pile !=0 || wp->n_working != 0)
|
||||
pthread_cond_wait(&wp->finish_wait, &wp->lock);
|
||||
pthread_mutex_unlock(&wp->lock);
|
||||
}
|
||||
|
||||
void
|
||||
quick_sort_aux(float *data, int n, int depth, workpile_t wp, int deferrable)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
/* If array small, use insertion sort */
|
||||
if (n <= SORT_DIRECT) {
|
||||
for (j = 1; j < n; j++) {
|
||||
/* data[0..j-1] in sort; find a spot for data[j] */
|
||||
float key = data[j];
|
||||
for (i = j - 1; i >= 0 && key < data[i]; i--)
|
||||
data[i+1] = data[i];
|
||||
data[i+1] = key;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Defer this work to work queue if policy says so */
|
||||
if (deferrable && depth <= DEFER_DEPTH) {
|
||||
quick_sort_args *q = (quick_sort_args *)
|
||||
malloc(sizeof (quick_sort_args));
|
||||
assert(q != NULL);
|
||||
q->data = data; q->n = n; q->depth = depth; q->wp = wp;
|
||||
work_put(wp, (void *)q);
|
||||
return;
|
||||
}
|
||||
/* Otherwise, partition data based on a median estimate */
|
||||
#define swap(i,j) {float t = data[i]; data[i] = data[j]; data[j] = t;}
|
||||
i = 0;
|
||||
j = n - 1;
|
||||
for (;;) {
|
||||
while (data[i] < data[j]) j--;
|
||||
if (i >= j) break;
|
||||
swap(i, j); i++;
|
||||
while (data[i] < data[j]) i++;
|
||||
if (i >= j) { i = j; break; }
|
||||
swap(i, j); j--;
|
||||
}
|
||||
/* Median value is now at data[i] */
|
||||
/* Partitioned so that data[0..i-1] <= median <= data[i+1..n-1] */
|
||||
quick_sort_aux(data, i, depth+1, wp, TRUE);
|
||||
quick_sort_aux(&data[i+1], n-i-1, depth+1, wp, TRUE);
|
||||
}
|
||||
/* Called from workpile controller with argument pointing to work. */
|
||||
void
|
||||
quick_sort_worker(void *a)
|
||||
{
|
||||
quick_sort_args *q = (quick_sort_args *)a;
|
||||
quick_sort_aux(q->data, q->n, q->depth, q->wp, FALSE);
|
||||
free(q);
|
||||
}
|
||||
/* Main routine, called by client to do a sort. */
|
||||
void
|
||||
quick_sort(float *data, int n)
|
||||
{
|
||||
if (quick_sort_workpile == NULL) {
|
||||
int n_threads = 6;
|
||||
quick_sort_workpile = work_init(2 << DEFER_DEPTH,
|
||||
quick_sort_worker, n_threads);
|
||||
assert(quick_sort_workpile != NULL);
|
||||
}
|
||||
|
||||
quick_sort_aux(data, n, 0, quick_sort_workpile, FALSE);
|
||||
|
||||
/* Wait for all work to finish */
|
||||
work_wait(quick_sort_workpile);
|
||||
|
||||
#ifdef QUICK_DEBUG
|
||||
printf( "== Quicksort: done sorting\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
main( argc, argv )
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
float data[SORTSET];
|
||||
int i; int debugging = 0;
|
||||
|
||||
if((argc > 1) && (0 != argv )) {
|
||||
if( 1 == atoi( argv[1] ) )
|
||||
wait_here = TRUE;
|
||||
}
|
||||
|
||||
for(i = 0; i < SORTSET; i++)
|
||||
data[SORTSET -1 -i] = drand48();
|
||||
|
||||
for(i = 0; i < SORTSET; i++)
|
||||
if (debugging)
|
||||
printf("data[%d] = %f\n", i, data[i]);
|
||||
|
||||
quick_sort(data, SORTSET);
|
||||
for(i = 0; i < SORTSET; i++)
|
||||
if (debugging)
|
||||
printf("data[%d] = %f\n", i, data[i]);
|
||||
|
||||
return(0);
|
||||
}
|
||||
/* EndSourceFile */
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* This simple classical example of recursion is useful for
|
||||
* testing stack backtraces and such.
|
||||
*/
|
||||
|
||||
#ifdef vxworks
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
/* VxWorks does not supply atoi. */
|
||||
static int
|
||||
atoi (z)
|
||||
char *z;
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (*z >= '0' && *z <= '9')
|
||||
i = i * 10 + (*z++ - '0');
|
||||
return i;
|
||||
}
|
||||
|
||||
/* I don't know of any way to pass an array to VxWorks. This function
|
||||
can be called directly from gdb. */
|
||||
|
||||
vxmain (arg)
|
||||
char *arg;
|
||||
{
|
||||
char *argv[2];
|
||||
|
||||
argv[0] = "";
|
||||
argv[1] = arg;
|
||||
main (2, argv, (char **) 0);
|
||||
}
|
||||
|
||||
#else /* ! vxworks */
|
||||
# include <stdio.h>
|
||||
#endif /* ! vxworks */
|
||||
|
||||
main (argc, argv, envp)
|
||||
int argc;
|
||||
char *argv[], **envp;
|
||||
{
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
#ifdef FAKEARGV
|
||||
printf ("%d\n", factorial (1));
|
||||
#else
|
||||
if (argc != 2) {
|
||||
printf ("usage: factorial <number>\n");
|
||||
return 1;
|
||||
} else {
|
||||
printf ("%d\n", factorial (atoi (argv[1])));
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int factorial (value)
|
||||
int value;
|
||||
{
|
||||
int local_var;
|
||||
|
||||
if (value > 1) {
|
||||
value *= factorial (value - 1);
|
||||
}
|
||||
local_var = value;
|
||||
return (value);
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
/* BeginSourceFile start_stop.c
|
||||
|
||||
This file creates and deletes threads, so that wdb
|
||||
can be tested on thread delete.
|
||||
|
||||
To compile:
|
||||
|
||||
cc -Ae +DA1.0 -g -o start_stop -lpthread start_stop.c
|
||||
|
||||
To run:
|
||||
|
||||
start_stop --normal run
|
||||
start_stop 1 --waits in each thread to keep it alive.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define OUTER_LOOP_COUNT 3
|
||||
#define N_THREADS 3
|
||||
#define MAX_LOCAL_VAL 40
|
||||
|
||||
/* Uncomment to turn on debugging output */
|
||||
/* #define START_DEBUG */
|
||||
|
||||
/* True if waiting for attach.
|
||||
*/
|
||||
int wait_here;
|
||||
|
||||
/* Thing to check for debugging purposes.
|
||||
*/
|
||||
int a_global = 0;
|
||||
|
||||
/* Thread-local storage.
|
||||
*/
|
||||
__thread int a_thread_local;
|
||||
|
||||
/* Check the results of thread-local storage.
|
||||
*/
|
||||
int thread_local_val[ N_THREADS ];
|
||||
int val_debugger_saw[ N_THREADS ];
|
||||
|
||||
/* Routine for each thread to run, does nothing.
|
||||
*/
|
||||
void *spin( vp )
|
||||
void * vp;
|
||||
{
|
||||
int me = (int) vp;
|
||||
int i;
|
||||
|
||||
#ifdef START_DEBUG
|
||||
printf( "== In thread %d\n", me );
|
||||
#endif
|
||||
|
||||
a_global++;
|
||||
|
||||
a_thread_local = 0;
|
||||
for( i = 0; i < a_global; i++ ) {
|
||||
a_thread_local += i;
|
||||
}
|
||||
|
||||
thread_local_val[ me ] = a_thread_local; /* Line 67 */
|
||||
|
||||
printf( "== Thread %d, a_thread_local is %d\n",
|
||||
(int) vp, a_thread_local );
|
||||
|
||||
if( wait_here ) {
|
||||
/* Extend life of thread to extend life of thread-local var.
|
||||
* This makes life easier for human debugging (though you'd
|
||||
* probably want to make the delay longer).
|
||||
*/
|
||||
sleep( 5 );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_pass( pass )
|
||||
int pass;
|
||||
{
|
||||
int i;
|
||||
pthread_t t[ N_THREADS ];
|
||||
int err;
|
||||
|
||||
for( i = 0; i < N_THREADS; i++) {
|
||||
thread_local_val[i] = 0;
|
||||
val_debugger_saw[i] = 0;
|
||||
}
|
||||
|
||||
/* Start N_THREADS threads, then join them so
|
||||
* that they are terminated.
|
||||
*/
|
||||
for( i = 0; i < N_THREADS; i++ ) {
|
||||
err = pthread_create( &t[i], NULL, spin, (void *)i );
|
||||
if( err != 0 ) {
|
||||
printf( "== Start/stop, error in thread %d create\n", i );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < N_THREADS; i++ ) {
|
||||
err = pthread_join(t[i], NULL ); /* Line 105 */
|
||||
if( err != 0 ) { /* Line 106 */
|
||||
printf( "== Start/stop, error in thread %d join\n", i );
|
||||
}
|
||||
}
|
||||
|
||||
i = 10; /* Line 109. Null line for setting bpts on. */
|
||||
|
||||
/*#ifdef START_DEBUG*/
|
||||
for( i = 0; i < N_THREADS; i++) {
|
||||
printf( " Local in thread %d was %d, debugger saw %d\n",
|
||||
i, thread_local_val[i], val_debugger_saw[i] );
|
||||
}
|
||||
printf( "== Pass %d done\n", pass );
|
||||
/*#endif*/
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
do_it()
|
||||
{
|
||||
/* We want to start some threads and then
|
||||
* end them, and then do it again and again
|
||||
*/
|
||||
int i;
|
||||
int dummy;
|
||||
|
||||
for( i = 0; i < OUTER_LOOP_COUNT; i++ ) {
|
||||
do_pass( i );
|
||||
dummy = i; /* Line 134, null line for setting bps on */
|
||||
}
|
||||
}
|
||||
|
||||
main( argc, argv )
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
wait_here = FALSE;
|
||||
if((argc > 1) && (0 != argv )) {
|
||||
if( 1 == atoi( argv[1] ) )
|
||||
wait_here = TRUE;
|
||||
}
|
||||
|
||||
#ifdef START_DEBUG
|
||||
printf( "== Test starting\n" );
|
||||
#endif
|
||||
|
||||
do_it();
|
||||
|
||||
#ifdef START_DEBUG
|
||||
printf( "== Test done\n" );
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* EndSourceFile */
|
|
@ -0,0 +1,15 @@
|
|||
/* This is a sample program for the HP/DDE debugger. */
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __STDC__
|
||||
int sum(int list[], int low, int high)
|
||||
#else
|
||||
int sum(list, low, high)
|
||||
int list[], low, high;
|
||||
#endif
|
||||
{
|
||||
int i, s = 0;
|
||||
for (i = low; i <= high; i++)
|
||||
s += list[i];
|
||||
return(s);
|
||||
}
|
|
@ -0,0 +1,785 @@
|
|||
/* This test code is from Wendell Baker (wbaker@comet.berkeley.edu) */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int a_i;
|
||||
char a_c;
|
||||
double a_d;
|
||||
|
||||
typedef void *Pix;
|
||||
|
||||
int
|
||||
f(int i)
|
||||
{ return 0; }
|
||||
|
||||
int
|
||||
f(int i, char c)
|
||||
{ return 0; }
|
||||
|
||||
int
|
||||
f(int i, char c, double d)
|
||||
{ return 0; }
|
||||
|
||||
int
|
||||
f(int i, char c, double d, char *cs)
|
||||
{ return 0; }
|
||||
|
||||
int
|
||||
f(int i, char c, double d, char *cs, void (*fig)(int, char))
|
||||
{ return 0; }
|
||||
|
||||
int
|
||||
f(int i, char c, double d, char *cs, void (*fig)(char, int))
|
||||
{ return 0; }
|
||||
|
||||
class R {
|
||||
public:
|
||||
int i;
|
||||
};
|
||||
class S {
|
||||
public:
|
||||
int i;
|
||||
};
|
||||
class T {
|
||||
public:
|
||||
int i;
|
||||
};
|
||||
|
||||
char g(char, const char, volatile char)
|
||||
{ return 'c'; }
|
||||
char g(R, char&, const char&, volatile char&)
|
||||
{ return 'c'; }
|
||||
char g(char*, const char*, volatile char*)
|
||||
{ return 'c'; }
|
||||
char g(S, char*&, const char*&, volatile char*&)
|
||||
{ return 'c'; }
|
||||
|
||||
signed char g(T,signed char, const signed char, volatile signed char)
|
||||
{ return 'c'; }
|
||||
signed char g(T, R, signed char&, const signed char&, volatile signed char&)
|
||||
{ return 'c'; }
|
||||
signed char g(T, signed char*, const signed char*, volatile signed char*)
|
||||
{ return 'c'; }
|
||||
signed char g(T, S, signed char*&, const signed char*&, volatile signed char*&)
|
||||
{ return 'c'; }
|
||||
|
||||
unsigned char g(unsigned char, const unsigned char, volatile unsigned char)
|
||||
{ return 'c'; }
|
||||
unsigned char g(R, unsigned char&, const unsigned char&, volatile unsigned char&)
|
||||
{ return 'c'; }
|
||||
unsigned char g(unsigned char*, const unsigned char*, volatile unsigned char*)
|
||||
{ return 'c'; }
|
||||
unsigned char g(S, unsigned char*&, const unsigned char*&, volatile unsigned char*&)
|
||||
{ return 'c'; }
|
||||
|
||||
short g(short, const short, volatile short)
|
||||
{ return 0; }
|
||||
short g(R, short&, const short&, volatile short&)
|
||||
{ return 0; }
|
||||
short g(short*, const short*, volatile short*)
|
||||
{ return 0; }
|
||||
short g(S, short*&, const short*&, volatile short*&)
|
||||
{ return 0; }
|
||||
|
||||
signed short g(T, signed short, const signed short, volatile signed short)
|
||||
{ return 0; }
|
||||
signed short g(T, R, signed short&, const signed short&, volatile signed short&)
|
||||
{ return 0; }
|
||||
signed short g(T, signed short*, const signed short*, volatile signed short*)
|
||||
{ return 0; }
|
||||
signed short g(T, S, double, signed short*&, const signed short*&, volatile signed short*&)
|
||||
{ return 0; }
|
||||
|
||||
unsigned short g(unsigned short, const unsigned short, volatile unsigned short)
|
||||
{ return 0; }
|
||||
unsigned short g(R, unsigned short&, const unsigned short&, volatile unsigned short&)
|
||||
{ return 0; }
|
||||
unsigned short g(unsigned short*, const unsigned short*, volatile unsigned short*)
|
||||
{ return 0; }
|
||||
unsigned short g(S, unsigned short*&, const unsigned short*&, volatile unsigned short*&)
|
||||
{ return 0; }
|
||||
|
||||
int g(int, const int, volatile int)
|
||||
{ return 0; }
|
||||
int g(R, int&, const int&, volatile int&)
|
||||
{ return 0; }
|
||||
int g(int*, const int*, volatile int*)
|
||||
{ return 0; }
|
||||
int g(S, int*&, const int*&, volatile int*&)
|
||||
{ return 0; }
|
||||
|
||||
signed int g(T, signed int, const signed int, volatile signed int)
|
||||
{ return 0; }
|
||||
signed int g(T, R, signed int&, const signed int&, volatile signed int&)
|
||||
{ return 0; }
|
||||
signed int g(T, signed int*, const signed int*, volatile signed int*)
|
||||
{ return 0; }
|
||||
signed int g(T, S, signed int*&, const signed int*&, volatile signed int*&)
|
||||
{ return 0; }
|
||||
|
||||
unsigned int g(unsigned int, const unsigned int, volatile unsigned int)
|
||||
{ return 0; }
|
||||
unsigned int g(R, unsigned int&, const unsigned int&, volatile unsigned int&)
|
||||
{ return 0; }
|
||||
unsigned int g(unsigned int*, const unsigned int*, volatile unsigned int*)
|
||||
{ return 0; }
|
||||
unsigned int g(S, unsigned int*&, const unsigned int*&, volatile unsigned int*&)
|
||||
{ return 0; }
|
||||
|
||||
long g(long, const long, volatile long)
|
||||
{ return 0; }
|
||||
long g(R, long&, const long&, volatile long&)
|
||||
{ return 0; }
|
||||
long g(long*, const long*, volatile long*)
|
||||
{ return 0; }
|
||||
long g(S, long*&, const long*&, volatile long*&)
|
||||
{ return 0; }
|
||||
|
||||
signed long g(T, signed long, const signed long, volatile signed long)
|
||||
{ return 0; }
|
||||
signed long g(T, R, signed long&, const signed long&, volatile signed long&)
|
||||
{ return 0; }
|
||||
signed long g(T, signed long*, const signed long*, volatile signed long*)
|
||||
{ return 0; }
|
||||
signed long g(T, S, signed long*&, const signed long*&, volatile signed long*&)
|
||||
{ return 0; }
|
||||
|
||||
unsigned long g(unsigned long, const unsigned long, volatile unsigned long)
|
||||
{ return 0; }
|
||||
unsigned long g(S, unsigned long&, const unsigned long&, volatile unsigned long&)
|
||||
{ return 0; }
|
||||
unsigned long g(unsigned long*, const unsigned long*, volatile unsigned long*)
|
||||
{ return 0; }
|
||||
unsigned long g(S, unsigned long*&, const unsigned long*&, volatile unsigned long*&)
|
||||
{ return 0; }
|
||||
|
||||
#ifdef __GNUC__
|
||||
long long g(long long, const long long, volatile long long)
|
||||
{ return 0; }
|
||||
long long g(S, long long&, const long long&, volatile long long&)
|
||||
{ return 0; }
|
||||
long long g(long long*, const long long*, volatile long long*)
|
||||
{ return 0; }
|
||||
long long g(R, long long*&, const long long*&, volatile long long*&)
|
||||
{ return 0; }
|
||||
|
||||
signed long long g(T, signed long long, const signed long long, volatile signed long long)
|
||||
{ return 0; }
|
||||
signed long long g(T, R, signed long long&, const signed long long&, volatile signed long long&)
|
||||
{ return 0; }
|
||||
signed long long g(T, signed long long*, const signed long long*, volatile signed long long*)
|
||||
{ return 0; }
|
||||
signed long long g(T, S, signed long long*&, const signed long long*&, volatile signed long long*&)
|
||||
{ return 0; }
|
||||
|
||||
unsigned long long g(unsigned long long, const unsigned long long, volatile unsigned long long)
|
||||
{ return 0; }
|
||||
unsigned long long g(R, unsigned long long*, const unsigned long long*, volatile unsigned long long*)
|
||||
{ return 0; }
|
||||
unsigned long long g(unsigned long long&, const unsigned long long&, volatile unsigned long long&)
|
||||
{ return 0; }
|
||||
unsigned long long g(S, unsigned long long*&, const unsigned long long*&, volatile unsigned long long*&)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
float g(float, const float, volatile float)
|
||||
{ return 0; }
|
||||
float g(char, float&, const float&, volatile float&)
|
||||
{ return 0; }
|
||||
float g(float*, const float*, volatile float*)
|
||||
{ return 0; }
|
||||
float g(char, float*&, const float*&, volatile float*&)
|
||||
{ return 0; }
|
||||
|
||||
double g(double, const double, volatile double)
|
||||
{ return 0; }
|
||||
double g(char, double&, const double&, volatile double&)
|
||||
{ return 0; }
|
||||
double g(double*, const double*, volatile double*)
|
||||
{ return 0; }
|
||||
double g(char, double*&, const double*&, volatile double*&)
|
||||
{ return 0; }
|
||||
|
||||
#ifdef __GNUC__
|
||||
long double g(long double, const long double, volatile long double)
|
||||
{ return 0; }
|
||||
long double g(char, long double&, const long double&, volatile long double&)
|
||||
{ return 0; }
|
||||
long double g(long double*, const long double*, volatile long double*)
|
||||
{ return 0; }
|
||||
long double g(char, long double*&, const long double*&, volatile long double*&)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
class c {
|
||||
public:
|
||||
c(int) {};
|
||||
int i;
|
||||
};
|
||||
|
||||
class c g(c, const c, volatile c)
|
||||
{ return 0; }
|
||||
c g(char, c&, const c&, volatile c&)
|
||||
{ return 0; }
|
||||
c g(c*, const c*, volatile c*)
|
||||
{ return 0; }
|
||||
c g(char, c*&, const c*&, volatile c*&)
|
||||
{ return 0; }
|
||||
|
||||
/*
|
||||
void h(char = 'a')
|
||||
{ }
|
||||
void h(char, signed char = 'a')
|
||||
{ }
|
||||
void h(unsigned char = 'a')
|
||||
{ }
|
||||
*/
|
||||
/*
|
||||
void h(char = (char)'a')
|
||||
{ }
|
||||
void h(char, signed char = (signed char)'a')
|
||||
{ }
|
||||
void h(unsigned char = (unsigned char)'a')
|
||||
{ }
|
||||
|
||||
|
||||
void h(short = (short)43)
|
||||
{ }
|
||||
void h(char, signed short = (signed short)43)
|
||||
{ }
|
||||
void h(unsigned short = (unsigned short)43)
|
||||
{ }
|
||||
|
||||
void h(int = (int)43)
|
||||
{ }
|
||||
void h(char, signed int = (signed int)43)
|
||||
{ }
|
||||
void h(unsigned int = (unsigned int)43)
|
||||
{ }
|
||||
|
||||
|
||||
void h(long = (long)43)
|
||||
{ }
|
||||
void h(char, signed long = (signed long)43)
|
||||
{ }
|
||||
void h(unsigned long = (unsigned long)43)
|
||||
{ }
|
||||
|
||||
#ifdef __GNUC__
|
||||
void h(long long = 43)
|
||||
{ }
|
||||
void h(char, signed long long = 43)
|
||||
{ }
|
||||
void h(unsigned long long = 43)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
void h(float = 4.3e-10)
|
||||
{ }
|
||||
void h(double = 4.3)
|
||||
{ }
|
||||
#ifdef __GNUC__
|
||||
void h(long double = 4.33e33)
|
||||
{ }
|
||||
#endif
|
||||
*/
|
||||
void printf(const char *format, ... )
|
||||
{
|
||||
// elipsis
|
||||
}
|
||||
|
||||
class T1 {
|
||||
public:
|
||||
static void* operator new(size_t);
|
||||
static void operator delete(void *pointer);
|
||||
|
||||
void operator=(const T1&);
|
||||
T1& operator=(int);
|
||||
|
||||
int operator==(int) const;
|
||||
int operator==(const T1&) const;
|
||||
int operator!=(int) const;
|
||||
int operator!=(const T1&) const;
|
||||
|
||||
int operator<=(int) const;
|
||||
int operator<=(const T1&) const;
|
||||
int operator<(int) const;
|
||||
int operator<(const T1&) const;
|
||||
int operator>=(int) const;
|
||||
int operator>=(const T1&) const;
|
||||
int operator>(int) const;
|
||||
int operator>(const T1&) const;
|
||||
|
||||
void operator+(int) const;
|
||||
T1& operator+(const T1&) const;
|
||||
void operator+=(int) const;
|
||||
T1& operator+=(const T1&) const;
|
||||
|
||||
T1& operator++() const;
|
||||
|
||||
void operator-(int) const;
|
||||
T1& operator-(const T1&) const;
|
||||
void operator-=(int) const;
|
||||
T1& operator-=(const T1&) const;
|
||||
|
||||
T1& operator--() const;
|
||||
|
||||
void operator*(int) const;
|
||||
T1& operator*(const T1&) const;
|
||||
void operator*=(int) const;
|
||||
T1& operator*=(const T1&) const;
|
||||
|
||||
void operator/(int) const;
|
||||
T1& operator/(const T1&) const;
|
||||
void operator/=(int) const;
|
||||
T1& operator/=(const T1&) const;
|
||||
|
||||
void operator%(int) const;
|
||||
T1& operator%(const T1&) const;
|
||||
void operator%=(int) const;
|
||||
T1& operator%=(const T1&) const;
|
||||
|
||||
void operator&&(int) const;
|
||||
T1& operator&&(const T1&) const;
|
||||
|
||||
void operator||(int) const;
|
||||
T1& operator||(const T1&) const;
|
||||
|
||||
void operator&(int) const;
|
||||
T1& operator&(const T1&) const;
|
||||
void operator&=(int) const;
|
||||
T1& operator&=(const T1&) const;
|
||||
|
||||
void operator|(int) const;
|
||||
T1& operator|(const T1&) const;
|
||||
void operator|=(int) const;
|
||||
T1& operator|=(const T1&) const;
|
||||
|
||||
void operator^(int) const;
|
||||
T1& operator^(const T1&) const;
|
||||
void operator^=(int) const;
|
||||
T1& operator^=(const T1&) const;
|
||||
|
||||
T1& operator!() const;
|
||||
T1& operator~() const;
|
||||
};
|
||||
|
||||
void*
|
||||
T1::operator new(size_t)
|
||||
{ return 0; }
|
||||
|
||||
void
|
||||
T1::operator delete(void *pointer)
|
||||
{ }
|
||||
|
||||
class T2 {
|
||||
public:
|
||||
T2(int i): integer(i)
|
||||
{ }
|
||||
int integer;
|
||||
};
|
||||
|
||||
int operator==(const T2&, const T2&)
|
||||
{ return 0; }
|
||||
int operator==(const T2&, char)
|
||||
{ return 0; }
|
||||
int operator!=(const T2&, const T2&)
|
||||
{ return 0; }
|
||||
int operator!=(const T2&, char)
|
||||
{ return 0; }
|
||||
|
||||
int operator<=(const T2&, const T2&)
|
||||
{ return 0; }
|
||||
int operator<=(const T2&, char)
|
||||
{ return 0; }
|
||||
int operator<(const T2&, const T2&)
|
||||
{ return 0; }
|
||||
int operator<(const T2&, char)
|
||||
{ return 0; }
|
||||
int operator>=(const T2&, const T2&)
|
||||
{ return 0; }
|
||||
int operator>=(const T2&, char)
|
||||
{ return 0; }
|
||||
int operator>(const T2&, const T2&)
|
||||
{ return 0; }
|
||||
int operator>(const T2&, char)
|
||||
{ return 0; }
|
||||
|
||||
T2 operator+(const T2 t, int i)
|
||||
{ return t.integer + i; }
|
||||
T2 operator+(const T2 a, const T2& b)
|
||||
{ return a.integer + b.integer; }
|
||||
T2& operator+=(T2& t, int i)
|
||||
{ t.integer += i; return t; }
|
||||
T2& operator+=(T2& a, const T2& b)
|
||||
{ a.integer += b.integer; return a; }
|
||||
|
||||
T2 operator-(const T2 t, int i)
|
||||
{ return t.integer - i; }
|
||||
T2 operator-(const T2 a, const T2& b)
|
||||
{ return a.integer - b.integer; }
|
||||
T2& operator-=(T2& t, int i)
|
||||
{ t.integer -= i; return t; }
|
||||
T2& operator-=(T2& a, const T2& b)
|
||||
{ a.integer -= b.integer; return a; }
|
||||
|
||||
T2 operator*(const T2 t, int i)
|
||||
{ return t.integer * i; }
|
||||
T2 operator*(const T2 a, const T2& b)
|
||||
{ return a.integer * b.integer; }
|
||||
T2& operator*=(T2& t, int i)
|
||||
{ t.integer *= i; return t; }
|
||||
T2& operator*=(T2& a, const T2& b)
|
||||
{ a.integer *= b.integer; return a; }
|
||||
|
||||
T2 operator/(const T2 t, int i)
|
||||
{ return t.integer / i; }
|
||||
T2 operator/(const T2 a, const T2& b)
|
||||
{ return a.integer / b.integer; }
|
||||
T2& operator/=(T2& t, int i)
|
||||
{ t.integer /= i; return t; }
|
||||
T2& operator/=(T2& a, const T2& b)
|
||||
{ a.integer /= b.integer; return a; }
|
||||
|
||||
T2 operator%(const T2 t, int i)
|
||||
{ return t.integer % i; }
|
||||
T2 operator%(const T2 a, const T2& b)
|
||||
{ return a.integer % b.integer; }
|
||||
T2& operator%=(T2& t, int i)
|
||||
{ t.integer %= i; return t; }
|
||||
T2& operator%=(T2& a, const T2& b)
|
||||
{ a.integer %= b.integer; return a; }
|
||||
|
||||
template<class T>
|
||||
class T5 {
|
||||
public:
|
||||
T5(int);
|
||||
T5(const T5<T>&);
|
||||
~T5();
|
||||
static void* operator new(size_t);
|
||||
static void operator delete(void *pointer);
|
||||
int value();
|
||||
|
||||
static T X;
|
||||
T x;
|
||||
int val;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T5<T>::T5(int v)
|
||||
{ val = v; }
|
||||
|
||||
template<class T>
|
||||
T5<T>::T5(const T5<T>&)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
T5<T>::~T5()
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void*
|
||||
T5<T>::operator new(size_t)
|
||||
{ return 0; }
|
||||
|
||||
template<class T>
|
||||
void
|
||||
T5<T>::operator delete(void *pointer)
|
||||
{ }
|
||||
|
||||
template<class T>
|
||||
int
|
||||
T5<T>::value()
|
||||
{ return val; }
|
||||
|
||||
|
||||
#if ! defined(__GNUC__) || defined(GCC_BUG)
|
||||
template<class T>
|
||||
T T5<T>::X;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
T5<char> t5c(1);
|
||||
T5<int> t5i(2);
|
||||
T5<int (*)(char, void *)> t5fi1(3);
|
||||
T5<int (*)(int, double **, void *)> t5fi2(4);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class x {
|
||||
public:
|
||||
int (*manage[5])(double,
|
||||
void *(*malloc)(unsigned size),
|
||||
void (*free)(void *pointer));
|
||||
int (*device[5])(int open(const char *, unsigned mode, unsigned perms, int extra = 0),
|
||||
int *(*read)(int fd, void *place, unsigned size),
|
||||
int *(*write)(int fd, void *place, unsigned size),
|
||||
void (*close)(int fd));
|
||||
};
|
||||
T5<x> t5x(5);
|
||||
|
||||
#if !defined(__GNUC__) || (__GNUC__ >= 2 && __GNUC_MINOR__ >= 6)
|
||||
template class T5<char>;
|
||||
template class T5<int>;
|
||||
template class T5<int (*)(char, void *)>;
|
||||
template class T5<int (*)(int, double **, void *)>;
|
||||
template class T5<x>;
|
||||
#endif
|
||||
|
||||
class T7 {
|
||||
public:
|
||||
static int get();
|
||||
static void put(int);
|
||||
};
|
||||
|
||||
int
|
||||
T7::get()
|
||||
{ return 1; }
|
||||
|
||||
void
|
||||
T7::put(int i)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
// More template kinds. GDB 4.16 didn't handle these, but
|
||||
// Wildebeest does. Note: Assuming HP aCC is used to compile
|
||||
// this file; with g++ or HP cfront or other compilers the
|
||||
// demangling may not get done correctly.
|
||||
|
||||
// Ordinary template, to be instantiated with different types
|
||||
template<class T>
|
||||
class Foo {
|
||||
public:
|
||||
int x;
|
||||
T t;
|
||||
T foo (int, T);
|
||||
};
|
||||
|
||||
|
||||
template<class T> T Foo<T>::foo (int i, T tt)
|
||||
{
|
||||
return tt;
|
||||
}
|
||||
|
||||
// Template with int parameter
|
||||
|
||||
template<class T, int sz>
|
||||
class Bar {
|
||||
public:
|
||||
int x;
|
||||
T t;
|
||||
T bar (int, T);
|
||||
};
|
||||
|
||||
|
||||
template<class T, int sz> T Bar<T, sz>::bar (int i, T tt)
|
||||
{
|
||||
if (i < sz)
|
||||
return tt;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// function template with int parameter
|
||||
template<class T> int dummy (T tt, int i)
|
||||
{
|
||||
return tt;
|
||||
}
|
||||
|
||||
// Template with partial specializations
|
||||
template<class T1, class T2>
|
||||
class Spec {
|
||||
public:
|
||||
int x;
|
||||
T1 spec (T2);
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
T1 Spec<T1, T2>::spec (T2 t2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
class Spec<T, T*> {
|
||||
public:
|
||||
int x;
|
||||
T spec (T*);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T Spec<T, T*>::spec (T * tp)
|
||||
{
|
||||
return *tp;
|
||||
}
|
||||
|
||||
// Template with char parameter
|
||||
template<class T, char sz>
|
||||
class Baz {
|
||||
public:
|
||||
int x;
|
||||
T t;
|
||||
T baz (int, T);
|
||||
};
|
||||
|
||||
template<class T, char sz> T Baz<T, sz>::baz (int i, T tt)
|
||||
{
|
||||
if (i < sz)
|
||||
return tt;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Template with char * parameter
|
||||
template<class T, char * sz>
|
||||
class Qux {
|
||||
public:
|
||||
int x;
|
||||
T t;
|
||||
T qux (int, T);
|
||||
};
|
||||
|
||||
template<class T, char * sz> T Qux<T, sz>::qux (int i, T tt)
|
||||
{
|
||||
if (sz[0] == 'q')
|
||||
return tt;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Template with a function pointer parameter
|
||||
template<class T, int (*f)(int) >
|
||||
class Qux1 {
|
||||
public:
|
||||
int x;
|
||||
T t;
|
||||
T qux (int, T);
|
||||
};
|
||||
|
||||
template<class T, int (*f)(int)> T Qux1<T, f>::qux (int i, T tt)
|
||||
{
|
||||
if (f != 0)
|
||||
return tt;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Some functions to provide as arguments to template
|
||||
int gf1 (int a) {
|
||||
return a * 2 + 13;
|
||||
}
|
||||
int gf2 (int a) {
|
||||
return a * 2 + 26;
|
||||
}
|
||||
|
||||
char string[3];
|
||||
|
||||
|
||||
// Template for nested instantiations
|
||||
|
||||
template<class T>
|
||||
class Garply {
|
||||
public:
|
||||
int x;
|
||||
T t;
|
||||
T garply (int, T);
|
||||
};
|
||||
|
||||
template<class T> T Garply<T>::garply (int i, T tt)
|
||||
{
|
||||
if (i > x)
|
||||
return tt;
|
||||
else
|
||||
{
|
||||
x += i;
|
||||
return tt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
i = i + 1;
|
||||
|
||||
// New tests added here
|
||||
|
||||
Foo<int> fint;
|
||||
Foo<char> fchar;
|
||||
Foo<volatile char *> fvpchar;
|
||||
|
||||
Bar<int, 33> bint;
|
||||
Bar<int, (4 > 3)> bint2;
|
||||
|
||||
Baz<int, 's'> bazint;
|
||||
Baz<char, 'a'> bazint2;
|
||||
|
||||
Qux<char, string> quxint2;
|
||||
Qux<int, string> quxint;
|
||||
|
||||
Qux1<int, gf1> qux11;
|
||||
|
||||
int x = fint.foo(33, 47);
|
||||
char c = fchar.foo(33, 'x');
|
||||
volatile char * cp = fvpchar.foo(33, 0);
|
||||
|
||||
int y = dummy<int> (400, 600);
|
||||
|
||||
int z = bint.bar(55, 66);
|
||||
z += bint2.bar(55, 66);
|
||||
|
||||
c = bazint2.baz(4, 'y');
|
||||
c = quxint2.qux(4, 'z');
|
||||
|
||||
y = bazint.baz(4,3);
|
||||
y = quxint.qux(4, 22);
|
||||
y += qux11.qux(4, 22);
|
||||
|
||||
y *= gf1(y) - gf2(y);
|
||||
|
||||
Spec<int, char> sic;
|
||||
Spec<int, int *> siip;
|
||||
|
||||
sic.spec ('c');
|
||||
siip.spec (&x);
|
||||
|
||||
Garply<int> f;
|
||||
Garply<char> fc;
|
||||
f.x = 13;
|
||||
|
||||
Garply<Garply<char> > nf;
|
||||
nf.x = 31;
|
||||
|
||||
x = f.garply (3, 4);
|
||||
|
||||
fc = nf.garply (3, fc);
|
||||
|
||||
y = x + fc.x;
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/* Thread local in a library.
|
||||
*/
|
||||
#include "thread-local-in-lib.h"
|
||||
/*
|
||||
* #define NTHREADS 4
|
||||
* #define NUM_ELEMS 12
|
||||
*/
|
||||
|
||||
extern void* adder( void * );
|
||||
|
||||
pthread_mutex_t mutex; /* mutex for protecting global data total */
|
||||
|
||||
int numbers[NUM_ELEMS] = {5, 4, 3, 2, 1, 6, 7, 8, 9, 10, 12, 11};
|
||||
int total = 0;
|
||||
|
||||
int debugger_saw[NTHREADS][ELEMS_PER_THREAD]; /* [4][3] */
|
||||
int the_code_saw[NTHREADS][ELEMS_PER_THREAD];
|
||||
|
||||
int get_number(i)
|
||||
int i;
|
||||
{
|
||||
/* sleep to force context switch to another thread in non-MP system
|
||||
* so that TLS symbols are used by multiple threads concurrently
|
||||
* in some way.
|
||||
*/
|
||||
sleep(1);
|
||||
return numbers[i];
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
pthread_t thread[NTHREADS];
|
||||
void *status;
|
||||
int i, j, ret;
|
||||
|
||||
printf("== Thread: Test started\n");
|
||||
|
||||
for( i = 0; i < NTHREADS; i++ ) {
|
||||
for( j = 0; j < ELEMS_PER_THREAD; j++ ) {
|
||||
debugger_saw[i][j] = 0;
|
||||
the_code_saw[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret = pthread_mutex_init(&mutex, NULL);
|
||||
if (ret != 0) {
|
||||
printf("== Thread: pthread_mutex_init() error: %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i < NTHREADS; i++) {
|
||||
ret = pthread_create( &thread[i],
|
||||
NULL,
|
||||
adder,
|
||||
(void *) i);
|
||||
if (ret != 0) {
|
||||
printf("== Thread: pthread_create() error: %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
printf("== Thread: thread %d created\n", i);
|
||||
}
|
||||
|
||||
for (i=0; i < NTHREADS; i++) {
|
||||
pthread_join( thread[i], &status);
|
||||
}
|
||||
|
||||
printf("== Thread: total = %d\n", total); /* Expect "78" */
|
||||
|
||||
for( i = 0; i < NTHREADS; i++ ) {
|
||||
for( j = 0; j < ELEMS_PER_THREAD; j++ ) {
|
||||
printf( "== Thread: the debugger saw %d, the program saw %d\n",
|
||||
debugger_saw[i][j],
|
||||
the_code_saw[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
printf("== Thread: Test ended\n");
|
||||
exit(0);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define NTHREADS 4
|
||||
#define NUM_ELEMS 12
|
||||
|
||||
#define ELEMS_PER_THREAD (NUM_ELEMS/NTHREADS)
|
|
@ -0,0 +1,92 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/* Library code for thread local in lib test.
|
||||
*/
|
||||
#include "thread-local-in-lib.h"
|
||||
|
||||
extern pthread_mutex_t mutex;
|
||||
extern int get_number();
|
||||
extern int total;
|
||||
extern int the_code_saw[NTHREADS][ELEMS_PER_THREAD];
|
||||
|
||||
/* The debugger should see this without a declaration.
|
||||
*
|
||||
* extern int debugger_saw[NTHREADS][ELEMS_PER_THREAD];
|
||||
*/
|
||||
|
||||
/* The actual thread locals.
|
||||
*/
|
||||
__thread int sum;
|
||||
__thread int x[ ELEMS_PER_THREAD ]; /* [3] */
|
||||
|
||||
void sumup()
|
||||
{
|
||||
int j;
|
||||
|
||||
sum = 0;
|
||||
for (j = 0; j < ELEMS_PER_THREAD; j++) {
|
||||
sum += x[j];
|
||||
}
|
||||
|
||||
if( sum == x[0] )
|
||||
/* It won't be "==", but this lets us set a breakpoint
|
||||
* and look at the thread-local storage.
|
||||
*/
|
||||
sum++;
|
||||
|
||||
x[0] = x[2]; /* Another no-op for debugger use */
|
||||
}
|
||||
|
||||
void *adder( vid )
|
||||
void * vid;
|
||||
{
|
||||
int id;
|
||||
int i, j;
|
||||
int ret;
|
||||
|
||||
id = (int) vid;
|
||||
|
||||
/* printf( "== Thread: Welcome to adder %d\n", id ); */
|
||||
|
||||
for (j = 0; j < ELEMS_PER_THREAD; j++) {
|
||||
x[j] = 0;
|
||||
}
|
||||
|
||||
for (i = id, j = 0; i < NUM_ELEMS; i += NTHREADS, j++ ) {
|
||||
|
||||
/* printf( "== Thread: id %d, i %d, j %d\n", id, i, j );
|
||||
fflush( stdout ); */
|
||||
|
||||
x[j] = get_number(i); /* {0,1,2,3} +0, +4, +8 */
|
||||
|
||||
/* Record for posterity; the debugger will gather
|
||||
* the same data here, using "x[j]".
|
||||
*/
|
||||
the_code_saw[ id ][ j ] = x[j];
|
||||
|
||||
/* printf( "== Thread %d, sample %d, val %d, i %d\n", id, j, x[j],i );
|
||||
fflush( stdout ); */
|
||||
}
|
||||
|
||||
sumup();
|
||||
/* printf("== Thread: adder %d contributes total %d\n", id, sum); */
|
||||
|
||||
/* protect global data */
|
||||
ret = pthread_mutex_lock(&mutex);
|
||||
if (ret != 0) {
|
||||
printf("== Thread: pthread_mutex_lock() error: %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
total += sum;
|
||||
|
||||
ret = pthread_mutex_unlock(&mutex);
|
||||
if (ret != 0) {
|
||||
printf("== Thread: pthread_mutex_unlock() error: %d\n", ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( NTHREADS != 4 || ELEMS_PER_THREAD != 3 || NUM_ELEMS != 12 ) {
|
||||
printf( "** ERROR in test code **\n" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
main()
|
||||
{
|
||||
printf("Hello from vforked_program...\n");
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
// Pls try the following program on virtual functions and try to do print on
|
||||
// most of the code in main(). Almost none of them works !
|
||||
|
||||
//
|
||||
// The inheritance structure is:
|
||||
//
|
||||
// V : VA VB
|
||||
// A : (V)
|
||||
// B : A
|
||||
// D : AD (V)
|
||||
// C : (V)
|
||||
// E : B (V) D C
|
||||
//
|
||||
|
||||
class VA
|
||||
{
|
||||
public:
|
||||
int va;
|
||||
};
|
||||
|
||||
class VB
|
||||
{
|
||||
public:
|
||||
int vb;
|
||||
int fvb();
|
||||
virtual vvb();
|
||||
};
|
||||
|
||||
class V : public VA, public VB
|
||||
{
|
||||
public:
|
||||
int f();
|
||||
virtual vv();
|
||||
int w;
|
||||
};
|
||||
|
||||
class A : virtual public V
|
||||
{
|
||||
public:
|
||||
virtual int f();
|
||||
private:
|
||||
int a;
|
||||
};
|
||||
|
||||
class B : public A
|
||||
{
|
||||
public:
|
||||
int f();
|
||||
private:
|
||||
int b;
|
||||
};
|
||||
|
||||
class C : public virtual V
|
||||
{
|
||||
public:
|
||||
int c;
|
||||
};
|
||||
|
||||
class AD
|
||||
{
|
||||
public:
|
||||
virtual int vg() = 0;
|
||||
};
|
||||
|
||||
class D : public AD, virtual public V
|
||||
{
|
||||
public:
|
||||
static void s();
|
||||
virtual int vg();
|
||||
virtual int vd();
|
||||
int fd();
|
||||
int d;
|
||||
};
|
||||
|
||||
class E : public B, virtual public V, public D, public C
|
||||
{
|
||||
public:
|
||||
int f();
|
||||
int vg();
|
||||
int vv();
|
||||
int e;
|
||||
};
|
||||
|
||||
D dd;
|
||||
D* ppd = ⅆ
|
||||
AD* pAd = ⅆ
|
||||
|
||||
A a;
|
||||
B b;
|
||||
C c;
|
||||
D d;
|
||||
E e;
|
||||
V v;
|
||||
VB vb;
|
||||
|
||||
|
||||
A* pAa = &a;
|
||||
A* pAe = &e;
|
||||
|
||||
B* pBe = &e;
|
||||
|
||||
D* pDd = &d;
|
||||
D* pDe = &e;
|
||||
|
||||
V* pVa = &a;
|
||||
V* pVv = &v;
|
||||
V* pVe = &e;
|
||||
V* pVd = &d;
|
||||
|
||||
AD* pADe = &e;
|
||||
|
||||
E* pEe = &e;
|
||||
|
||||
VB* pVB = &vb;
|
||||
|
||||
void init()
|
||||
{
|
||||
a.vb = 1;
|
||||
b.vb = 2;
|
||||
c.vb = 3;
|
||||
d.vb = 4;
|
||||
e.vb = 5;
|
||||
v.vb = 6;
|
||||
vb.vb = 7;
|
||||
|
||||
d.d = 1;
|
||||
e.d = 2;
|
||||
}
|
||||
|
||||
extern "C" printf(const char *, ...);
|
||||
|
||||
int all_count = 0;
|
||||
int failed_count = 0;
|
||||
|
||||
#define TEST(EXPR, EXPECTED) \
|
||||
ret = EXPR; \
|
||||
if (ret != EXPECTED) {\
|
||||
printf("Failed %s is %d, should be %d!\n", #EXPR, ret, EXPECTED); \
|
||||
failed_count++; } \
|
||||
all_count++;
|
||||
|
||||
int ret;
|
||||
|
||||
void test_calls()
|
||||
{
|
||||
TEST(pAe->f(), 20);
|
||||
TEST(pAa->f(), 1);
|
||||
|
||||
TEST(pDe->vg(), 202);
|
||||
TEST(pADe->vg(), 202);
|
||||
TEST(pDd->vg(), 101);
|
||||
|
||||
TEST(pEe->vvb(), 411);
|
||||
|
||||
TEST(pVB->vvb(), 407);
|
||||
|
||||
TEST(pBe->vvb(), 411);
|
||||
TEST(pDe->vvb(), 411);
|
||||
|
||||
TEST(pEe->vd(), 282);
|
||||
TEST(pEe->fvb(), 311);
|
||||
|
||||
TEST(pEe->D::vg(), 102);
|
||||
printf("Did %d tests, of which %d failed.\n", all_count, failed_count);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
e.w = 7;
|
||||
e.vb = 11;
|
||||
|
||||
test_calls();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int A::f() {return 1;}
|
||||
int B::f() {return 2;}
|
||||
void D::s() {}
|
||||
int E::f() {return 20;}
|
||||
int D::vg() {return 100+d;}
|
||||
int E::vg() {return 200+d;}
|
||||
int V::f() {return 600+w;}
|
||||
int V::vv() {return 400+w;}
|
||||
int E::vv() {return 450+w;}
|
||||
int D::fd() {return 250+d;}
|
||||
int D::vd() {return 280+d;}
|
||||
int VB::fvb() {return 300+vb;}
|
||||
int VB::vvb() {return 400+vb;}
|
|
@ -0,0 +1,166 @@
|
|||
#include <stdio.h>
|
||||
/*
|
||||
* Since using watchpoints can be very slow, we have to take some pains to
|
||||
* ensure that we don't run too long with them enabled or we run the risk
|
||||
* of having the test timeout. To help avoid this, we insert some marker
|
||||
* functions in the execution stream so we can set breakpoints at known
|
||||
* locations, without worrying about invalidating line numbers by changing
|
||||
* this file. We use null bodied functions are markers since gdb does
|
||||
* not support breakpoints at labeled text points at this time.
|
||||
*
|
||||
* One place we need is a marker for when we start executing our tests
|
||||
* instructions rather than any process startup code, so we insert one
|
||||
* right after entering main(). Another is right before we finish, before
|
||||
* we start executing any process termination code.
|
||||
*
|
||||
* Another problem we have to guard against, at least for the test
|
||||
* suite, is that we need to ensure that the line that causes the
|
||||
* watchpoint to be hit is still the current line when gdb notices
|
||||
* the hit. Depending upon the specific code generated by the compiler,
|
||||
* the instruction after the one that triggers the hit may be part of
|
||||
* the same line or part of the next line. Thus we ensure that there
|
||||
* are always some instructions to execute on the same line after the
|
||||
* code that should trigger the hit.
|
||||
*/
|
||||
|
||||
int count = -1;
|
||||
int ival1 = -1;
|
||||
int ival2 = -1;
|
||||
int ival3 = -1;
|
||||
int ival4 = -1;
|
||||
int ival5 = -1;
|
||||
char buf[10];
|
||||
struct foo
|
||||
{
|
||||
int val;
|
||||
};
|
||||
struct foo struct1, struct2, *ptr1, *ptr2;
|
||||
|
||||
int doread = 0;
|
||||
|
||||
void marker1 ()
|
||||
{
|
||||
}
|
||||
|
||||
void marker2 ()
|
||||
{
|
||||
}
|
||||
|
||||
void marker4 ()
|
||||
{
|
||||
}
|
||||
|
||||
void marker5 ()
|
||||
{
|
||||
}
|
||||
|
||||
void marker6 ()
|
||||
{
|
||||
}
|
||||
|
||||
void recurser (x)
|
||||
int x;
|
||||
{
|
||||
int local_x;
|
||||
|
||||
if (x > 0)
|
||||
recurser (x-1);
|
||||
local_x = x;
|
||||
}
|
||||
|
||||
void
|
||||
func2 ()
|
||||
{
|
||||
int local_a;
|
||||
static int static_b;
|
||||
|
||||
ival5++;
|
||||
local_a = ival5;
|
||||
static_b = local_a;
|
||||
}
|
||||
|
||||
int
|
||||
func1 ()
|
||||
{
|
||||
/* The point of this is that we will set a breakpoint at this call.
|
||||
|
||||
Then, if DECR_PC_AFTER_BREAK equals the size of a function call
|
||||
instruction (true on a sun3 if this is gcc-compiled--FIXME we
|
||||
should use asm() to make it work for any compiler, present or
|
||||
future), then we will end up branching to the location just after
|
||||
the breakpoint. And we better not confuse that with hitting the
|
||||
breakpoint. */
|
||||
func2 ();
|
||||
return 73;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
struct1.val = 1;
|
||||
struct2.val = 2;
|
||||
ptr1 = &struct1;
|
||||
ptr2 = &struct2;
|
||||
marker1 ();
|
||||
func1 ();
|
||||
for (count = 0; count < 4; count++) {
|
||||
ival1 = count;
|
||||
ival3 = count; ival4 = count;
|
||||
}
|
||||
ival1 = count; /* Outside loop */
|
||||
ival2 = count;
|
||||
ival3 = count; ival4 = count;
|
||||
marker2 ();
|
||||
if (doread)
|
||||
{
|
||||
static char msg[] = "type stuff for buf now:";
|
||||
write (1, msg, sizeof (msg) - 1);
|
||||
read (0, &buf[0], 5);
|
||||
}
|
||||
marker4 ();
|
||||
|
||||
/* We have a watchpoint on ptr1->val. It should be triggered if
|
||||
ptr1's value changes. */
|
||||
ptr1 = ptr2;
|
||||
|
||||
/* This should not trigger the watchpoint. If it does, then we
|
||||
used the wrong value chain to re-insert the watchpoints or we
|
||||
are not evaluating the watchpoint expression correctly. */
|
||||
struct1.val = 5;
|
||||
marker5 ();
|
||||
|
||||
/* We have a watchpoint on ptr1->val. It should be triggered if
|
||||
ptr1's value changes. */
|
||||
ptr1 = ptr2;
|
||||
|
||||
/* This should not trigger the watchpoint. If it does, then we
|
||||
used the wrong value chain to re-insert the watchpoints or we
|
||||
are not evaluating the watchpoint expression correctly. */
|
||||
struct1.val = 5;
|
||||
marker5 ();
|
||||
|
||||
/* We're going to watch locals of func2, to see that out-of-scope
|
||||
watchpoints are detected and properly deleted.
|
||||
*/
|
||||
marker6 ();
|
||||
|
||||
/* This invocation is used for watches of a single
|
||||
local variable. */
|
||||
func2 ();
|
||||
|
||||
/* This invocation is used for watches of an expression
|
||||
involving a local variable. */
|
||||
func2 ();
|
||||
|
||||
/* This invocation is used for watches of a static
|
||||
(non-stack-based) local variable. */
|
||||
func2 ();
|
||||
|
||||
/* This invocation is used for watches of a local variable
|
||||
when recursion happens.
|
||||
*/
|
||||
marker6 ();
|
||||
recurser (2);
|
||||
|
||||
marker6 ();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int callee( x )
|
||||
int x;
|
||||
{
|
||||
int y = x * x;
|
||||
return (y - 2);
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < 10; i++)
|
||||
{
|
||||
printf( "%d ", callee( i ));
|
||||
|
||||
}
|
||||
printf( " Goodbye!\n" );
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#include "xdb0.h"
|
||||
|
||||
main ()
|
||||
{
|
||||
int x;
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
x = 0;
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
foo (x++);
|
||||
}
|
||||
|
||||
static void
|
||||
unused ()
|
||||
{
|
||||
/* Not used for anything */
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/* An include file that actually causes code to be generated in the
|
||||
including file. This is known to cause problems on some systems. */
|
||||
|
||||
static void
|
||||
foo (x)
|
||||
int x;
|
||||
{
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
bar (x++);
|
||||
}
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue