/[hurd]/hurd/exec/elfcore.c
ViewVC logotype

Diff of /hurd/exec/elfcore.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by roland, Sat Mar 9 07:31:40 2002 UTC revision 1.5 by roland, Mon Mar 11 01:13:00 2002 UTC
# Line 2  Line 2 
2  #include <elf.h>  #include <elf.h>
3  #include <link.h>  #include <link.h>
4  #include <string.h>  #include <string.h>
5    #include <argz.h>
6  #include <sys/mman.h>  #include <sys/mman.h>
7  #include <sys/utsname.h>  #include <sys/utsname.h>
8    #include <sys/procfs.h>
9    #include <stddef.h>
10    
11    
12  #define ELF_MACHINE     EM_386  /* XXX */  #define ELF_MACHINE     EM_386  /* XXX */
# Line 20  Line 23 
23  #endif  #endif
24    
25    
26    #define TIME_VALUE_TO_TIMESPEC(tv, ts) \
27      TIMEVAL_TO_TIMESPEC ((struct timeval *) (tv), (ts))
28    
29    #define PAGES_TO_KB(x)  ((x) * (vm_page_size / 1024))
30    #define ENCODE_PCT(f)   ((uint16_t) ((f) * 32768.0))
31    
32    extern process_t procserver;
33    
34  error_t  error_t
35  dump_core (task_t task, file_t file, off_t corelimit,  dump_core (task_t task, file_t file, off_t corelimit,
36             int signo, long int sigcode, int sigerror)             int signo, long int sigcode, int sigerror)
37  {  {
38      static float host_memory_size = -1.0;
39    error_t err;    error_t err;
40    ElfW(Phdr) *phdrs, *ph;    ElfW(Phdr) *phdrs, *ph;
41    ElfW(Ehdr) hdr =              /* ELF header for the core file.  */    ElfW(Ehdr) hdr =              /* ELF header for the core file.  */
# Line 50  dump_core (task_t task, file_t file, off Line 62  dump_core (task_t task, file_t file, off
62    off_t offset;    off_t offset;
63    size_t wrote;    size_t wrote;
64    
65      pid_t pid;
66    thread_t *threads;    thread_t *threads;
67    size_t nthreads, i;    size_t nthreads, i;
68    off_t notestart;    off_t notestart;
# Line 194  dump_core (task_t task, file_t file, off Line 207  dump_core (task_t task, file_t file, off
207    if (err || (corelimit >= 0 && corelimit <= offset))    if (err || (corelimit >= 0 && corelimit <= offset))
208      return err;      return err;
209    
210  #if 0    err = proc_task2pid (procserver, task, &pid);
211    /* The pstatus_t note should contain the death info and some process-global    if (err)
212       info we should get from the proc server, but no thread-specific info      return err;
213       like register state.  We need to define this type.  */  
214      /* Make sure we have the total RAM size of the host.
215         We only do this once, assuming that it won't change.
216         XXX this could use the task's host-self port instead. */
217      if (host_memory_size <= 0.0)
218        {
219          host_basic_info_data_t hostinfo;
220          mach_msg_type_number_t size = sizeof hostinfo;
221          error_t err = host_info (mach_host_self (), HOST_BASIC_INFO,
222                                   (host_info_t) &hostinfo, &size);
223          if (err == 0)
224            host_memory_size = hostinfo.memory_size;
225        }
226    
227      /* The psinfo_t note contains some process-global info we should get from
228         the proc server, but no thread-specific info like register state.  */
229    {    {
230      DEFINE_NOTE (pstatus_t) note;      DEFINE_NOTE (psinfo_t) note;
231        int flags = PI_FETCH_TASKINFO | PI_FETCH_THREADS | PI_FETCH_THREAD_BASIC;
232        char *waits = 0;
233        mach_msg_type_number_t num_waits = 0;
234        char pibuf[offsetof (struct procinfo, threadinfos[2])];
235        struct procinfo *pi = (void *) &pibuf;
236        mach_msg_type_number_t pi_size = sizeof pibuf;
237        err = proc_getprocinfo (procserver, pid, &flags,
238                                (procinfo_t *) &pi, &pi_size,
239                                &waits, &num_waits);
240        if (err == 0)
241          {
242            if (num_waits != 0)
243              munmap (waits, num_waits);
244            memset (&note.data, 0, sizeof note.data);
245            note.data.pr_flag = pi->state;
246            note.data.pr_nlwp = pi->nthreads;
247            note.data.pr_pid = pid;
248            note.data.pr_ppid = pi->ppid;
249            note.data.pr_pgid = pi->pgrp;
250            note.data.pr_sid = pi->session;
251            note.data.pr_euid = pi->owner;
252            /* XXX struct procinfo should have these */
253            note.data.pr_egid = note.data.pr_gid = note.data.pr_uid = -1;
254            note.data.pr_size = PAGES_TO_KB (pi->taskinfo.virtual_size);
255            note.data.pr_rssize = PAGES_TO_KB (pi->taskinfo.resident_size);
256            {
257              /* Sum all the threads' cpu_usage fields.  */
258              integer_t cpu_usage = 0;
259              for (i = 0; i < pi->nthreads; ++i)
260                cpu_usage += pi->threadinfos[i].pis_bi.cpu_usage;
261              note.data.pr_pctcpu = ENCODE_PCT ((float) cpu_usage
262                                                / (float) TH_USAGE_SCALE);
263            }
264            if (host_memory_size > 0.0)
265              note.data.pr_pctmem = ENCODE_PCT ((float) pi->taskinfo.resident_size
266                                                / host_memory_size);
267            TIME_VALUE_TO_TIMESPEC (&pi->taskinfo.creation_time,
268                                    &note.data.pr_start);
269            timeradd ((const struct timeval *) &pi->taskinfo.user_time,
270                      (const struct timeval *) &pi->taskinfo.system_time,
271                      (struct timeval *) &pi->taskinfo.user_time);
272            TIME_VALUE_TO_TIMESPEC (&pi->taskinfo.user_time, &note.data.pr_time);
273            /* XXX struct procinfo should have dead child info for pr_ctime */
274            note.data.pr_wstat = pi->exitstatus;
275            {
276              /* We have to nab the process's own proc port to get the
277                 proc server to tell us its registered arg locations.  */
278              process_t proc;
279              err = proc_task2proc (procserver, task, &proc);
280              if (err == 0)
281                {
282                  err = proc_get_arg_locations (proc,
283                                                &note.data.pr_argv,
284                                                &note.data.pr_envp);
285                  mach_port_deallocate (mach_task_self (), proc);
286                }
287              err = 0;
288            }
289            {
290              /* Now fetch the arguments.  We could do this directly from the
291                 task given the locations we now have.  But we are lazy and have
292                 the proc server do it for us.  */
293              char *data = note.data.pr_psargs;
294              size_t datalen = sizeof note.data.pr_psargs;
295              err = proc_getprocargs (procserver, pid, &data, &datalen);
296              if (err == 0)
297                {
298                  note.data.pr_argc = argz_count (data, datalen);
299                  argz_stringify (data, datalen, ' ');
300                  if (data != note.data.pr_psargs)
301                    {
302                      memcpy (note.data.pr_psargs, data,
303                              sizeof note.data.pr_psargs);
304                      munmap (data, datalen);
305                    }
306                }
307            }
308            err = WRITE_NOTE (NT_PSTATUS, note);
309          }
310    
311    #if 0
312      note.data.pr_info.si_signo = signo;      note.data.pr_info.si_signo = signo;
313      note.data.pr_info.si_code = sigcode;      note.data.pr_info.si_code = sigcode;
314      note.data.pr_info.si_errno = sigerror;      note.data.pr_info.si_errno = sigerror;
315      err = WRITE_NOTE (NT_PSTATUS, note);  #endif
316    }    }
317    if (err || (corelimit >= 0 && corelimit <= offset))    if (err || (corelimit >= 0 && corelimit <= offset))
318      return err;      return err;
 #endif  
319    
320    /* Now examine all the threads in the task.    /* Now examine all the threads in the task.
321       For each thread we produce one or more notes.  */       For each thread we produce one or more notes.  */

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26