From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25898 invoked by alias); 29 Feb 2008 11:08:38 -0000 Received: (qmail 25239 invoked by uid 22791); 29 Feb 2008 11:08:34 -0000 X-Spam-Status: No, hits=0.4 required=5.0 tests=AWL,BAYES_50,J_CHICKENPOX_33,J_CHICKENPOX_38,J_CHICKENPOX_45,J_CHICKENPOX_54,J_CHICKENPOX_66,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 29 Feb 2008 11:08:06 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m1TB84Hc029956 for ; Fri, 29 Feb 2008 06:08:04 -0500 Received: from pobox-2.corp.redhat.com (pobox-2.corp.redhat.com [10.11.255.15]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m1TB83SZ005560 for ; Fri, 29 Feb 2008 06:08:03 -0500 Received: from localhost.localdomain (vpn-6-10.fab.redhat.com [10.33.6.10]) by pobox-2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m1TB814M020738 for ; Fri, 29 Feb 2008 06:08:02 -0500 Message-ID: <47C7E791.9000908@redhat.com> Date: Fri, 29 Feb 2008 11:08:00 -0000 From: Phil Muldoon User-Agent: Thunderbird 2.0.0.9 (X11/20071115) MIME-Version: 1.0 To: frysk@sourceware.org Subject: Re: [SCM] master: Add --segment= dumping strategy. Delete --stackonly dumping strategy. References: <20080228212550.18079.qmail@sourceware.org> In-Reply-To: <20080228212550.18079.qmail@sourceware.org> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 X-IsSubscribed: yes Mailing-List: contact frysk-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-owner@sourceware.org X-SW-Source: 2008-q1/txt/msg00085.txt.bz2 This commit adds a selective map dumping feature to fcore via the -segments option. So for example. sleep 100 & [1] 7480 fcore -segments=”stack|heap|vdso|($^)” 7480 Will dump the segments that match the program’s: stack, heap, its virtual dynamic shared object (vdso) and any maps without a name (maps not backed with a file). The segment's argument is treated as regex and is run through a Pattern Matcher to match map name. Please note this is Java's version of regex and may differ from the the regex you know and love. See: http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html Specifically the section to how this differs from Perl 5 regex. If people find this useful, we can look in the future to adding other selective criteria. Subsequently I removed the --stackonly option. The default mode of fcore has not changed, and is to emulate kernel map dumping strategy. Regards Phil pmuldoon@sourceware.org wrote: > The branch, master has been updated > via 058aac11987b42390a7a179274227d4735d41f19 (commit) > from 1b5a098d45d2565f472285dde9d990b90c33460a (commit) > > Those revisions listed above that are new to this repository have > not appeared on any other notification email. > > - Log ----------------------------------------------------------------- > commit 058aac11987b42390a7a179274227d4735d41f19 > Author: Phil Muldoon > Date: Thu Feb 28 21:24:56 2008 +0000 > > Add --segment= dumping strategy. Delete --stackonly dumping strategy. > > 2008-02-28 Phil Muldoon > > * fcore.xml: Add --segments option. Delete > --stackonly option. > * fcore.java (addOptions): Delete stack only option. > Add segments option. > > 2008-02-28 Phil Muldoon > > * TestLinuxElfCorefile.java (constructStackOnlyCore): Delete. > (testStackOnlyMap): Delete. > (testRegexSelectedMap): New. > (giveMeABlockedProc): Delete comments and remove unecessary > proc creations. > > * LinuxElfCorefile.java (setStackOnly): Delete. > (buildMap): Add in regex code. Implement selective > > 2008-02-28 Phil Muldoon > > * CoredumpAction.java: Remove stack only > constructor. > > ----------------------------------------------------------------------- > > Summary of changes: > frysk-core/frysk/bindir/ChangeLog | 7 ++ > frysk-core/frysk/bindir/fcore.java | 112 +++++++++++--------- > frysk-core/frysk/bindir/fcore.xml | 4 +- > frysk-core/frysk/isa/corefiles/ChangeLog | 10 ++ > .../frysk/isa/corefiles/LinuxElfCorefile.java | 61 ++++++----- > .../frysk/isa/corefiles/TestLinuxElfCorefile.java | 76 ++++++-------- > frysk-core/frysk/testbed/ChangeLog | 5 + > frysk-core/frysk/testbed/CoredumpAction.java | 17 --- > 8 files changed, 147 insertions(+), 145 deletions(-) > > First 500 lines of diff: > diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog > index c2f4788..2f6f7a1 100644 > --- a/frysk-core/frysk/bindir/ChangeLog > +++ b/frysk-core/frysk/bindir/ChangeLog > @@ -1,3 +1,10 @@ > +2008-02-28 Phil Muldoon > + > + * fcore.xml: Add --segments option. Delete > + --stackonly option. > + * fcore.java (addOptions): Delete stack only option. > + Add segments option. > + > 2008-02-28 Teresa Thomas > > * fdebugrpm.sh: Show error message if fdebuginfo install > diff --git a/frysk-core/frysk/bindir/fcore.java b/frysk-core/frysk/bindir/fcore.java > index a6a2239..dc81c90 100644 > --- a/frysk-core/frysk/bindir/fcore.java > +++ b/frysk-core/frysk/bindir/fcore.java > @@ -54,9 +54,11 @@ import gnu.classpath.tools.getopt.OptionException; > > public class fcore > { > + private static String matchingRegEx = ""; > private static String filename = "core"; > private static boolean writeAllMaps = false; > - private static boolean stackOnly = false; > + > + private static int mapOptionCount = 0; > protected static final Logger logger = Logger.getLogger("frysk"); > > /** > @@ -79,54 +81,55 @@ public class fcore > */ > private static void addOptions (ProcStopUtil fcore) > { > - fcore.addOption(new Option("stackonly", 's', > - " Writes only stack segment, and elides all" > - + " other maps.") > - { > - public void parsed (String mapsValue) throws OptionException { > - try { > - stackOnly = true; > - } catch (IllegalArgumentException e) { > - throw new OptionException( "Invalid maps parameter " > - + mapsValue); > - } > - > - } > - }); > > fcore.addOption(new Option( "allmaps", 'a', > " Writes all readable maps. Does not elide" > + " or omit any readable map. Caution: could" > + " take considerable amount of time to" > + " construct core file.") > - { > - public void parsed (String mapsValue) throws OptionException { > - try { > - writeAllMaps = true; > - stackOnly = false; > - } catch (IllegalArgumentException e) { > - throw new OptionException("Invalid maps parameter " + mapsValue); > + { > + public void parsed (String mapsValue) throws OptionException { > + try { > + writeAllMaps = true; > + mapOptionCount++; > + } catch (IllegalArgumentException e) { > + throw new OptionException("Invalid maps parameter " + mapsValue); > + } > + > } > - > - } > - }); > + }); > + > + fcore.addOption(new Option("segments", 's', > + "Define what segments to include via regex.", > + "RegEx") { > + public void parsed(String regEx) throws OptionException { > + try { > + mapOptionCount++; > + matchingRegEx = regEx; > + } catch (IllegalArgumentException e) { > + throw new OptionException("Invalid match parameter " > + + matchingRegEx); > + } > + } > + }); > + > + > > fcore.addOption(new Option( "outputfile", 'o', > " Sets the name (not extension) of the core" > + " file. Default is core.{pid}. The extension" > - + " will always be the pid.", "") > - { > - public void parsed (String filenameValue) throws OptionException > + + " will always be the pid.", "") > { > - try { > + public void parsed (String filenameValue) throws OptionException { > + try { > filename = filenameValue; > + } > + catch (IllegalArgumentException e) { > + throw new OptionException( "Invalid output filename: " > + + filenameValue); > + } > } > - catch (IllegalArgumentException e) { > - throw new OptionException( "Invalid output filename: " > - + filenameValue); > - } > - } > - }); > + }); > } > > /** > @@ -136,24 +139,31 @@ public class fcore > { > public void executeLive(Proc proc) { > > - Task[] tasks = (Task[]) proc.getTasks().toArray > - (new Task[proc.getTasks().size()]); > - LinuxElfCorefile coreFile = LinuxElfCorefileFactory. > - getCorefile(proc, tasks); > + > > - if (coreFile == null) { > - System.err.println ( "Architecture not supported or " > - + "LinuxElfCorefileFactory returned null"); > - } else { > - coreFile.setName(filename); > - coreFile.setWriteAllMaps(writeAllMaps); > - coreFile.setStackOnly(stackOnly); > - > - try { > - coreFile.constructCorefile(); > - } catch (RuntimeException e) { > + if (mapOptionCount > 1) > + System.err.println("Please either speciy -stackonly,"+ > + " -allmaps, or -match for map writing."); > + else { > + Task[] tasks = (Task[]) proc.getTasks().toArray > + (new Task[proc.getTasks().size()]); > + LinuxElfCorefile coreFile = LinuxElfCorefileFactory. > + getCorefile(proc, tasks); > + > + if (coreFile == null) { > System.err.println ( "Architecture not supported or " > - + "LinuxElfCorefileFactory returned null"); > + + "LinuxElfCorefileFactory returned null"); > + } else { > + coreFile.setName(filename); > + coreFile.setWriteAllMaps(writeAllMaps); > + coreFile.setPatternMatch(matchingRegEx); > + > + try { > + coreFile.constructCorefile(); > + } catch (RuntimeException e) { > + System.err.println ( "Architecture not supported or " > + + "LinuxElfCorefileFactory returned null"); > + } > } > } > } > diff --git a/frysk-core/frysk/bindir/fcore.xml b/frysk-core/frysk/bindir/fcore.xml > index 407db94..0f63fad 100644 > --- a/frysk-core/frysk/bindir/fcore.xml > +++ b/frysk-core/frysk/bindir/fcore.xml > @@ -107,9 +107,9 @@ > > > > - > + > > - Writes only the stack segment. Elide all other segments. > + Writes only the segments that match the regex specified. Elide all other segments. > > > > diff --git a/frysk-core/frysk/isa/corefiles/ChangeLog b/frysk-core/frysk/isa/corefiles/ChangeLog > index 0cd6d0f..790d374 100644 > --- a/frysk-core/frysk/isa/corefiles/ChangeLog > +++ b/frysk-core/frysk/isa/corefiles/ChangeLog > @@ -1,5 +1,15 @@ > 2008-02-28 Phil Muldoon > > + * TestLinuxElfCorefile.java (constructStackOnlyCore): Delete. > + (testStackOnlyMap): Delete. > + (testRegexSelectedMap): New. > + (giveMeABlockedProc): Delete comments and remove unecessary > + proc creations. > + > + * LinuxElfCorefile.java (setStackOnly): Delete. > + (buildMap): Add in regex code. Implement selective > + segment code. > + > * TestLinuxElfCorefile.java: Move and rename from > frysk/testbed/TestCoredumpAction.java. > > diff --git a/frysk-core/frysk/isa/corefiles/LinuxElfCorefile.java b/frysk-core/frysk/isa/corefiles/LinuxElfCorefile.java > index 9999d52..dd6c686 100644 > --- a/frysk-core/frysk/isa/corefiles/LinuxElfCorefile.java > +++ b/frysk-core/frysk/isa/corefiles/LinuxElfCorefile.java > @@ -57,12 +57,15 @@ import frysk.proc.Task; > import frysk.sys.StatelessFile; > import frysk.sys.proc.MapsBuilder; > import java.io.File; > +import java.util.regex.Pattern; > +import java.util.regex.Matcher; > > public abstract class LinuxElfCorefile { > > long elfSectionOffset = 0; > > String coreName = "core"; > + String regex = ""; > > Proc process = null; > > @@ -70,7 +73,7 @@ public abstract class LinuxElfCorefile { > > boolean writeAllMaps = false; > > - boolean stackOnly = true; > + boolean regexMatch = false; > > Elf linuxElfCorefileImage = null; > > @@ -101,19 +104,11 @@ public abstract class LinuxElfCorefile { > } > > > - /** > - * > - * Defines whether to write only the stack segment and elide all others. > - * > - * @param maps - True if attempt to write all maps, false to follow > - * map writing convention. > - * > - */ > - > - public void setStackOnly(boolean stackOnly) { > - this.stackOnly = stackOnly; > + public void setPatternMatch(String regex) { > + this.regex = regex; > + if (!this.regex.equals("")) > + this.regexMatch = true; > } > - > /** > * > * Set the name of the corefile to be constructed. This should be > @@ -466,10 +461,13 @@ public abstract class LinuxElfCorefile { > > Dwfl dwfl = null; > Elf elf; > + Pattern pattern; > > CoreMapsBuilder() > { > dwfl = DwflCache.getDwfl(process.getMainTask()); > + if (regexMatch) > + pattern = Pattern.compile(regex); > } > > public void buildBuffer(final byte[] maps) { > @@ -495,9 +493,19 @@ public abstract class LinuxElfCorefile { > pathnameLength); > String sfilename = new String(filename); > > + > if (writeAllMaps) { > writeMap = true; > + } > + > + > + if (regexMatch) { > + Matcher match = pattern.matcher(sfilename); > + if (match.find()) { > + writeMap = true; > + } > } else { > + > // Should the map be written? > if (inode == 0) > writeMap = true; > @@ -511,25 +519,18 @@ public abstract class LinuxElfCorefile { > writeMap = true; > if (shared) > writeMap = true; > - } > - > - if (!writeMap) { > - DwflModule module = null; > - if (dwfl != null) { > - module = dwfl.getModule(addressLow); > - if (module != null) > - if (module.getElf() == null) > - writeMap = true; > - } > - } > + > > - if (stackOnly) { > - if (sfilename.equals("[stack]") || sfilename.equals("[vdso]")) > - writeMap = true; > - else > - writeMap = false; > + if (!writeMap) { > + DwflModule module = null; > + if (dwfl != null) { > + module = dwfl.getModule(addressLow); > + if (module != null) > + if (module.getElf() == null) > + writeMap = true; > + } > + } > } > - > > // Get empty progam segment header corresponding to this entry. > // PT_NOTE's program header entry takes the index: 0. So we should > diff --git a/frysk-core/frysk/isa/corefiles/TestLinuxElfCorefile.java b/frysk-core/frysk/isa/corefiles/TestLinuxElfCorefile.java > index 247cb82..5b93010 100644 > --- a/frysk-core/frysk/isa/corefiles/TestLinuxElfCorefile.java > +++ b/frysk-core/frysk/isa/corefiles/TestLinuxElfCorefile.java > @@ -57,13 +57,15 @@ import frysk.proc.Auxv; > import frysk.proc.Manager; > import frysk.proc.MemoryMap; > import frysk.proc.Proc; > +import frysk.proc.Task; > import frysk.proc.ProcBlockAction; > import frysk.proc.dead.LinuxCoreFactory; > import frysk.testbed.DaemonBlockedAtEntry; > import frysk.testbed.SlaveOffspring; > import frysk.testbed.TestLib; > import frysk.testbed.CoredumpAction; > - > +import frysk.isa.corefiles.LinuxElfCorefile; > + import frysk.isa.corefiles.LinuxElfCorefileFactory; > public class TestLinuxElfCorefile > extends TestLib > { > @@ -223,20 +225,22 @@ public class TestLinuxElfCorefile > } > > > - public void testStackOnlyMap () > + public void testRegexSelectedMap () > { > - Proc ackProc = giveMeAProc(); > - MemoryMap stackMap = null; > + Proc ackProc = giveMeABlockedProc(); > + MemoryMap stackMap = null, vdsoMap = null; > MemoryMap coreMap = null; > + > // Create a corefile from process > - String coreFileName = constructStackOnlyCore(ackProc); > - File testCore = new File(coreFileName); > - > - assertTrue("Checking core file " + coreFileName + " exists.", > - testCore.exists()); > + LinuxElfCorefile core = > + LinuxElfCorefileFactory.getCorefile(ackProc, > + (Task[])ackProc.getTasks().toArray(new Task[0])); > + > + core.setPatternMatch("stack|vdso"); > + core.constructCorefile(); > > // Model the corefile, and get the Process. > - Proc coreProc = LinuxCoreFactory.createProc(testCore, > + Proc coreProc = LinuxCoreFactory.createProc(new File(core.getConstructedFileName()), > new File(ackProc.getExe())); > assertNotNull("Checking core file process", coreProc); > > @@ -244,18 +248,28 @@ public class TestLinuxElfCorefile > MemoryMap[] liveMaps = ackProc.getMaps(); > > for(int i=0; i - if (liveMaps[i].name.equals("[stack]")) { > + System.out.println(liveMaps[i].name); > + if (liveMaps[i].name.equals("[stack]")) > stackMap = liveMaps[i]; > - break; > - } > + if (liveMaps[i].name.equals("[vdso]")) > + vdsoMap = liveMaps[i]; > } > + > + > + assertNotNull("Live VDSO segment not null", vdsoMap); > + assertNotNull("Live STACK segment not null", stackMap); > > - assertNotNull("Cannot find stack in live process", stackMap); > - int mapNo = findLowAddress(stackMap.addressLow, coreMaps); > + int mapNo=0; > + > + mapNo = findLowAddress(stackMap.addressLow, coreMaps); > coreMap = coreMaps[mapNo]; > assertNotNull("Cannot find stack in core process", coreMap); > > - Elf testElf = new Elf(testCore, ElfCommand.ELF_C_READ); > + mapNo = findLowAddress(vdsoMap.addressLow, coreMaps); > + coreMap = coreMaps[mapNo]; > + assertNotNull("Cannot find vdso in core process", coreMap); > + > + Elf testElf = new Elf(new File(core.getConstructedFileName()), ElfCommand.ELF_C_READ); > ElfEHeader header = testElf.getEHeader(); > int count = header.phnum; > int segCount = 0; > @@ -269,7 +283,7 @@ public class TestLinuxElfCorefile > } > testElf.close(); > > - assertEquals("stack only corefile segCount +stack +notes != 2",segCount,2); > + assertEquals("stack only corefile segCount +stack +vdso +notes != 3",3,segCount); > } > > > @@ -297,30 +311,6 @@ public class TestLinuxElfCorefile > return coreDump.getConstructedFileName(); > } > > - /** > - * Given a Proc object, generate a core file from that given proc. > - * > - * @param ackProc - proc object to generate core from. > - * @return - name of constructed core file. > - */ > - private String constructStackOnlyCore (final Proc ackProc) > - { > - > - CoredumpAction coreDump = null; > - coreDump = new CoredumpAction(ackProc, "core", > - new Event() { > - public void execute () { > - ackProc. > - requestAbandonAndRunEvent( > - new RequestStopEvent( > - Manager.eventLoop)); > - } > - }, false, true); > - > - new ProcBlockAction(ackProc, coreDump); > - assertRunUntilStop("Running event loop for core file"); > - return coreDump.getConstructedFileName(); > - } > > > /** > @@ -343,11 +333,7 @@ public class TestLinuxElfCorefile > { > String[] nocmds = {}; > DaemonBlockedAtEntry ackProc = new DaemonBlockedAtEntry(nocmds); > - //SlaveOffspring ackProc = SlaveOffspring.createDaemon(); > assertNotNull(ackProc); > - ackProc.getMainTask().getProc(); > - //Proc proc = ackProc.assertFindProcAndTasks(); > - //assertNotNull(proc); > return ackProc.getMainTask().getProc(); > } > > diff --git a/frysk-core/frysk/testbed/ChangeLog b/frysk-core/frysk/testbed/ChangeLog > index 98d033a..a15fce6 100644 > --- a/frysk-core/frysk/testbed/ChangeLog > +++ b/frysk-core/frysk/testbed/ChangeLog > @@ -1,3 +1,8 @@ > +2008-02-28 Phil Muldoon > + > + * CoredumpAction.java: Remove stack only > + constructor. > + > 2008-02-28 Teresa Thomas > > * CorefileFactory.java: Remove redundant import. > diff --git a/frysk-core/frysk/testbed/CoredumpAction.java b/frysk-core/frysk/testbed/CoredumpAction.java > index 6a26ca5..36683a7 100644 > --- a/frysk-core/frysk/testbed/CoredumpAction.java > +++ b/frysk-core/frysk/testbed/CoredumpAction.java > @@ -72,8 +72,6 @@ public class CoredumpAction implements ProcObserver.ProcAction { > > private boolean writeAllMaps = false; > > - private boolean stackOnly = false; > - > private LinuxElfCorefile coreFile; > > int taskArraySize = 1; > @@ -101,20 +99,6 @@ public class CoredumpAction implements ProcObserver.ProcAction { > Manager.eventLoop.add(new InterruptEvent(proc)); > } > > - /** > > > hooks/post-receive > -- > frysk system monitor/debugger >