Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/trace/trace.c

    r01900b6 rfafb8e5  
    4747#include <mem.h>
    4848#include <str.h>
     49#include <loader/loader.h>
    4950#include <io/console.h>
    5051#include <io/keycode.h>
     
    8586void thread_trace_start(uintptr_t thread_hash);
    8687
    87 static char *cmd_path;
    88 static char **cmd_args;
    89 
    9088static task_id_t task_id;
    91 static task_wait_t task_w;
     89static loader_t *task_ldr;
    9290static bool task_wait_for;
    9391
     
    9593display_mask_t display_mask;
    9694
     95static errno_t program_run_fibril(void *arg);
    9796static errno_t cev_fibril(void *arg);
     97
     98static void program_run(void)
     99{
     100        fid_t fid;
     101
     102        fid = fibril_create(program_run_fibril, NULL);
     103        if (fid == 0) {
     104                printf("Error creating fibril\n");
     105                exit(1);
     106        }
     107
     108        fibril_add_ready(fid);
     109}
    98110
    99111static void cev_fibril_start(void)
     
    110122}
    111123
    112 static errno_t program_run(void)
     124static errno_t program_run_fibril(void *arg)
    113125{
    114126        errno_t rc;
    115127
    116         rc = task_spawnv_debug(&task_id, &task_w, cmd_path,
    117             (const char *const *)cmd_args, &sess);
    118 
    119         if (rc == ENOTSUP) {
    120                 printf("You do not have userspace debugging support "
    121                     "compiled in the kernel.\n");
    122                 printf("Compile kernel with 'Support for userspace debuggers' "
    123                     "(CONFIG_UDEBUG) enabled.\n");
    124         }
    125 
     128        /*
     129         * This must be done in background as it will block until
     130         * we let the task reply to this call.
     131         */
     132        rc = loader_run(task_ldr);
    126133        if (rc != EOK) {
    127                 printf("Error running program (%s)\n", str_error_name(rc));
     134                printf("Error running program\n");
     135                exit(1);
     136        }
     137
     138        task_ldr = NULL;
     139
     140        printf("program_run_fibril exiting\n");
     141        return 0;
     142}
     143
     144static errno_t connect_task(task_id_t task_id)
     145{
     146        async_sess_t *ksess = async_connect_kbox(task_id);
     147
     148        if (!ksess) {
     149                if (errno == ENOTSUP) {
     150                        printf("You do not have userspace debugging support "
     151                            "compiled in the kernel.\n");
     152                        printf("Compile kernel with 'Support for userspace debuggers' "
     153                            "(CONFIG_UDEBUG) enabled.\n");
     154                        return errno;
     155                }
     156
     157                printf("Error connecting\n");
     158                printf("ipc_connect_task(%" PRIu64 ") -> %s ", task_id, str_error_name(errno));
     159                return errno;
     160        }
     161
     162        errno_t rc = udebug_begin(ksess);
     163        if (rc != EOK) {
     164                printf("udebug_begin() -> %s\n", str_error_name(rc));
    128165                return rc;
    129166        }
    130167
    131         return EOK;
    132 }
    133 
    134 static errno_t connect_task(task_id_t task_id)
    135 {
    136         errno_t rc;
    137         bool debug_started = false;
    138         bool wait_set_up = false;
    139 
    140         if (sess == NULL) {
    141                 sess = async_connect_kbox(task_id, &rc);
    142                 if (sess == NULL) {
    143                         printf("Error connecting to task %" PRIu64 ".\n",
    144                             task_id);
    145                         goto error;
    146                 }
    147 
    148                 rc = udebug_begin(sess);
    149                 if (rc != EOK) {
    150                         printf("Error starting debug session.\n");
    151                         goto error;
    152                 }
    153 
    154                 debug_started = true;
    155 
    156                 rc = task_setup_wait(task_id, &task_w);
    157                 if (rc != EOK) {
    158                         printf("Error setting up wait for task termination.\n");
    159                         goto error;
    160                 }
    161 
    162                 wait_set_up = true;
    163         }
    164 
    165         rc = udebug_set_evmask(sess, UDEBUG_EM_ALL);
     168        rc = udebug_set_evmask(ksess, UDEBUG_EM_ALL);
    166169        if (rc != EOK) {
    167170                printf("udebug_set_evmask(0x%x) -> %s\n ", UDEBUG_EM_ALL, str_error_name(rc));
     
    169172        }
    170173
    171         return EOK;
    172 error:
    173         if (wait_set_up)
    174                 task_cancel_wait(&task_w);
    175         if (debug_started)
    176                 udebug_end(sess);
    177         if (sess != NULL)
    178                 async_hangup(sess);
    179         return rc;
     174        sess = ksess;
     175        return 0;
    180176}
    181177
     
    202198        printf("\ntotal of %zu threads\n", tb_needed / sizeof(uintptr_t));
    203199
    204         return EOK;
     200        return 0;
    205201}
    206202
     
    492488
    493489        printf("Finished tracing thread [%d].\n", thread_id);
    494         return EOK;
     490        return 0;
    495491}
    496492
     
    506502        }
    507503        fibril_add_ready(fid);
     504}
     505
     506static loader_t *preload_task(const char *path, char **argv,
     507    task_id_t *task_id)
     508{
     509        loader_t *ldr;
     510        errno_t rc;
     511
     512        /* Spawn a program loader */
     513        ldr = loader_connect();
     514        if (ldr == NULL)
     515                return NULL;
     516
     517        /* Get task ID. */
     518        rc = loader_get_task_id(ldr, task_id);
     519        if (rc != EOK)
     520                goto error;
     521
     522        /* Send program. */
     523        rc = loader_set_program_path(ldr, path);
     524        if (rc != EOK)
     525                goto error;
     526
     527        /* Send arguments */
     528        rc = loader_set_args(ldr, (const char **) argv);
     529        if (rc != EOK)
     530                goto error;
     531
     532        /* Send default files */
     533        int fd_root;
     534        int fd_stdin;
     535        int fd_stdout;
     536        int fd_stderr;
     537
     538        fd_root = vfs_root();
     539        if (fd_root >= 0) {
     540                rc = loader_add_inbox(ldr, "root", fd_root);
     541                vfs_put(fd_root);
     542                if (rc != EOK)
     543                        goto error;
     544        }
     545
     546        if ((stdin != NULL) && (vfs_fhandle(stdin, &fd_stdin) == EOK)) {
     547                rc = loader_add_inbox(ldr, "stdin", fd_stdin);
     548                if (rc != EOK)
     549                        goto error;
     550        }
     551
     552        if ((stdout != NULL) && (vfs_fhandle(stdout, &fd_stdout) == EOK)) {
     553                rc = loader_add_inbox(ldr, "stdout", fd_stdout);
     554                if (rc != EOK)
     555                        goto error;
     556        }
     557
     558        if ((stderr != NULL) && (vfs_fhandle(stderr, &fd_stderr) == EOK)) {
     559                rc = loader_add_inbox(ldr, "stderr", fd_stderr);
     560                if (rc != EOK)
     561                        goto error;
     562        }
     563
     564        /* Load the program. */
     565        rc = loader_load_program(ldr);
     566        if (rc != EOK)
     567                goto error;
     568
     569        /* Success */
     570        return ldr;
     571
     572        /* Error exit */
     573error:
     574        loader_abort(ldr);
     575        return NULL;
    508576}
    509577
     
    739807                                ++argv;
    740808                                task_id = strtol(*argv, &err_p, 10);
     809                                task_ldr = NULL;
    741810                                task_wait_for = false;
    742811                                if (*err_p) {
     
    779848                printf("'%s'\n", *cp++);
    780849
    781         cmd_path = *argv;
    782         cmd_args = argv;
     850        task_ldr = preload_task(*argv, argv, &task_id);
    783851        task_wait_for = true;
    784852
     
    801869
    802870        main_init();
    803 
    804         if (cmd_path != NULL)
    805                 program_run();
    806871
    807872        rc = connect_task(task_id);
     
    813878        printf("Connected to task %" PRIu64 ".\n", task_id);
    814879
     880        if (task_ldr != NULL)
     881                program_run();
     882
    815883        cev_fibril_start();
    816884        trace_task(task_id);
     
    819887                printf("Waiting for task to exit.\n");
    820888
    821                 rc = task_wait(&task_w, &texit, &retval);
     889                rc = task_wait_task_id(task_id, &texit, &retval);
    822890                if (rc != EOK) {
    823891                        printf("Failed waiting for task.\n");
Note: See TracChangeset for help on using the changeset viewer.