Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F97664240
D30369.id89560.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D30369.id89560.diff
View Options
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -106,8 +106,6 @@
CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"");
-#define CORE_BUF_SIZE (16 * 1024)
-
int __elfN(fallback_brand) = -1;
SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO,
fallback_brand, CTLFLAG_RWTUN, &__elfN(fallback_brand), 0,
@@ -1454,23 +1452,11 @@
TAILQ_HEAD(note_info_list, note_info);
-/* Coredump output parameters. */
-struct coredump_params {
- off_t offset;
- struct ucred *active_cred;
- struct ucred *file_cred;
- struct thread *td;
- struct vnode *vp;
- struct compressor *comp;
-};
-
extern int compress_user_cores;
extern int compress_user_cores_level;
static void cb_put_phdr(vm_map_entry_t, void *);
static void cb_size_segment(vm_map_entry_t, void *);
-static int core_write(struct coredump_params *, const void *, size_t, off_t,
- enum uio_seg, size_t *);
static void each_dumpable_segment(struct thread *, segment_callback, void *,
int);
static int __elfN(corehdr)(struct coredump_params *, int, void *, size_t,
@@ -1480,7 +1466,6 @@
static void __elfN(puthdr)(struct thread *, void *, size_t, int, size_t, int);
static void __elfN(putnote)(struct note_info *, struct sbuf *);
static size_t register_note(struct note_info_list *, int, outfunc_t, void *);
-static int sbuf_drain_core_output(void *, const char *, int);
static void __elfN(note_fpregset)(void *, struct sbuf *, size_t *);
static void __elfN(note_prpsinfo)(void *, struct sbuf *, size_t *);
@@ -1498,34 +1483,6 @@
static void note_procstat_umask(void *, struct sbuf *, size_t *);
static void note_procstat_vmmap(void *, struct sbuf *, size_t *);
-/*
- * Write out a core segment to the compression stream.
- */
-static int
-compress_chunk(struct coredump_params *p, char *base, char *buf, u_int len)
-{
- u_int chunk_len;
- int error;
-
- while (len > 0) {
- chunk_len = MIN(len, CORE_BUF_SIZE);
-
- /*
- * We can get EFAULT error here.
- * In that case zero out the current chunk of the segment.
- */
- error = copyin(base, buf, chunk_len);
- if (error != 0)
- bzero(buf, chunk_len);
- error = compressor_write(p->comp, buf, chunk_len);
- if (error != 0)
- break;
- base += chunk_len;
- len -= chunk_len;
- }
- return (error);
-}
-
static int
core_compressed_write(void *base, size_t len, off_t offset, void *arg)
{
@@ -1534,123 +1491,6 @@
UIO_SYSSPACE, NULL));
}
-static int
-core_write(struct coredump_params *p, const void *base, size_t len,
- off_t offset, enum uio_seg seg, size_t *resid)
-{
-
- return (vn_rdwr_inchunks(UIO_WRITE, p->vp, __DECONST(void *, base),
- len, offset, seg, IO_UNIT | IO_DIRECT | IO_RANGELOCKED,
- p->active_cred, p->file_cred, resid, p->td));
-}
-
-static int
-core_output(char *base, size_t len, off_t offset, struct coredump_params *p,
- void *tmpbuf)
-{
- vm_map_t map;
- struct mount *mp;
- size_t resid, runlen;
- int error;
- bool success;
-
- KASSERT((uintptr_t)base % PAGE_SIZE == 0,
- ("%s: user address %p is not page-aligned", __func__, base));
-
- if (p->comp != NULL)
- return (compress_chunk(p, base, tmpbuf, len));
-
- map = &p->td->td_proc->p_vmspace->vm_map;
- for (; len > 0; base += runlen, offset += runlen, len -= runlen) {
- /*
- * Attempt to page in all virtual pages in the range. If a
- * virtual page is not backed by the pager, it is represented as
- * a hole in the file. This can occur with zero-filled
- * anonymous memory or truncated files, for example.
- */
- for (runlen = 0; runlen < len; runlen += PAGE_SIZE) {
- error = vm_fault(map, (uintptr_t)base + runlen,
- VM_PROT_READ, VM_FAULT_NOFILL, NULL);
- if (runlen == 0)
- success = error == KERN_SUCCESS;
- else if ((error == KERN_SUCCESS) != success)
- break;
- }
-
- if (success) {
- error = core_write(p, base, runlen, offset,
- UIO_USERSPACE, &resid);
- if (error != 0) {
- if (error != EFAULT)
- break;
-
- /*
- * EFAULT may be returned if the user mapping
- * could not be accessed, e.g., because a mapped
- * file has been truncated. Skip the page if no
- * progress was made, to protect against a
- * hypothetical scenario where vm_fault() was
- * successful but core_write() returns EFAULT
- * anyway.
- */
- runlen -= resid;
- if (runlen == 0) {
- success = false;
- runlen = PAGE_SIZE;
- }
- }
- }
- if (!success) {
- error = vn_start_write(p->vp, &mp, V_WAIT);
- if (error != 0)
- break;
- vn_lock(p->vp, LK_EXCLUSIVE | LK_RETRY);
- error = vn_truncate_locked(p->vp, offset + runlen,
- false, p->td->td_ucred);
- VOP_UNLOCK(p->vp);
- vn_finished_write(mp);
- if (error != 0)
- break;
- }
- }
- return (error);
-}
-
-/*
- * Drain into a core file.
- */
-static int
-sbuf_drain_core_output(void *arg, const char *data, int len)
-{
- struct coredump_params *p;
- int error, locked;
-
- p = (struct coredump_params *)arg;
-
- /*
- * Some kern_proc out routines that print to this sbuf may
- * call us with the process lock held. Draining with the
- * non-sleepable lock held is unsafe. The lock is needed for
- * those routines when dumping a live process. In our case we
- * can safely release the lock before draining and acquire
- * again after.
- */
- locked = PROC_LOCKED(p->td->td_proc);
- if (locked)
- PROC_UNLOCK(p->td->td_proc);
- if (p->comp != NULL)
- error = compressor_write(p->comp, __DECONST(char *, data), len);
- else
- error = core_write(p, __DECONST(void *, data), len, p->offset,
- UIO_SYSSPACE, NULL);
- if (locked)
- PROC_LOCK(p->td->td_proc);
- if (error != 0)
- return (-error);
- p->offset += len;
- return (len);
-}
-
int
__elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
{
Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -39,6 +39,7 @@
#include <sys/acct.h>
#include <sys/asan.h>
#include <sys/capsicum.h>
+#include <sys/compressor.h>
#include <sys/eventhandler.h>
#include <sys/exec.h>
#include <sys/fcntl.h>
@@ -1867,3 +1868,149 @@
execsw = newexecsw;
return (0);
}
+
+/*
+ * Write out a core segment to the compression stream.
+ */
+static int
+compress_chunk(struct coredump_params *p, char *base, char *buf, u_int len)
+{
+ u_int chunk_len;
+ int error;
+
+ while (len > 0) {
+ chunk_len = MIN(len, CORE_BUF_SIZE);
+
+ /*
+ * We can get EFAULT error here.
+ * In that case zero out the current chunk of the segment.
+ */
+ error = copyin(base, buf, chunk_len);
+ if (error != 0)
+ bzero(buf, chunk_len);
+ error = compressor_write(p->comp, buf, chunk_len);
+ if (error != 0)
+ break;
+ base += chunk_len;
+ len -= chunk_len;
+ }
+ return (error);
+}
+
+int
+core_write(struct coredump_params *p, const void *base, size_t len,
+ off_t offset, enum uio_seg seg, size_t *resid)
+{
+
+ return (vn_rdwr_inchunks(UIO_WRITE, p->vp, __DECONST(void *, base),
+ len, offset, seg, IO_UNIT | IO_DIRECT | IO_RANGELOCKED,
+ p->active_cred, p->file_cred, resid, p->td));
+}
+
+int
+core_output(char *base, size_t len, off_t offset, struct coredump_params *p,
+ void *tmpbuf)
+{
+ vm_map_t map;
+ struct mount *mp;
+ size_t resid, runlen;
+ int error;
+ bool success;
+
+ KASSERT((uintptr_t)base % PAGE_SIZE == 0,
+ ("%s: user address %p is not page-aligned", __func__, base));
+
+ if (p->comp != NULL)
+ return (compress_chunk(p, base, tmpbuf, len));
+
+ map = &p->td->td_proc->p_vmspace->vm_map;
+ for (; len > 0; base += runlen, offset += runlen, len -= runlen) {
+ /*
+ * Attempt to page in all virtual pages in the range. If a
+ * virtual page is not backed by the pager, it is represented as
+ * a hole in the file. This can occur with zero-filled
+ * anonymous memory or truncated files, for example.
+ */
+ for (runlen = 0; runlen < len; runlen += PAGE_SIZE) {
+ error = vm_fault(map, (uintptr_t)base + runlen,
+ VM_PROT_READ, VM_FAULT_NOFILL, NULL);
+ if (runlen == 0)
+ success = error == KERN_SUCCESS;
+ else if ((error == KERN_SUCCESS) != success)
+ break;
+ }
+
+ if (success) {
+ error = core_write(p, base, runlen, offset,
+ UIO_USERSPACE, &resid);
+ if (error != 0) {
+ if (error != EFAULT)
+ break;
+
+ /*
+ * EFAULT may be returned if the user mapping
+ * could not be accessed, e.g., because a mapped
+ * file has been truncated. Skip the page if no
+ * progress was made, to protect against a
+ * hypothetical scenario where vm_fault() was
+ * successful but core_write() returns EFAULT
+ * anyway.
+ */
+ runlen -= resid;
+ if (runlen == 0) {
+ success = false;
+ runlen = PAGE_SIZE;
+ }
+ }
+ }
+ if (!success) {
+ error = vn_start_write(p->vp, &mp, V_WAIT);
+ if (error != 0)
+ break;
+ vn_lock(p->vp, LK_EXCLUSIVE | LK_RETRY);
+ error = vn_truncate_locked(p->vp, offset + runlen,
+ false, p->td->td_ucred);
+ VOP_UNLOCK(p->vp);
+ vn_finished_write(mp);
+ if (error != 0)
+ break;
+ }
+ }
+ return (error);
+}
+
+/*
+ * Drain into a core file.
+ */
+int
+sbuf_drain_core_output(void *arg, const char *data, int len)
+{
+ struct coredump_params *p;
+ int error, locked;
+
+ p = (struct coredump_params *)arg;
+
+ /*
+ * Some kern_proc out routines that print to this sbuf may
+ * call us with the process lock held. Draining with the
+ * non-sleepable lock held is unsafe. The lock is needed for
+ * those routines when dumping a live process. In our case we
+ * can safely release the lock before draining and acquire
+ * again after.
+ */
+ locked = PROC_LOCKED(p->td->td_proc);
+ if (locked)
+ PROC_UNLOCK(p->td->td_proc);
+ if (p->comp != NULL)
+ error = compressor_write(p->comp, __DECONST(char *, data), len);
+ else
+ error = core_write(p, __DECONST(void *, data), len, p->offset,
+ UIO_SYSSPACE, NULL);
+ if (locked)
+ PROC_LOCK(p->td->td_proc);
+ if (error != 0)
+ return (-error);
+ p->offset += len;
+ return (len);
+}
+
Index: sys/sys/exec.h
===================================================================
--- sys/sys/exec.h
+++ sys/sys/exec.h
@@ -60,6 +60,16 @@
unsigned int ps_nenvstr; /* the number of environment strings */
};
+/* Coredump output parameters. */
+struct coredump_params {
+ off_t offset;
+ struct ucred *active_cred;
+ struct ucred *file_cred;
+ struct thread *td;
+ struct vnode *vp;
+ struct compressor *comp;
+};
+
struct image_params;
struct execsw {
@@ -84,6 +94,15 @@
int exec_register(const struct execsw *);
int exec_unregister(const struct execsw *);
+enum uio_seg;
+
+#define CORE_BUF_SIZE (16 * 1024)
+
+int core_write(struct coredump_params *, const void *, size_t, off_t,
+ enum uio_seg, size_t *);
+int core_output(char *, size_t, off_t, struct coredump_params *, void *);
+int sbuf_drain_core_output(void *, const char *, int);
+
extern int coredump_pack_fileinfo;
extern int coredump_pack_vmmapinfo;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 1, 4:11 PM (16 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13262686
Default Alt Text
D30369.id89560.diff (10 KB)
Attached To
Mode
D30369: Refactor core dumping code a bit
Attached
Detach File
Event Timeline
Log In to Comment