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.
7 #include "debug_utils.h"
18 #include <libroot_private.h>
22 extern const char* __progname
;
23 static const char* kCommandName
= __progname
;
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
;
38 // get the PATH environment variable
39 const char* paths
= getenv("PATH");
41 return B_ENTRY_NOT_FOUND
;
43 // iterate through the paths
45 const char* pathEnd
= strchr(paths
, ':');
46 int pathLen
= (pathEnd
? pathEnd
- paths
: strlen(paths
));
48 // We skip empty paths.
50 // get the program path
51 std::string
path(paths
, pathLen
);
55 // stat() the path to be sure, there is a file
57 if (stat(path
.c_str(), &st
) == 0 && S_ISREG(st
.st_mode
)) {
63 paths
= (pathEnd
? pathEnd
+ 1 : NULL
);
67 return B_ENTRY_NOT_FOUND
;
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
);
90 mutableArgs
[0] = programPath
.c_str();
92 // count environment variables
94 while (environ
[envCount
] != NULL
)
97 // flatten the program args and environment
98 char** flatArgs
= NULL
;
100 error
= __flatten_process_args(mutableArgs
, argCount
, environ
, &envCount
,
101 mutableArgs
[0], &flatArgs
, &flatArgsSize
);
106 thread
= _kern_load_image(flatArgs
, flatArgsSize
, argCount
, envCount
,
107 B_NORMAL_PRIORITY
, (traceLoading
? 0 : B_WAIT_TILL_LOADED
), -1, 0);
113 delete[] mutableArgs
;
119 // set_team_debugging_flags
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
;
128 error
= write_port(nubPort
, B_DEBUG_MESSAGE_SET_TEAM_FLAGS
,
129 &message
, sizeof(message
));
130 } while (error
== B_INTERRUPTED
);
133 fprintf(stderr
, "%s: Failed to set team debug flags: %s\n",
134 kCommandName
, strerror(error
));
141 // set_thread_debugging_flags
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
;
151 error
= write_port(nubPort
, B_DEBUG_MESSAGE_SET_THREAD_FLAGS
,
152 &message
, sizeof(message
));
153 } while (error
== B_INTERRUPTED
);
156 fprintf(stderr
, "%s: Failed to set thread debug flags: %s\n",
157 kCommandName
, strerror(error
));
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
;
176 error
= write_port(nubPort
, B_DEBUG_MESSAGE_CONTINUE_THREAD
,
177 &message
, sizeof(message
));
178 } while (error
== B_INTERRUPTED
);
181 fprintf(stderr
, "%s: Failed to run thread %" B_PRId32
": %s\n",
182 kCommandName
, thread
, strerror(error
));