Changeset 2443ad8 in mainline
- Timestamp:
- 2019-10-02T09:27:57Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9dcf472
- Parents:
- 6fa3a03
- git-author:
- Jiri Svoboda <jiri@…> (2019-10-01 17:23:52)
- git-committer:
- Jiri Svoboda <jiri@…> (2019-10-02 09:27:57)
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/trace/trace.c
r6fa3a03 r2443ad8 47 47 #include <mem.h> 48 48 #include <str.h> 49 #include <loader/loader.h>50 49 #include <io/console.h> 51 50 #include <io/keycode.h> … … 86 85 void thread_trace_start(uintptr_t thread_hash); 87 86 87 static char *cmd_path; 88 static char **cmd_args; 89 88 90 static task_id_t task_id; 89 static loader_t *task_ldr;90 91 static bool task_wait_for; 91 92 … … 93 94 display_mask_t display_mask; 94 95 95 static errno_t program_run_fibril(void *arg);96 96 static errno_t cev_fibril(void *arg); 97 98 static 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 }110 97 111 98 static void cev_fibril_start(void) … … 122 109 } 123 110 124 static errno_t program_run_fibril(void *arg) 125 { 126 errno_t rc; 127 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); 111 static errno_t program_run(void) 112 { 113 errno_t rc; 114 115 rc = task_spawnv_debug(&task_id, NULL, cmd_path, 116 (const char *const *)cmd_args, &sess); 117 118 if (rc == ENOTSUP) { 119 printf("You do not have userspace debugging support " 120 "compiled in the kernel.\n"); 121 printf("Compile kernel with 'Support for userspace debuggers' " 122 "(CONFIG_UDEBUG) enabled.\n"); 123 } 124 133 125 if (rc != EOK) { 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; 126 printf("Error running program (%s)\n", str_error_name(rc)); 127 return rc; 128 } 129 130 return EOK; 142 131 } 143 132 144 133 static errno_t connect_task(task_id_t task_id) 145 134 { 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)); 165 return rc; 166 } 167 168 rc = udebug_set_evmask(ksess, UDEBUG_EM_ALL); 135 errno_t rc; 136 bool debug_started = false; 137 138 if (sess == NULL) { 139 sess = async_connect_kbox(task_id); 140 if (sess == NULL) { 141 printf("Error connecting to task %" PRIu64 ".\n", 142 task_id); 143 goto error; 144 } 145 146 rc = udebug_begin(sess); 147 if (rc != EOK) { 148 printf("Error starting debug session.\n"); 149 goto error; 150 } 151 152 debug_started = true; 153 } 154 155 rc = udebug_set_evmask(sess, UDEBUG_EM_ALL); 169 156 if (rc != EOK) { 170 157 printf("udebug_set_evmask(0x%x) -> %s\n ", UDEBUG_EM_ALL, str_error_name(rc)); … … 172 159 } 173 160 174 sess = ksess; 175 return 0; 161 return EOK; 162 error: 163 if (debug_started) 164 udebug_end(sess); 165 if (sess != NULL) 166 async_hangup(sess); 167 return rc; 176 168 } 177 169 … … 198 190 printf("\ntotal of %zu threads\n", tb_needed / sizeof(uintptr_t)); 199 191 200 return 0;192 return EOK; 201 193 } 202 194 … … 488 480 489 481 printf("Finished tracing thread [%d].\n", thread_id); 490 return 0;482 return EOK; 491 483 } 492 484 … … 502 494 } 503 495 fibril_add_ready(fid); 504 }505 506 static 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 */573 error:574 loader_abort(ldr);575 return NULL;576 496 } 577 497 … … 807 727 ++argv; 808 728 task_id = strtol(*argv, &err_p, 10); 809 task_ldr = NULL;810 729 task_wait_for = false; 811 730 if (*err_p) { … … 848 767 printf("'%s'\n", *cp++); 849 768 850 task_ldr = preload_task(*argv, argv, &task_id); 769 cmd_path = *argv; 770 cmd_args = argv; 851 771 task_wait_for = true; 852 772 … … 869 789 870 790 main_init(); 791 792 if (cmd_path != NULL) 793 program_run(); 871 794 872 795 rc = connect_task(task_id); … … 877 800 878 801 printf("Connected to task %" PRIu64 ".\n", task_id); 879 880 if (task_ldr != NULL)881 program_run();882 802 883 803 cev_fibril_start(); -
uspace/lib/c/generic/loader.c
r6fa3a03 r2443ad8 345 345 } 346 346 347 /** Instruct loader to execute the program and do not wait for reply. 348 * 349 * This function does not block even if the loaded task is stopped 350 * for debugging. 351 * 352 * After using this function, no further operations can be performed 353 * on the loader structure and it is deallocated. 354 * 355 * @param ldr Loader connection structure. 356 * 357 * @return Zero on success or an error code. 358 * 359 */ 360 void loader_run_nowait(loader_t *ldr) 361 { 362 async_exch_t *exch = async_exchange_begin(ldr->sess); 363 async_msg_0(exch, LOADER_RUN); 364 async_exchange_end(exch); 365 366 async_hangup(ldr->sess); 367 free(ldr); 368 } 369 347 370 /** Cancel the loader session. 348 371 * -
uspace/lib/c/generic/task.c
r6fa3a03 r2443ad8 35 35 */ 36 36 37 #include <async.h> 37 38 #include <task.h> 38 39 #include <loader/loader.h> … … 46 47 #include <ns.h> 47 48 #include <stdlib.h> 49 #include <udebug.h> 48 50 #include <libc.h> 49 51 #include "private/ns.h" … … 94 96 * This is really just a convenience wrapper over the more complicated 95 97 * loader API. Arguments are passed as a null-terminated array of strings. 98 * A debug session is created optionally. 96 99 * 97 100 * @param id If not NULL, the ID of the task is stored here on success. … … 100 103 * @param path Pathname of the binary to execute. 101 104 * @param argv Command-line arguments. 102 * 103 * @return Zero on success or an error code. 104 * 105 */ 106 errno_t task_spawnv(task_id_t *id, task_wait_t *wait, const char *path, 107 const char *const args[]) 105 * @param rsess Place to store pointer to debug session or @c NULL 106 * not to start a debug session 107 * 108 * @return Zero on success or an error code. 109 * 110 */ 111 errno_t task_spawnv_debug(task_id_t *id, task_wait_t *wait, const char *path, 112 const char *const args[], async_sess_t **rsess) 108 113 { 109 114 /* Send default files */ … … 125 130 } 126 131 127 return task_spawnvf (id, wait, path, args, fd_stdin, fd_stdout,128 fd_stderr );132 return task_spawnvf_debug(id, wait, path, args, fd_stdin, fd_stdout, 133 fd_stderr, rsess); 129 134 } 130 135 131 136 /** Create a new task by running an executable from the filesystem. 137 * 138 * This is really just a convenience wrapper over the more complicated 139 * loader API. Arguments are passed as a null-terminated array of strings. 140 * 141 * @param id If not NULL, the ID of the task is stored here on success. 142 * @param wait If not NULL, setup waiting for task's return value and store 143 * the information necessary for waiting here on success. 144 * @param path Pathname of the binary to execute. 145 * @param argv Command-line arguments. 146 * 147 * @return Zero on success or an error code. 148 * 149 */ 150 errno_t task_spawnv(task_id_t *id, task_wait_t *wait, const char *path, 151 const char *const args[]) 152 { 153 return task_spawnv_debug(id, wait, path, args, NULL); 154 } 155 156 /** Create a new task by loading an executable from the filesystem. 132 157 * 133 158 * This is really just a convenience wrapper over the more complicated 134 159 * loader API. Arguments are passed as a null-terminated array of strings. 135 160 * Files are passed as null-terminated array of pointers to fdi_node_t. 161 * A debug session is created optionally. 136 162 * 137 163 * @param id If not NULL, the ID of the task is stored here on success. 138 * @param wait If not NULL, setup waiting for task's return value and store 164 * @param wait If not NULL, setup waiting for task's return value and store. 139 165 * @param path Pathname of the binary to execute. 140 * @param argv Command-line arguments. 141 * @param std_in File to use as stdin. 142 * @param std_out File to use as stdout. 143 * @param std_err File to use as stderr. 144 * 145 * @return Zero on success or an error code. 146 * 147 */ 148 errno_t task_spawnvf(task_id_t *id, task_wait_t *wait, const char *path, 149 const char *const args[], int fd_stdin, int fd_stdout, int fd_stderr) 150 { 166 * @param argv Command-line arguments 167 * @param std_in File to use as stdin 168 * @param std_out File to use as stdout 169 * @param std_err File to use as stderr 170 * @param rsess Place to store pointer to debug session or @c NULL 171 * not to start a debug session 172 * 173 * @return Zero on success or an error code 174 * 175 */ 176 errno_t task_spawnvf_debug(task_id_t *id, task_wait_t *wait, 177 const char *path, const char *const args[], int fd_stdin, int fd_stdout, 178 int fd_stderr, async_sess_t **rsess) 179 { 180 async_sess_t *ksess = NULL; 181 151 182 /* Connect to a program loader. */ 152 183 loader_t *ldr = loader_connect(); … … 217 248 } 218 249 219 /* Run it. */ 220 rc = loader_run(ldr); 221 if (rc != EOK) 222 goto error; 250 /* Start a debug session if requested */ 251 if (rsess != NULL) { 252 ksess = async_connect_kbox(task_id); 253 if (ksess == NULL) { 254 /* Most likely debugging support is not compiled in */ 255 rc = ENOTSUP; 256 goto error; 257 } 258 259 rc = udebug_begin(ksess); 260 if (rc != EOK) 261 goto error; 262 263 /* 264 * Run it, not waiting for response. It would never come 265 * as the loader is stopped. 266 */ 267 loader_run_nowait(ldr); 268 } else { 269 /* Run it. */ 270 rc = loader_run(ldr); 271 if (rc != EOK) 272 goto error; 273 } 223 274 224 275 /* Success */ 225 276 if (id != NULL) 226 277 *id = task_id; 227 278 if (rsess != NULL) 279 *rsess = ksess; 228 280 return EOK; 229 281 230 282 error: 283 if (ksess != NULL) 284 async_hangup(ksess); 231 285 if (wait_initialized) 232 286 task_cancel_wait(wait); … … 235 289 loader_abort(ldr); 236 290 return rc; 291 } 292 293 /** Create a new task by running an executable from the filesystem. 294 * 295 * Arguments are passed as a null-terminated array of strings. 296 * Files are passed as null-terminated array of pointers to fdi_node_t. 297 * 298 * @param id If not NULL, the ID of the task is stored here on success. 299 * @param wait If not NULL, setup waiting for task's return value and store. 300 * @param path Pathname of the binary to execute 301 * @param argv Command-line arguments 302 * @param std_in File to use as stdin 303 * @param std_out File to use as stdout 304 * @param std_err File to use as stderr 305 * 306 * @return Zero on success or an error code. 307 * 308 */ 309 errno_t task_spawnvf(task_id_t *id, task_wait_t *wait, const char *path, 310 const char *const args[], int fd_stdin, int fd_stdout, int fd_stderr) 311 { 312 return task_spawnvf_debug(id, wait, path, args, fd_stdin, fd_stdout, 313 fd_stderr, NULL); 237 314 } 238 315 -
uspace/lib/c/include/loader/loader.h
r6fa3a03 r2443ad8 53 53 extern errno_t loader_load_program(loader_t *); 54 54 extern errno_t loader_run(loader_t *); 55 extern void loader_run_nowait(loader_t *); 55 56 extern void loader_abort(loader_t *); 56 57 -
uspace/lib/c/include/task.h
r6fa3a03 r2443ad8 36 36 #define _LIBC_TASK_H_ 37 37 38 #include <async.h> 38 39 #include <stdint.h> 39 40 #include <stdarg.h> … … 56 57 extern errno_t task_spawnv(task_id_t *, task_wait_t *, const char *path, 57 58 const char *const []); 59 extern errno_t task_spawnv_debug(task_id_t *, task_wait_t *, const char *path, 60 const char *const [], async_sess_t **); 58 61 extern errno_t task_spawnvf(task_id_t *, task_wait_t *, const char *path, 59 62 const char *const [], int, int, int); 63 extern errno_t task_spawnvf_debug(task_id_t *, task_wait_t *, const char *path, 64 const char *const [], int, int, int, async_sess_t **); 60 65 extern errno_t task_spawn(task_id_t *, task_wait_t *, const char *path, int, 61 66 va_list ap);
Note:
See TracChangeset
for help on using the changeset viewer.