
Read the command line of the main target process as well as any other process Delve attaches to in follow exec mode. The command line can be viewed using the 'target list' command. In follow exec mode this command line is used to match the follow exec regex to decide whether or not to attach to a child process. On macOS or when using rr the list of arguments is not available for attached processes since there is no way to use the gdb serial protocol to read it. Fixes #2242
95 lines
2.0 KiB
C
95 lines
2.0 KiB
C
#include <sys/param.h>
|
|
#include <sys/mount.h>
|
|
#include <sys/queue.h>
|
|
#include <sys/sysctl.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include "proc_freebsd.h"
|
|
|
|
/*
|
|
* Returns the absolute pathname of the process's executable, if one was found.
|
|
* Must be freed by the caller. Sets errno on failure.
|
|
*/
|
|
char * find_executable(int pid) {
|
|
struct procstat *ps;
|
|
struct kinfo_proc *kp;
|
|
char *pathname;
|
|
|
|
/*
|
|
* procstat_open_sysctl is for running processes. For core files, use
|
|
* procstat_open_core
|
|
*/
|
|
ps = procstat_open_sysctl();
|
|
kp = kinfo_getproc(pid);
|
|
pathname = malloc(MNAMELEN);
|
|
if (ps && kp && pathname)
|
|
procstat_getpathname(ps, kp, pathname, MNAMELEN);
|
|
free(kp);
|
|
procstat_close(ps);
|
|
return (pathname);
|
|
}
|
|
|
|
/*
|
|
* Returns the comm value of the process, which is usually the basename of its
|
|
* executable. Must be freed by the caller. Sets errno on failure.
|
|
*/
|
|
char * find_command_name(int pid) {
|
|
char *command_name = NULL;
|
|
struct kinfo_proc *kinfo;
|
|
|
|
kinfo = kinfo_getproc(pid);
|
|
if (kinfo != NULL) {
|
|
command_name = malloc(COMMLEN + 1);
|
|
if (command_name != NULL)
|
|
strlcpy(command_name, kinfo->ki_comm, COMMLEN + 1);
|
|
free(kinfo);
|
|
}
|
|
|
|
return (command_name);
|
|
}
|
|
|
|
int find_status(int pid){
|
|
char status;
|
|
struct kinfo_proc *kinfo;
|
|
kinfo = kinfo_getproc(pid);
|
|
if (kinfo != NULL)
|
|
status = kinfo->ki_stat;
|
|
else
|
|
status = '?';
|
|
free(kinfo);
|
|
|
|
return (status);
|
|
}
|
|
|
|
uintptr_t get_entry_point(int pid) {
|
|
void *ep = NULL;
|
|
|
|
errno = EINVAL;
|
|
|
|
struct procstat *ps = procstat_open_sysctl();
|
|
if (ps == NULL)
|
|
return 0;
|
|
|
|
uint cnt = 0;
|
|
struct kinfo_proc *kipp = procstat_getprocs(ps, KERN_PROC_PID, pid, &cnt);
|
|
if (cnt == 0)
|
|
return 0;
|
|
|
|
Elf_Auxinfo *auxv = procstat_getauxv(ps, kipp, &cnt);
|
|
if (auxv == NULL)
|
|
return 0;
|
|
|
|
for (int i = 0; i < cnt; i++) {
|
|
if (auxv[i].a_type == AT_ENTRY) {
|
|
ep = auxv[i].a_un.a_ptr;
|
|
break;
|
|
}
|
|
}
|
|
procstat_freeauxv(ps, auxv);
|
|
errno = 0;
|
|
return (uintptr_t)ep;
|
|
}
|