vfs: check userland buffers before reading them.
[haiku.git] / src / bin / debug / debug_utils.cpp
blob4bfc3612972a575a0ef68664a4c882b748a9c29e
1 /*
2 * Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2013, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
7 #include "debug_utils.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/stat.h>
13 #include <string>
14 #include <string.h>
16 #include <debugger.h>
18 #include <libroot_private.h>
19 #include <syscalls.h>
22 extern const char* __progname;
23 static const char* kCommandName = __progname;
26 // find_program
27 static status_t
28 find_program(const char* programName, std::string& resolvedPath)
30 // If the program name is absolute, then there's nothing to do.
31 // If the program name consists of more than one path element, then we
32 // consider it a relative path and don't search in PATH either.
33 if (*programName == '/' || strchr(programName, '/')) {
34 resolvedPath = programName;
35 return B_OK;
38 // get the PATH environment variable
39 const char* paths = getenv("PATH");
40 if (!paths)
41 return B_ENTRY_NOT_FOUND;
43 // iterate through the paths
44 do {
45 const char* pathEnd = strchr(paths, ':');
46 int pathLen = (pathEnd ? pathEnd - paths : strlen(paths));
48 // We skip empty paths.
49 if (pathLen > 0) {
50 // get the program path
51 std::string path(paths, pathLen);
52 path += "/";
53 path += programName;
55 // stat() the path to be sure, there is a file
56 struct stat st;
57 if (stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode)) {
58 resolvedPath = path;
59 return B_OK;
63 paths = (pathEnd ? pathEnd + 1 : NULL);
64 } while (paths);
66 // not found in PATH
67 return B_ENTRY_NOT_FOUND;
71 // #pragma mark -
74 // load_program
75 thread_id
76 load_program(const char* const* args, int32 argCount, bool traceLoading)
78 // clone the argument vector so that we can change it
79 const char** mutableArgs = new const char*[argCount];
80 for (int i = 0; i < argCount; i++)
81 mutableArgs[i] = args[i];
83 // resolve the program path
84 std::string programPath;
85 status_t error = find_program(args[0], programPath);
86 if (error != B_OK) {
87 delete[] mutableArgs;
88 return error;
90 mutableArgs[0] = programPath.c_str();
92 // count environment variables
93 int32 envCount = 0;
94 while (environ[envCount] != NULL)
95 envCount++;
97 // flatten the program args and environment
98 char** flatArgs = NULL;
99 size_t flatArgsSize;
100 error = __flatten_process_args(mutableArgs, argCount, environ, &envCount,
101 mutableArgs[0], &flatArgs, &flatArgsSize);
103 // load the program
104 thread_id thread;
105 if (error == B_OK) {
106 thread = _kern_load_image(flatArgs, flatArgsSize, argCount, envCount,
107 B_NORMAL_PRIORITY, (traceLoading ? 0 : B_WAIT_TILL_LOADED), -1, 0);
109 free(flatArgs);
110 } else
111 thread = error;
113 delete[] mutableArgs;
115 return thread;
119 // set_team_debugging_flags
120 status_t
121 set_team_debugging_flags(port_id nubPort, int32 flags)
123 debug_nub_set_team_flags message;
124 message.flags = flags;
126 status_t error = B_OK;
127 do {
128 error = write_port(nubPort, B_DEBUG_MESSAGE_SET_TEAM_FLAGS,
129 &message, sizeof(message));
130 } while (error == B_INTERRUPTED);
132 if (error != B_OK) {
133 fprintf(stderr, "%s: Failed to set team debug flags: %s\n",
134 kCommandName, strerror(error));
137 return error;
141 // set_thread_debugging_flags
142 status_t
143 set_thread_debugging_flags(port_id nubPort, thread_id thread, int32 flags)
145 debug_nub_set_thread_flags message;
146 message.thread = thread;
147 message.flags = flags;
149 status_t error = B_OK;
150 do {
151 error = write_port(nubPort, B_DEBUG_MESSAGE_SET_THREAD_FLAGS,
152 &message, sizeof(message));
153 } while (error == B_INTERRUPTED);
155 if (error != B_OK) {
156 fprintf(stderr, "%s: Failed to set thread debug flags: %s\n",
157 kCommandName, strerror(error));
160 return error;
164 // continue_thread
165 status_t
166 continue_thread(port_id nubPort, thread_id thread)
168 debug_nub_continue_thread message;
169 message.thread = thread;
170 message.handle_event = B_THREAD_DEBUG_HANDLE_EVENT;
171 message.single_step = false;
173 status_t error = B_OK;
175 do {
176 error = write_port(nubPort, B_DEBUG_MESSAGE_CONTINUE_THREAD,
177 &message, sizeof(message));
178 } while (error == B_INTERRUPTED);
180 if (error != B_OK) {
181 fprintf(stderr, "%s: Failed to run thread %" B_PRId32 ": %s\n",
182 kCommandName, thread, strerror(error));
185 return error;