Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 6d37627d89824d913e5e039b1bac1e2e791a51c3 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                                
                                                                

                                                                        


                                                                           
                                                       
                                                    
                                                                          
  







                                                                                 
                   
 
                    
 




                   




                                 
                  
                                           
      
 



                  





                        




                          





                                  
                       

              

                              
                                 
                                
                                 
                                           
 




                                                                             
                           
                    


                 
                          

                         

                                                                     
                     
                     

                                
                        


                           
                    


                     
                                  


                     

                              
 



                  


                                        
                                  



                
                      


                        
                              








                                                                                          
                             
                                  






                                                     
                                                                                 
                                                                                         
                                                                     
                     
                                                  
                                             

                                    



                                                      
              
                                            



                                                                                          


                                    
                              


              










                                                                        
                                                              



                               
                           
 
                                                                 
                  

                             
                

                            

                             

                                 
                                
                                                         
                                        
                  


                                

                                                                                   
                                          
                                        

                  







                                                                        





                                                                                                   
                                              

                                       


                           
               
                                               


                                                  


                    
                                                                


      
                             
/*******************************************************************************
 * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 * The Eclipse Public License is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 * You may elect to redistribute this code under either of these licenses.
 *
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/

/*
 * Agent self-testing service.
 */

#include <config.h>

#if ENABLE_RCBP_TEST

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <assert.h>
#include <framework/myalloc.h>
#include <framework/trace.h>
#include <framework/errors.h>
#include <services/diagnostics.h>
#include <main/test.h>
#if defined(WIN32)
#  include <system/Windows/context-win32.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef enum test_enum {
    enum_val1 = 1,
    enum_val2 = 2,
    enum_val3 = 3
} test_enum;

typedef union test_union {
    int x;
    float y;
} test_union;

typedef struct test_struct {
    test_enum f_enum;
    int f_int;
    struct test_struct * f_struct;
    float f_float;
    double f_double;
    test_union f_union;
} test_struct;

typedef int test_array[10001];

extern void tcf_test_func3(void);
extern int tcf_test_func2(void);
extern void tcf_test_func1(void);
extern void tcf_test_func0(enum test_enum);

/* Main purpose of this declaration is to pull basic types info into DWARF */
char tcf_test_char = 0;
short tcf_test_short = 0;
long tcf_test_long = 0;

void tcf_test_func3(void) {
    tcf_test_char++;
    usleep(1000);
}

int tcf_test_func2(void) {
    int func2_local1 = 1;
    int func2_local2 = 2;
    test_struct func2_local3 = { enum_val3, 153, NULL, 3.14f, 2.71 };
    func2_local3.f_struct = &func2_local3;
    tcf_test_short++;
    tcf_test_func3();
    func2_local1++;
    func2_local2 = func2_local1;
    return func2_local2;
}

void tcf_test_func1(void) {
    tcf_test_long++;
    tcf_test_func2();
}

void tcf_test_func0(test_enum e) {
    tcf_test_func1();
}

static char array[0x1000];
char * tcf_test_array = array;

#ifdef __cplusplus
}
#endif

static void * test_sub(void * x) {
    volatile int * test_done = (int *)x;
    while (!*test_done) {
        tcf_test_func0(enum_val3);
    }
    return NULL;
}

void test_proc(void) {
    int i;
    pthread_t thread[4];
    int test_done = 0;
    tcf_test_func0(enum_val1);
    for (i = 0; i < 4; i++) {
        thread[i] = 0;
    }
    for (i = 0; i < 4; i++) {
        if (pthread_create(thread + i, &pthread_create_attr, test_sub, &test_done) != 0) {
            perror("pthread_create");
            break;
        }
    }
    for (i = 0; i < 9; i++) {
        tcf_test_func0(enum_val2);
    }
    test_done = 1;
    for (i = 0; i < 4; i++) {
        if (thread[i]) pthread_join(thread[i], NULL);
    }
}

