From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7566 invoked by alias); 20 May 2008 16:59:57 -0000 Received: (qmail 7531 invoked by uid 367); 20 May 2008 16:59:56 -0000 Date: Tue, 20 May 2008 16:59:00 -0000 Message-ID: <20080520165956.7516.qmail@sourceware.org> From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Work-around changed elfutils behavior; can open scripts. X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 131f1576b9fea62702a2a776e569b444cd7a0630 X-Git-Newrev: 1f4adac698d83a3e1f35b2272afc3a0dd34cc956 Mailing-List: contact frysk-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-cvs-owner@sourceware.org Reply-To: frysk@sourceware.org X-SW-Source: 2008-q2/txt/msg00253.txt.bz2 The branch, master has been updated via 1f4adac698d83a3e1f35b2272afc3a0dd34cc956 (commit) via 026114e80a97051bd390d162b9b12f8dafd38956 (commit) via 40454950a61eeefcb332fa9c479012b4f5cdaf8a (commit) via 4bb22af8c8fe923b9894eaf784132de6fcd0577f (commit) from 131f1576b9fea62702a2a776e569b444cd7a0630 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 1f4adac698d83a3e1f35b2272afc3a0dd34cc956 Author: Andrew Cagney Date: Tue May 20 12:58:32 2008 -0400 Work-around changed elfutils behavior; can open scripts. frysk-core/frysk/bindir/ChangeLog 2008-05-20 Andrew Cagney * TestFexe.java (testExeOfScript()): New. frysk-core/frysk/proc/dead/ChangeLog 2008-05-20 Andrew Cagney * LinuxExeFactory.java: Add more logging. frysk-core/frysk/util/ChangeLog 2008-05-20 Andrew Cagney * CommandlineParser.java (isCoreFile(String)) (isExeFile(String)): Catch exceptions from Elf.getEHeader. commit 026114e80a97051bd390d162b9b12f8dafd38956 Author: Andrew Cagney Date: Tue May 20 11:41:54 2008 -0400 Implement jni/Stat.cxx. frysk-sys/frysk/sys/proc/ChangeLog 2008-05-20 Andrew Cagney * jni/Stat.cxx: Implement. commit 40454950a61eeefcb332fa9c479012b4f5cdaf8a Author: Andrew Cagney Date: Tue May 20 10:19:18 2008 -0400 Implement jni/MapsBuilder. frysk-sys/frysk/sys/proc/ChangeLog 2008-05-20 Andrew Cagney * jni/MapsBuilder.cxx: Implement. frysk-sys/jnixx/ChangeLog 2008-05-20 Andrew Cagney * scan.hxx: New. * scan.cxx: New. commit 4bb22af8c8fe923b9894eaf784132de6fcd0577f Author: Andrew Cagney Date: Tue May 20 09:37:10 2008 -0400 Implement jni/Exe. frysk-sys/frysk/sys/proc/ChangeLog 2008-05-20 Andrew Cagney * jni/Exe.cxx: implement. ----------------------------------------------------------------------- Summary of changes: frysk-core/frysk/bindir/ChangeLog | 4 + frysk-core/frysk/bindir/TestFexe.java | 11 ++ frysk-core/frysk/proc/dead/ChangeLog | 4 + frysk-core/frysk/proc/dead/LinuxExeFactory.java | 5 +- frysk-core/frysk/util/ChangeLog | 5 + frysk-core/frysk/util/CommandlineParser.java | 32 ++++-- frysk-sys/frysk/sys/proc/ChangeLog | 6 + frysk-sys/frysk/sys/proc/jni/Exe.cxx | 36 ++++++- frysk-sys/frysk/sys/proc/jni/MapsBuilder.cxx | 89 ++++++++++++++++- frysk-sys/frysk/sys/proc/jni/Stat.cxx | 111 +++++++++++++++++++- frysk-sys/jnixx/ChangeLog | 3 + .../{frysk/sys/proc/jni/Exe.cxx => jnixx/scan.cxx} | 41 +++++++- .../{frysk/sys/proc/jni/Exe.cxx => jnixx/scan.hxx} | 14 ++- 13 files changed, 342 insertions(+), 19 deletions(-) copy frysk-sys/{frysk/sys/proc/jni/Exe.cxx => jnixx/scan.cxx} (71%) copy frysk-sys/{frysk/sys/proc/jni/Exe.cxx => jnixx/scan.hxx} (84%) First 500 lines of diff: diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog index fe9a144..c9627bb 100644 --- a/frysk-core/frysk/bindir/ChangeLog +++ b/frysk-core/frysk/bindir/ChangeLog @@ -1,3 +1,7 @@ +2008-05-20 Andrew Cagney + + * TestFexe.java (testExeOfScript()): New. + 2008-05-15 Tim Moore * fstep.java (DummyDisassembler, startTracingTask): Use new diff --git a/frysk-core/frysk/bindir/TestFexe.java b/frysk-core/frysk/bindir/TestFexe.java index a1eeb6b..6f79c80 100644 --- a/frysk-core/frysk/bindir/TestFexe.java +++ b/frysk-core/frysk/bindir/TestFexe.java @@ -76,4 +76,15 @@ public class TestFexe extends TestLib { }); e.expect("/bin/ls" + "\r\n"); } + + public void testExeOfScript() { + TearDownExpect e = new TearDownExpect(new String[] { + "/bin/bash", "-c", + Prefix.binFile("fexe").getPath() + + " " + + Prefix.binFile("fdebugrpm") + }); + e.expect("/bin/bash" + "\r\n"); + } + } diff --git a/frysk-core/frysk/proc/dead/ChangeLog b/frysk-core/frysk/proc/dead/ChangeLog index 79d6c6b..2f5d793 100644 --- a/frysk-core/frysk/proc/dead/ChangeLog +++ b/frysk-core/frysk/proc/dead/ChangeLog @@ -1,3 +1,7 @@ +2008-05-20 Andrew Cagney + + * LinuxExeFactory.java: Add more logging. + 2008-04-18 Stan Cox * LinuxCoreFactory.java (createProc): Add SysRoot to signature. diff --git a/frysk-core/frysk/proc/dead/LinuxExeFactory.java b/frysk-core/frysk/proc/dead/LinuxExeFactory.java index 2e2c55b..be6248f 100644 --- a/frysk-core/frysk/proc/dead/LinuxExeFactory.java +++ b/frysk-core/frysk/proc/dead/LinuxExeFactory.java @@ -118,6 +118,7 @@ public class LinuxExeFactory { } public static DeadProc createProc(File exeFile, String[] args) { + fine.log("createProc exe", exeFile, "args", args); DeadProc proc; proc = createElfProc(exeFile, args); if (proc != null) @@ -129,16 +130,16 @@ public class LinuxExeFactory { } public static DeadProc createProc(String[] args) { + fine.log("createProc args", args); SysRoot sysRoot = new SysRoot(SysRootCache.getSysRoot(args[0])); File exe = sysRoot.getPathViaSysRoot(args[0]).getFile(); - fine.log("createProc exe", exe); return createProc(exe, args); } public static DeadProc createProc(String[] args, String sysroot) { + fine.log("createProc args", args, "sysroot", sysroot); SysRoot sysRoot = new SysRoot(sysroot); File exe = sysRoot.getPathViaSysRoot(args[0]).getFile(); - fine.log("createProc exe", exe); return createProc(exe, args); } } diff --git a/frysk-core/frysk/util/ChangeLog b/frysk-core/frysk/util/ChangeLog index f269de8..bf95319 100644 --- a/frysk-core/frysk/util/ChangeLog +++ b/frysk-core/frysk/util/ChangeLog @@ -1,3 +1,8 @@ +2008-05-20 Andrew Cagney + + * CommandlineParser.java (isCoreFile(String)) + (isExeFile(String)): Catch exceptions from Elf.getEHeader. + 2008-05-13 Petr Machata * ArchFormatter.java (toHexString(int, long)): New method. diff --git a/frysk-core/frysk/util/CommandlineParser.java b/frysk-core/frysk/util/CommandlineParser.java index 837e39e..d2887f8 100644 --- a/frysk-core/frysk/util/CommandlineParser.java +++ b/frysk-core/frysk/util/CommandlineParser.java @@ -43,6 +43,7 @@ import frysk.config.FryskVersion; import java.io.File; import java.util.LinkedList; import lib.dwfl.Elf; +import lib.dwfl.ElfException; import lib.dwfl.ElfCommand; import lib.dwfl.ElfEHeader; import gnu.classpath.tools.getopt.Option; @@ -180,6 +181,7 @@ public abstract class CommandlineParser { return result; // Check if arguments are all pids. + fine.log("checking for pid"); try { Proc[] procs = new Proc[result.length]; procs[0] = Util.getProcFromPid(Integer.parseInt(result[0])); @@ -198,6 +200,7 @@ public abstract class CommandlineParser { } // Check if arguments are all core file/ exe file pairs.. + fine.log("checking for corefiles"); if (isCoreFile(result[0])) { LinkedList coreList = new LinkedList(); for (int file = 0; file < result.length; /*see below*/) { @@ -232,6 +235,7 @@ public abstract class CommandlineParser { } // If not above, then this is an executable command. + fine.log("checking for executable"); Proc command; if (explicitExe != null) command = LinuxExeFactory.createProc(new File(explicitExe), result); @@ -249,29 +253,35 @@ public abstract class CommandlineParser { * @return if fileName is a corefile returns true, otherwise false. */ private boolean isCoreFile(String fileName) { - Elf elf; + fine.log("isCoreFile file", fileName); + Elf elf = null; try { elf = new Elf(new File(fileName), ElfCommand.ELF_C_READ); - } catch (Exception e) { + boolean ret = elf.getEHeader().type == ElfEHeader.PHEADER_ET_CORE; + elf.close(); + return ret; + } catch (ElfException e) { + if (elf != null) { + elf.close(); + } return false; } - - boolean ret = elf.getEHeader().type == ElfEHeader.PHEADER_ET_CORE; - elf.close(); - return ret; } private boolean isExeFile(String fileName) { - Elf elf; + Elf elf = null; try { elf = new Elf(new File(fileName), ElfCommand.ELF_C_READ); - } catch (Exception e) { + boolean ret = elf.getEHeader().type == ElfEHeader.PHEADER_ET_EXEC; + elf.close(); + return ret; + } catch (ElfException e) { + if (elf != null) { + elf.close(); + } return false; } - boolean ret = elf.getEHeader().type == ElfEHeader.PHEADER_ET_EXEC; - elf.close(); - return ret; } diff --git a/frysk-sys/frysk/sys/proc/ChangeLog b/frysk-sys/frysk/sys/proc/ChangeLog index 0bf727e..dc6accf 100644 --- a/frysk-sys/frysk/sys/proc/ChangeLog +++ b/frysk-sys/frysk/sys/proc/ChangeLog @@ -1,5 +1,11 @@ 2008-05-20 Andrew Cagney + * jni/Stat.cxx: Implement. + + * jni/MapsBuilder.cxx: Implement. + + * jni/Exe.cxx: implement. + * jni/CmdLineBuilder.cxx: Implement. * CmdLineBuilder.java (buildBuffer(byte[])): Delete. * TestCmdLine.java: Update. diff --git a/frysk-sys/frysk/sys/proc/jni/Exe.cxx b/frysk-sys/frysk/sys/proc/jni/Exe.cxx index b358932..12745a8 100644 --- a/frysk-sys/frysk/sys/proc/jni/Exe.cxx +++ b/frysk-sys/frysk/sys/proc/jni/Exe.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2006, 2008, Red Hat Inc. // // FRYSK is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by @@ -37,4 +37,38 @@ // version and license this file solely under the GPL without // exception. +#include +#include +#include + #include "jni.hxx" + +#include "jnixx/exceptions.hxx" +#include "jnixx/elements.hxx" + +using namespace java::lang; + +String +frysk::sys::proc::Exe::get(jnixx::env env, jint pid) { + // Get the name of the EXE in /proc. + char file[FILENAME_MAX]; + if (::snprintf(file, sizeof file, "/proc/%d/exe", (int) pid) + >= FILENAME_MAX) + errnoException(env, errno, "snprintf: buffer overflow"); + + // /proc/$$/exe contains a soft-link specifying the name of the + // executable, possibly with "(deleted)" appended. That link's + // upper bound is determined by FILENAME_MAX since that is the + // longest possible allowable file name. + const int maxLen = FILENAME_MAX + sizeof (" (deleted)") + 1; + char link[maxLen]; + int len = ::readlink (file, link, sizeof (link) - 1); + if (len < 0 || len >= maxLen) + errnoException(env, errno, "readlink"); + link[len] = '\0'; + + // Note that some kernels have a "feature" where the link can become + // corrupted. Just retun that, the caller needs to decide if the + // extracted link is valid. + return String::NewStringUTF(env, link); +} diff --git a/frysk-sys/frysk/sys/proc/jni/MapsBuilder.cxx b/frysk-sys/frysk/sys/proc/jni/MapsBuilder.cxx index b358932..462da09 100644 --- a/frysk-sys/frysk/sys/proc/jni/MapsBuilder.cxx +++ b/frysk-sys/frysk/sys/proc/jni/MapsBuilder.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2005, 2008, Red Hat Inc. // // FRYSK is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by @@ -37,4 +37,91 @@ // version and license this file solely under the GPL without // exception. +#include +#include +#include +#include + #include "jni.hxx" + +#include "jnixx/elements.hxx" +#include "jnixx/exceptions.hxx" +#include "jnixx/scan.hxx" + +bool +construct(jnixx::env env, frysk::sys::proc::MapsBuilder* builder, Bytes& buf) { + const char *start = (const char *) buf.elements; + const char *end = start + buf.length; + const char *p = start; + while (p < end) { + if (isspace (*p)) + p++; + else if (*p == '\0') + return true; + else { + //
-
+ jlong addressLow = scanJlong(env, &p, 16); + if (*p++ != '-') + runtimeException(env, "missing dash"); + jlong addressHigh = scanJlong(env, &p, 16); + // + if (*p++ != ' ') + runtimeException(env, "missing space"); + jboolean permRead = *p++ == 'r'; + jboolean permWrite = *p++ == 'w'; + jboolean permExecute = *p++ == 'x'; + jboolean shared = *p++ == 's'; + // + jlong offset = scanJlong(env, &p, 16); + // : + jint devMajor = scanJint(env, &p, 16); + if (*p++ != ':') + runtimeException(env, "missing colon"); + jint devMinor = scanJint(env, &p, 16); + // + jint inode = scanJint(env, &p, 10); + // ? + while (isblank (*p)) + p++; + jint pathnameOffset = p - start; + while (*p != '\0' && *p != '\n') { + p++; + } + int pathnameLength = p - start - pathnameOffset; + builder->buildMap(env, addressLow, addressHigh, + permRead, permWrite, permExecute, shared, + offset, + devMajor, devMinor, + inode, + pathnameOffset, pathnameLength); + } + } + runtimeException(env, "missing NUL"); + return false; +} + +bool +frysk::sys::proc::MapsBuilder::construct(jnixx::env env, jnixx::byteArray buf) { + ArrayBytes bytes = ArrayBytes(env, buf); + bool ok = ::construct(env, this, bytes); + bytes.release(); + return ok; +} + +bool +frysk::sys::proc::MapsBuilder::construct(jnixx::env env, jint pid) { + FileBytes bytes = FileBytes(env, pid, "maps"); + if (bytes.elements == NULL) + return false; + { + jnixx::byteArray array = jnixx::byteArray::NewByteArray(env, bytes.length); + ArrayBytes b = ArrayBytes(env, array); + memcpy(b.elements, bytes.elements, bytes.length); + b.release(); + buildBuffer(env, array); + array.DeleteLocalRef(env); + } + bool ok = ::construct(env, this, bytes); + bytes.release(); + return ok; +} diff --git a/frysk-sys/frysk/sys/proc/jni/Stat.cxx b/frysk-sys/frysk/sys/proc/jni/Stat.cxx index b358932..d4135bb 100644 --- a/frysk-sys/frysk/sys/proc/jni/Stat.cxx +++ b/frysk-sys/frysk/sys/proc/jni/Stat.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2005, 2006, 2008, Red Hat Inc. // // FRYSK is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by @@ -37,4 +37,113 @@ // version and license this file solely under the GPL without // exception. +#include +#include +#include +#include +#include +#include +#include +#include + #include "jni.hxx" + +#include "jnixx/exceptions.hxx" +#include "jnixx/elements.hxx" +#include "jnixx/scan.hxx" +#include "jnixx/logging.hxx" + +using namespace java::lang; +using namespace frysk::sys::proc; + +static void +scan(jnixx::env env, const char*p, Stat& stat, frysk::rsl::Log fine) { + // The "comm" needs special treatment, need to scan backwards for + // ')' as the command itself could contain ')'. + char* commStart = ::strchr(p, '('); + char* commEnd = ::strrchr(p, ')'); + if (commStart == NULL || commEnd == NULL) + runtimeException(env, "botched comm field"); + int commLength = commEnd - (commStart + 1); + char comm[commLength + 1]; + strncpy(comm, commStart+1, commLength); + comm[commLength] = '\0'; + logf(env, fine, "comm %s", comm); + stat.SetComm(env, String::NewStringUTF(env, comm)); + + jint pid = scanJint(env, &p); + logf(env, fine, "pid %d", pid); + stat.SetPid(env, frysk::sys::ProcessIdentifierFactory::create(env, pid)); + + // Messy, its a character, need to first skip any white space. + p = commEnd + 1; + p += ::strspn (p, " "); + char state = *p++; + logf(env, fine, "state %c", state); + stat.SetState(env, state); + + jint ppid = scanJint(env, &p); + logf(env, fine, "ppid %d", ppid); + stat.SetPpid(env, frysk::sys::ProcessIdentifierFactory::create(env, ppid)); + + stat.SetPgrp(env, scanJint(env, &p)); + stat.SetSession(env, scanJint(env, &p)); + stat.SetTtyNr(env, scanJint(env, &p)); + stat.SetTpgid(env, scanJint(env, &p)); + stat.SetFlags(env, scanJlong(env, &p)); + stat.SetMinflt(env, scanJlong(env, &p)); + stat.SetCminflt(env, scanJlong(env, &p)); + stat.SetMajflt(env, scanJlong(env, &p)); + stat.SetCmajflt(env, scanJlong(env, &p)); + stat.SetUtime(env, scanJlong(env, &p)); + stat.SetStime(env, scanJlong(env, &p)); + stat.SetCutime(env, scanJlong(env, &p)); + stat.SetCstime(env, scanJlong(env, &p)); + stat.SetPriority(env, scanJlong(env, &p)); + stat.SetNice(env, scanJint(env, &p)); + stat.SetNumThreads(env, scanJint(env, &p)); + stat.SetIrealvalue(env, scanJlong(env, &p)); + stat.SetStarttime(env, scanJlong(env, &p)); + stat.SetVsize(env, scanJlong(env, &p)); + stat.SetRss(env, scanJlong(env, &p)); + stat.SetRlim(env, scanJlong(env, &p)); + stat.SetStartcode(env, scanJlong(env, &p)); + stat.SetEndcode(env, scanJlong(env, &p)); + stat.SetStartstack(env, scanJlong(env, &p)); + stat.SetKstkesp(env, scanJlong(env, &p)); + stat.SetKstkeip(env, scanJlong(env, &p)); + stat.SetSignal(env, scanJlong(env, &p)); + stat.SetBlocked(env, scanJlong(env, &p)); + stat.SetSigignore(env, scanJlong(env, &p)); + stat.SetSigcatch(env, scanJlong(env, &p)); + stat.SetWchan(env, scanJlong(env, &p)); + stat.SetNswap(env, scanJlong(env, &p)); + stat.SetCnswap(env, scanJlong(env, &p)); + stat.SetExitSignal(env, scanJint(env, &p)); + stat.SetProcessor(env, scanJint(env, &p)); +} + +frysk::sys::proc::Stat +frysk::sys::proc::Stat::scan(jnixx::env env, jint procPid, jint threadTid) { + return scan(env, threadTid); +} + +frysk::sys::proc::Stat +frysk::sys::proc::Stat::scan(jnixx::env env, jint procPid) { + fprintf(stderr, "opening %d\n", procPid); + FileBytes bytes = FileBytes(env, procPid, "stat"); + fprintf(stderr, "elements %s\n", bytes.elements); + if (bytes.elements == NULL) + return Stat(env, NULL); + ::scan(env, (const char*) bytes.elements, *this, GetFine(env)); + bytes.release(); + return *this; +} + +frysk::sys::proc::Stat +frysk::sys::proc::Stat::scan(jnixx::env env, jnixx::byteArray buf) { + ArrayBytes bytes = ArrayBytes(env, buf); + ::scan(env, (const char*) bytes.elements, *this, GetFine(env)); + bytes.release(); + return *this; +} diff --git a/frysk-sys/jnixx/ChangeLog b/frysk-sys/jnixx/ChangeLog index 39d488c..ed3049d 100644 --- a/frysk-sys/jnixx/ChangeLog +++ b/frysk-sys/jnixx/ChangeLog @@ -1,5 +1,8 @@ 2008-05-20 Andrew Cagney + * scan.hxx: New. + * scan.cxx: New. + * elements.hxx (class ArrayBytes): Rename ByteArrayElements. Add length field, extend ByteArray, rename "p" to elements. (class Bytes): New. diff --git a/frysk-sys/frysk/sys/proc/jni/Exe.cxx b/frysk-sys/jnixx/scan.cxx similarity index 71% copy from frysk-sys/frysk/sys/proc/jni/Exe.cxx copy to frysk-sys/jnixx/scan.cxx index b358932..29b8700 100644 --- a/frysk-sys/frysk/sys/proc/jni/Exe.cxx +++ b/frysk-sys/jnixx/scan.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2005, 2007, 2008 Red Hat Inc. // // FRYSK is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by @@ -37,4 +37,43 @@ // version and license this file solely under the GPL without // exception. hooks/post-receive -- frysk system monitor/debugger