Exemplo n.º 1
0
//----------------------------------------------------------------------------------------------------------------------
// main
//----------------------------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
#if VOGL_FUNCTION_TRACING
    fflush(stdout);
    fflush(stderr);
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
#endif

    VOGL_FUNC_TRACER

    // Initialize vogl_core.
    vogl_core_init();

    XSetErrorHandler(xerror_handler);

    if (!voglbench_init(argc, argv))
    {
        voglbench_deinit();
        return EXIT_FAILURE;
    }

    if (g_command_line_params().get_count("") < 2)
    {
        vogl_error_printf("No trace file specified!\n");

        tool_print_help();

        voglbench_deinit();
        return EXIT_FAILURE;
    }

    if (g_command_line_params().get_value_as_bool("pause"))
    {
        vogl_message_printf("Press key to continue\n");
        vogl_sleep(1000);
        getchar();
    }

    bool success = tool_replay_mode();

    vogl_printf("%u warning(s), %u error(s)\n",
                    console::get_total_messages(cWarningConsoleMessage),
                    console::get_total_messages(cErrorConsoleMessage));

    voglbench_deinit();

    return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
Exemplo n.º 2
0
//----------------------------------------------------------------------------------------------------------------------
// main
//----------------------------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
#if VOGL_FUNCTION_TRACING
    fflush(stdout);
    fflush(stderr);
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
#endif

    VOGL_FUNC_TRACER

    // Initialize vogl_core.
    vogl_core_init();

    if (!voglsyms_init(argc, argv))
    {
        voglsyms_deinit();
        return EXIT_FAILURE;
    }

    if (g_command_line_params().get_count("") < 2)
    {
        vogl_error_printf("No trace file specified!\n");

        tool_print_help();

        voglsyms_deinit();
        return EXIT_FAILURE;
    }

    if (g_command_line_params().get_value_as_bool("pause"))
    {
        vogl_message_printf("Press key to continue\n");
        vogl_sleep(1000);
        getchar();
    }

    bool success = voglsym_main_loop(argv);

    voglsyms_deinit();

    return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