int find_test_symbol(Context * ctx, char * name, void ** addr, int * sym_class) {
    /* This code allows to run TCF diagnostic tests when symbols info is not available */
    if (is_test_process(ctx) && strncmp(name, "tcf_test_", 9) == 0) {
        *addr = NULL;
        if (strcmp(name, "tcf_test_array") == 0) {
            *sym_class = SYM_CLASS_REFERENCE;
            *addr = &tcf_test_array;
        }
        else if (strcmp(name, "tcf_test_char") == 0) {
            *sym_class = SYM_CLASS_REFERENCE;
            *addr = &tcf_test_char;
        }
        else {
            *sym_class = SYM_CLASS_FUNCTION;
            if (strcmp(name, "tcf_test_func0") == 0) *addr = (void *)&tcf_test_func0;
            else if (strcmp(name, "tcf_test_func1") == 0) *addr = (void *)&tcf_test_func1;
            else if (strcmp(name, "tcf_test_func2") == 0) *addr = (void *)&tcf_test_func2;
            else if (strcmp(name, "tcf_test_func3") == 0) *addr = (void *)&tcf_test_func3;
        }
        if (*addr != NULL) return 0;
    }
    errno = ERR_SYM_NOT_FOUND;
    return -1;
}

#if defined(WIN32)
typedef struct ContextAttachArgs {
    ContextAttachCallBack * done;
    void * data;
    HANDLE thread;
    HANDLE process;
} ContextAttachArgs;

static void done_context_attach(int error, Context * ctx, void * data) {
    ContextAttachArgs * args = (ContextAttachArgs *)data;
    args->done(error, ctx, args->data);
    assert(error || args->process != get_context_handle(ctx));
    CloseHandle(args->thread);
    CloseHandle(args->process);
    loc_free(args);
}
#endif /* defined(WIN32) */

int run_test_process(ContextAttachCallBack * done, void * data) {
#if defined(WIN32)
    char fnm[FILE_PATH_SIZE];
    char cmd[FILE_PATH_SIZE];
    int res = 0;
    STARTUPINFO si;
    PROCESS_INFORMATION prs;
    ContextAttachArgs * args;

    memset(&si, 0, sizeof(si));
    memset(&prs, 0, sizeof(prs));
    memset(fnm, 0, sizeof(fnm));
    if (GetModuleFileName(NULL, fnm, sizeof(fnm)) == 0) {
        set_win32_errno(GetLastError());
        return -1;
    }
    si.cb = sizeof(si);
    strcpy(cmd, "agent.exe -t");
    if (CreateProcess(fnm, cmd, NULL, NULL,
            FALSE, CREATE_SUSPENDED | CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW,
            NULL, NULL, &si, &prs) == 0) {
        set_win32_errno(GetLastError());
        return -1;
    }
    args = (ContextAttachArgs *)loc_alloc(sizeof(ContextAttachArgs));
    args->done = done;
    args->data = data;
    args->thread = prs.hThread;
    args->process = prs.hProcess;
    res = context_attach(prs.dwProcessId, done_context_attach, args, 0);
    if (res != 0) loc_free(args);
    return res;
#elif defined(_WRS_KERNEL)
    int tid = taskCreate("tTcf", 100, 0, 0x4000, (FUNCPTR)test_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    if (tid == 0) return -1;
    taskStop(tid);
    taskActivate(tid);
    assert(taskIsStopped(tid));
    return context_attach(tid, done, data, 0);
#else
    /* Create child process to debug */
    int pid = fork();
    if (pid < 0) return -1;
    if (pid == 0) {
        int fd;
        if (context_attach_self() < 0) exit(1);
        fd = sysconf(_SC_OPEN_MAX);
        while (fd-- > 2) close(fd);
        if (tkill(getpid(), SIGSTOP) < 0) exit(1);
        test_proc();
        exit(0);
    }
    return context_attach(pid, done, data, CONTEXT_ATTACH_SELF);
#endif
}

#endif /* ENABLE_RCBP_TEST */

Back to the top