static void tool_initialization(int argc, const char* argv[])
{
    atexit(cleanup_routine);

#if !defined(WIN32_BUILD) || defined(__CYGWIN__)
    // Define alternate stack
    stack_t alternate_stack;

	// Allocate a maximum of 1 Mbyte or more if MINSIGSTKSZ was
	// bigger than that (this is unlikely)
	int allocated_size = 1024 * 1024;
	if (MINSIGSTKSZ > 1024*1024)
	{
		allocated_size = MINSIGSTKSZ;
	}

	_alternate_signal_stack = malloc(allocated_size);

    alternate_stack.ss_flags = 0;
    alternate_stack.ss_size = allocated_size;
    alternate_stack.ss_sp = (void*)_alternate_signal_stack;

    if (alternate_stack.ss_sp == 0
            || sigaltstack(&alternate_stack, /* oss */ NULL) != 0)
    {
        running_error("Setting alternate signal stack failed (%s)\n",
				strerror(errno));
    }

    // Program signals
    struct sigaction terminating_sigaction;
    memset(&terminating_sigaction, 0, sizeof(terminating_sigaction));

    terminating_sigaction.sa_handler = terminating_signal_handler;
    // Use alternate stack and we want the signal be reset when it happens
    terminating_sigaction.sa_flags = SA_RESETHAND | SA_ONSTACK;
    // Block all blockable signals while handling the termination
    sigfillset(&terminating_sigaction.sa_mask);

    int result = 0;
    result |= sigaction(SIGSEGV, &terminating_sigaction, /* old_sigaction */ NULL);
    result |= sigaction(SIGQUIT, &terminating_sigaction, /* old_sigaction */ NULL);
    result |= sigaction(SIGINT,  &terminating_sigaction, /* old_sigaction */ NULL);
    result |= sigaction(SIGTERM, &terminating_sigaction, /* old_sigaction */ NULL);
    result |= sigaction(SIGABRT, &terminating_sigaction, /* old_sigaction */ NULL);
    
    if (result != 0)
    {
        running_error("Signal programming failed with '%s'\n", strerror(errno));
    }
#endif

    memset(&compilation_process, 0, sizeof(compilation_process));
    compilation_process.argc = argc;
    compilation_process.argv = (const char**)argv;
    compilation_process.exec_basename = give_basename(argv[0]);

    // Find my own directory
    compilation_process.home_directory = find_home(argv[0]);
}
Beispiel #2
0
void debug_message(const char* message, const char* kind, const char* source_file, int line, const char* function_name, ...)
{
    va_list ap;
    char* sanitized_message = xstrdup(message);

    // Remove annoying \n at the end. This will make this function
    // interchangeable with fprintf(stderr, 
    int length = strlen(sanitized_message);

    length--;
    while (length > 0 && sanitized_message[length] == '\n')
    {
        sanitized_message[length] = '\0';
        length--;
    }

    char *long_message = NULL;

    va_start(ap, function_name);
    int ret = vasprintf(&long_message, sanitized_message, ap);
    if (ret < 0)
    {
        // Desperate message
        const char *oom_message = "allocation failure in vasprintf\n";
        write(fileno(stderr), oom_message, strlen(oom_message));
        abort();
    }

    char* kind_copy = xstrdup(kind);

    char *start, *end;

    start = kind_copy;

    while (*start != '\0'
            && (end = strchr(start, '\n')) != NULL)
    {
        *end = '\0';
        fprintf(stderr, "%s:%d(%s): %s\n", give_basename(source_file), line, function_name, start);
        start = end + 1;
    }

    if (*start != '\0')
    {
        fprintf(stderr, "%s:%d(%s): %s\n", give_basename(source_file), line, function_name, start);
    }

    start = long_message;

    while (*start != '\0'
            && (end = strchr(start, '\n')) != NULL)
    {
        *end = '\0';
        fprintf(stderr, "%s:%d(%s): %s\n", give_basename(source_file), line, function_name, start);
        start = end + 1;
    }

    if (*start != '\0')
    {
        fprintf(stderr, "%s:%d(%s): %s\n", give_basename(source_file), line, function_name, start);
    }

    xfree(kind_copy);
    xfree(sanitized_message);
    xfree(long_message);
}
void debug_message(const char* message, const char* kind, const char* source_file, unsigned int line, const char* function_name, ...)
{
    va_list ap;
    char* sanitized_message = xstrdup(message);

    // Remove annoying \n at the end. This will make this function
    // interchangeable with fprintf(stderr, 
    int length = strlen(sanitized_message);

    length--;
    while (length > 0 && sanitized_message[length] == '\n')
    {
        sanitized_message[length] = '\0';
        length--;
    }

    char *long_message = NULL;

    va_start(ap, function_name);
    int ret = vasprintf(&long_message, sanitized_message, ap);
    if (ret < 0)
    {
        // Desperate message
        const char *oom_message = "allocation failure in vasprintf\n";
        int r = write(fileno(stderr), oom_message, strlen(oom_message));
        if (r < 0)
        {
            // Drama. Resort to perror and hope for the best
            perror("write");
        }
        abort();
    }

    char* kind_copy = xstrdup(kind);

    char *start, *end;

    start = kind_copy;

    while (*start != '\0'
            && (end = strchr(start, '\n')) != NULL)
    {
        *end = '\0';
        fprintf(stderr, "%s:%u(%s): %s\n", give_basename(source_file), line, function_name, start);
        start = end + 1;
    }

    if (*start != '\0')
    {
        fprintf(stderr, "%s:%u(%s): %s\n", give_basename(source_file), line, function_name, start);
    }

    start = long_message;

    while (*start != '\0'
            && (end = strchr(start, '\n')) != NULL)
    {
        *end = '\0';
        fprintf(stderr, "%s:%u(%s): %s\n", give_basename(source_file), line, function_name, start);
        start = end + 1;
    }

    if (*start != '\0')
    {
        fprintf(stderr, "%s:%u(%s): %s\n", give_basename(source_file), line, function_name, start);
    }

    DELETE(kind_copy);
    DELETE(sanitized_message);
    DELETE(long_message);

#if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS_FD)
    if (debug_options.backtrace_on_ice)
    {
        int nptrs = backtrace(backtrace_buffer, BACKTRACE_SIZE);

        /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
           would produce similar output to the following: */
        backtrace_symbols_fd(backtrace_buffer, nptrs, fileno(stderr));
    }
#endif
}
        void Interface::run(TL::DTO& dto)
        {
            reset_version_info();
            // Run looking up for every "#pragma nanos"
            PragmaCustomCompilerPhase::run(dto);
            
            // Create versioning symbols
            Source versioning_symbols;

            DEBUG_CODE()
            {
                for(std::map<std::string, int>::iterator it = Version::_interfaces.begin();
                        it != Version::_interfaces.end();
                        it++)
                    std::cerr << "Interface =>  Version::family '" << it->first << "'" 
                              << ", Version::version '" << it->second << "'" << std::endl;
            }

            CXX_LANGUAGE()
            {
                versioning_symbols
                    << "extern \"C\" { "
                    ;
            }

            // Code to maintain the Nanos4 version
            versioning_symbols
                << "const char* __nanos_family __attribute__((weak)) = \"" << Version::_interfaces.begin()->first << "\";"
                << "int __nanos_version __attribute__((weak)) = " << Version::_interfaces.begin()->second << ";"
            ;
            
            // Code for Nanox version
            for(std::map<std::string, int>::iterator it = Version::_interfaces.begin();
                    it != Version::_interfaces.end();
                    it++)
                versioning_symbols
                    << "int __mcc_" << it->first << " __attribute__((weak)) = " << it->second << ";"
                    ;
                
            CXX_LANGUAGE()
            {
                versioning_symbols
                    << "}"
                    ;
            }

            AST_t translation_unit = dto["translation_unit"];
            ScopeLink scope_link = dto["scope_link"];

            AST_t versioning_symbols_tree = versioning_symbols.parse_global(translation_unit,
                    scope_link);
                    
            // Get the translation_unit tree
            // and prepend these declarations
            translation_unit.prepend_to_translation_unit(versioning_symbols_tree);
            
            // We need to obtain the name of the file without the path
            const char* filename = give_basename(translation_unit.get_file().c_str());
            const char* ptr_extension = strrchr(filename, '.');

            // If The filename have not extension then error 
            if (ptr_extension == NULL)
            {
                internal_error("code unreachable.", 0);
            }
            
            std::string name (filename, (ptr_extension - filename));
            
            if (!_map_events.empty())
            {
                Source declare_events, register_events;

                declare_events
                    << "static void __register_events(void* p __attribute__((unused)))"
                    << "{"
                    <<    "nanos_event_key_t nanos_instr_name_key = 0;"
                    <<    register_events
                    << "}"
                    << "__attribute__((section(\"nanos_post_init\"))) nanos_init_desc_t "
                    << name
                    << "__register_events_list = { __register_events, (void*)0 };"
                    ;

                // Register events
                for (map_events::iterator it = _map_events.begin();
                        it != _map_events.end();
                        it++)
                {
                    register_events
                        << "nanos_instrument_register_key(&nanos_instr_name_key, \"" << it->first << "\", " << it->second << ", /* abort */ 0);"
                        ;
                }

                AST_t tree = declare_events.parse_global(translation_unit, 
                        scope_link);

                translation_unit.append_to_translation_unit(tree);
            }
        }