Exemplo n.º 3
0
    // init_uuid() is slow (~40ms, maybe slower), and forces a disk flush on a file, so don't call it more than once.
    // I'm a paranoid nut so this hashes a bunch of shit. It's probably completely overkill for my needs - I should stop reading RFC's.
    static md5_hash init_uuid()
    {
        static uint64_t s_counter;

        // Get as much entropy as we can here

        const uint N = 2;
        void *p[N];
        memset(p, 0, sizeof(p));

        md5_hash_gen gen;
        timer_ticks tick_hist[N];
        for (uint i = 0; i < N; i++)
        {
            uint64_t start_rdtsc = utils::RDTSC();
            gen.update(start_rdtsc);

            gen.update(s_counter);
            gen.update((uint64_t) & s_counter);
            s_counter++;

            // Hash stack address of gen_uuid
            gen.update((uint64_t) & gen_uuid);

            // Hash the initial timer ticks, and time(NULL)
            gen.update(timer::get_init_ticks());
            gen.update((uint64_t)time(NULL));

            // Hash user ID, name, shell, home dir
            uid_t uid = geteuid();
            gen.update(uid);
            struct passwd *pw = getpwuid(uid);
            gen.update((uint64_t) & pw);
            if (pw)
            {
                gen.update(pw, sizeof(struct passwd));
                if (pw->pw_name)
                    gen.update(pw->pw_name, vogl_strlen(pw->pw_name));
                if (pw->pw_passwd)
                    gen.update(pw->pw_passwd, vogl_strlen(pw->pw_passwd));
                if (pw->pw_shell)
                    gen.update(pw->pw_shell, vogl_strlen(pw->pw_shell));
                if (pw->pw_dir)
                    gen.update(pw->pw_dir, vogl_strlen(pw->pw_dir));
                if (pw->pw_gecos)
                    gen.update(pw->pw_gecos, vogl_strlen(pw->pw_gecos));
            }

            uint8_vec buf;

            timer_ticks ticks = timer::get_ticks();
            gen.update(ticks);

            // This is obviously expensive (and questionable?), only do it once. But it helps us get some entropy from the disk subsystem.
            // This is also by far the slowest component of this function (~35ms out of ~40ms).
            if (!i)
            {
                uint64_t st = utils::RDTSC();
                timer tm;
                tm.start();

                const char *pFilename = "!_!_!_!_!_!_!_vogl_temp!_!_!_!_!_!_!_!_.txt";
                FILE *pFile = vogl_fopen(pFilename, "wb");
                gen.update_obj_bits(pFile);
                if (pFile)
                {
                    fwrite("X", 1, 1, pFile);
                    fflush(pFile);
                    fsync(fileno(pFile));
                    vogl_fclose(pFile);
                    remove(pFilename);
                }

                uint64_t t = utils::RDTSC() - st;
                gen.update(t);

                tm.stop();

                gen.update(tm.get_elapsed_ticks());
            }

            // Grab some bits from /dev/urandom (not /dev/random - it may block for a long time)
            {
                const uint N = 64;
                char buf[N];
                FILE *fp = vogl_fopen("/dev/urandom", "rb");
                gen.update_obj_bits(fp);
                if (fp)
                {
                    size_t n = fread(buf, 1, N, fp);
                    VOGL_NOTE_UNUSED(n);
                    vogl_fclose(fp);

                    gen.update(buf, sizeof(buf));
                }
            }

// It's fine if some/most/all of these files don't exist, the true/false results get fed into the hash too.
// TODO: Double check that all the files we should be able to read are actually getting read and hashed here.
#define HASH_FILE(filename)                                               \
    do                                                                    \
    {                                                                     \
        bool success = cfile_stream::read_file_into_array(filename, buf); \
        gen.update_obj_bits(success);                                     \
        gen.update(buf);                                                  \
    } while (0)
            HASH_FILE("/proc/sys/kernel/random/entropy_avail");
            HASH_FILE("/proc/self/statm");
            HASH_FILE("/proc/self/mounts");
            HASH_FILE("/proc/self/io");
            HASH_FILE("/proc/self/smaps");
            HASH_FILE("/proc/self/stack");
            HASH_FILE("/proc/self/status");
            HASH_FILE("/proc/self/maps");
            HASH_FILE("/proc/self/stat");
            HASH_FILE("/proc/self/stat");
            HASH_FILE("/proc/cpuinfo");
            HASH_FILE("/proc/meminfo");
            HASH_FILE("/proc/stat");
            HASH_FILE("/proc/misc");
            HASH_FILE("/proc/swaps");
            HASH_FILE("/proc/version");
            HASH_FILE("/proc/loadavg");
            HASH_FILE("/proc/interrupts");
            HASH_FILE("/proc/ioports");
            HASH_FILE("/proc/partitions");
            HASH_FILE("/proc/driver/rtc");
            HASH_FILE("/proc/self/net/wireless");
            HASH_FILE("/proc/self/net/netstat");
            HASH_FILE("/proc/self/net/netlink");
            HASH_FILE("/sys/class/net/eth0/address");
            HASH_FILE("/sys/class/net/eth1/address");
            HASH_FILE("/sys/class/net/wlan0/address");
#undef HASH_FILE

            gen.update(utils::RDTSC());

            // Hash thread, process ID's, etc.
            pid_t tid = (pid_t)syscall(SYS_gettid);
            gen.update_obj_bits(tid);

            pid_t pid = getpid();
            gen.update_obj_bits(pid);

            pid = getppid();
            gen.update_obj_bits(pid);
            gen.update((uint64_t) & pid);

            ticks -= timer::get_ticks();
            tick_hist[i] = ticks;
            gen.update(ticks);

            ticks = timer::get_ticks();

            // Get some entropy from the stack.
            char purposely_uninitialized_buf[256];
            gen.update(purposely_uninitialized_buf, sizeof(purposely_uninitialized_buf));

            // Get some entropy from the heap.
            p[i] = vogl_malloc(65536 * (i + 1));
            gen.update_obj_bits(p[i]);
            if (p[i])
            {
                for (uint j = 0; j < 16; j++)
                    gen.update_obj_bits(reinterpret_cast<const uint64_t *>(p)[j]);
            }

            struct timeval tv;
            gettimeofday(&tv, NULL);
            gen.update_obj_bits(tv);

            // Hash the current environment
            uint e = 0;
            while (environ[e])
            {
                gen.update(environ[e], vogl_strlen(environ[e]));
                ++e;
            }

            uint64_t s = utils::RDTSC();

            // Try to get some entropy from the scheduler.
            vogl_sleep(2);

            gen.update(utils::RDTSC() - s);

            ticks -= timer::get_ticks();
            gen.update(ticks);

            gen.update(utils::RDTSC() - start_rdtsc);
        }

        for (uint i = 1; i < N; i++)
        {
            uint64_t t = tick_hist[i] - tick_hist[i - 1];
            gen.update(t);
        }

        for (uint i = 0; i < N; i++)
            vogl_free(p[i]);

        return gen.finalize();
    }