/tags/lkcd-6.1.0/lkcdutils/qlcrash/qlcrash/qlcrashdoc.cpp
C++ | 2026 lines | 1622 code | 288 blank | 116 comment | 430 complexity | 951b5eacf6591f4f6f229148696a3e10 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.1, LGPL-2.0
- /*-*-c++-*-
- * $Id: qlcrashdoc.cpp 1079 2004-10-22 19:59:34Z troyhebe $
- *
- * This file is part of qlcrash, a GUI for the dump-analysis tool lcrash.
- *
- * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *
- * Authors:
- * Michael Geselbracht (let@users.sourceforge.net)
- * Fritz Elfert (elfert@de.ibm.com)
- * Michael Holzheu (holzheu@de.ibm.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version. See the file COPYING for more
- * information.
- */
- #include "qlcrashdoc.h"
- #include "parser.h"
- #include "cchildmanager.h"
- #include "cconfigmanager.h"
- #include "structviewitem.h"
- #include "crashtypes.h"
- #include "clistview.h"
- #include "cparseview.h"
- #include <qapplication.h>
- #include <qmessagebox.h>
- #include <qstringlist.h>
- #include <qtimer.h>
- #include <qcache.h>
- #include <qstring.h>
- #include <qregexp.h>
- #ifndef WIN32
- # ifndef _GNU_SOURCE
- # define _GNU_SOURCE
- # endif
- #endif
- #include <assert.h>
- #include <ctype.h>
- #include <stdlib.h>
- #ifndef WIN32
- #include <stdint.h>
- #ifdef USE_REGEX
- #include <regex.h>
- #endif
- #else
- #ifdef USE_REGEX
- #include <hsregex.h>
- #endif
- #endif
- #include <signal.h>
- #include <iostream>
- #include "avl.h"
- // max. number of walk iterations
- #define WALKMAX 500
- using namespace std;
- int hexCharToInt(unsigned char ch)
- {
- int retval = ch - '0';
- if (retval > 9) {
- retval = ch - 'A' + 10;
- }
- if (retval > 15) {
- retval = ch - 'a' + 10;
- }
- return retval;
- }
- void removeTypeInfo(QString &result)
- {
- int rc=result.findRev(')', -1);
- if(rc != -1){
- // since lkcdutils 4.2 the output of
- // print ((task_struct*)0x..)->next_task
- // is '(task_struct *) 0x... >>'
- // we must get rid of the leading
- // type description
- result = result.mid(rc + 1);
- }
- }
- void dereferencePointerType(QString &result)
- {
- int rc=result.findRev('*', -1);
- if(rc != -1){
- result = result.left(rc);
- }
- }
- QLcrashDoc::QLcrashDoc(CConfigManager* cm, QObject* parent, const char* name)
- : QObject(parent, name)
- , oConfigManager(cm)
- , oGraph(false)
- , oWaitForInit(true)
- , oQuitAfterChildExit(false)
- , lcrashIsReady(false)
- , oS390dbf(-1)
- , oTargetEndian(unknown)
- , oTargetWordSize(-1)
- {
- oParser = new CParser(this);
- oChildManager = new CChildManager(this);
- oDumpCache = new QCache<unsigned char>(100, 131);
- connect(oChildManager, SIGNAL(sigChildDied()), SLOT(slotChildDied()));
- connect(oChildManager, SIGNAL(sigStdout(QString)), SLOT(slotStdoutFromChild(QString)));
- connect(oChildManager, SIGNAL(sigStderr(QString)), SLOT(slotStderrFromChild(QString)));
- connect(oChildManager, SIGNAL(sigBusy(bool)), SIGNAL(sigBusy(bool)));
- connect(this, SIGNAL(sigSetup()), oChildManager, SLOT(slotSetup()));
- oInitialTimer = new QTimer(this);
- connect(oInitialTimer, SIGNAL(timeout()), SLOT(slotInitialTimeout()));
- oInitialTimer->start(1000, true);
- }
- QLcrashDoc::~QLcrashDoc()
- {
- }
- void
- QLcrashDoc::slotSetup() {
- emit sigSetup();
- }
- void
- QLcrashDoc::slotFromConsole(CNConsole* con, QString str)
- {
- // don't accept user input until initialization of lcrash is complete
- if (oWaitForInit) {
- return;
- }
- str = str.stripWhiteSpace();
- if (str.isEmpty()) {
- emit sigToConsole(con, /*QString("\n") +*/ CMD_PROMPT);
- return;
- }
- if (str == "quit" || str == "q!" || str == "q") {
- emit sigExit(true);
- return;
- }
- if (str.left(2) == "vi") {
- printErr(tr("Editing of sial functions not supported from within qlcrash"));
- return;
- }
- if (str.left(5) == "graph") {
- oGraph = true;
- str = str.mid(5).stripWhiteSpace();
- }
- if (str.left(5) == "print") {
- QString tmp = str.mid(5).stripWhiteSpace();
- if ((tmp.left(2) != "-x") &&
- (tmp.left(2) != "-d") &&
- (tmp.left(2) != "-o") &&
- (tmp.left(2) != "-b") ) {
- str = QString("print") + printFormat() + tmp;
- }
- }
- QString result;
- bool w = oChildManager->command(str, result);
- if (w) {
- if (result.length() > 0) {
- if (oGraph == true) {
- if (result.left(6) == "struct" || result.left(6) == "union") {
- oParser->clearDebugString();
- oParser->setString(result);
- oParser->parseStruct();
- if (oParser->error()) {
- CParseView* pv = new CParseView(oParser, 0);
- pv->setFont(qApp->font());
- pv->exec();
- delete pv;
- }
- if (oParser->root() != 0) {
- // search address in command string
- int pos = str.find("0x", 0, false);
- if (pos != -1) {
- QString addr = getAddressFromExpression(str);
- // Address found. Store in root node.
- if (addr.length() > 2) {
- TreeNode* root = oParser->root();
- root->value = addr;
- }
- }
- QString type = getTypeFromExpression(str);
- if (!type.isEmpty()) {
- createTree(con, type);
- }
- else {
- emit sigErrToConsole(con, tr("Invalid type") + "\n");
- }
- }
- }
- else if (str.left(4) == "task") {
- PRINT(cerr << "graph task requested" << endl);
- oParser->setString(result);
- oParser->parseTaskList();
- if (!oParser->error()) {
- emit sigTaskList(&oParser->taskList());
- }
- else {
- PRINT(cerr << "Parse error in task list" << endl);
- }
- }
- else if (str.find(" print")) { // assuming pointer to scalar
- CListView* lv = new CListView(0);
- lv->addColumn(tr("Name"));
- lv->addColumn(tr("Value"));
- lv->addColumn(tr("Type"));
- lv->setSorting(-1);
- lv->setFindColumn(0);
- lv->setMinimumSize(200, 100);
-
- QString type = getTypeFromExpression(str);
- dereferencePointerType(type);
- QString addr = getAddressFromExpression(str);
- removeTypeInfo(result);
-
- if (result.right(CMD_PROMPT_LEN) == CMD_PROMPT) {
- result.truncate(result.length() - CMD_PROMPT_LEN);
- }
- result = result.simplifyWhiteSpace();
-
- StructViewItem* lvi;
- lvi = new StructViewItem(lv);
- lvi->setType(type);
- lvi->setPixmapType(Scalar);
- lvi->setText(0, "*(" + addr + ")");
- lvi->setText(1, result);
- lvi->setText(2, type);
-
- emit sigNewGraph(lv);
- if (lv->parentWidget() == 0) { // object is unused
- delete lv;
- }
- }
- oGraph = false;
- }
- else {
- emit sigToConsole(con, result /*+ CMD_PROMPT*/);
- }
- }
- else {
- emit sigToConsole(con, CMD_PROMPT);
- }
- }
- else {
- emit sigErrToConsole(con, result + CMD_PROMPT);
- oGraph = false;
- }
- }
- void
- QLcrashDoc::slotRestart()
- {
- oQuitAfterChildExit = false;
- oChildManager->killChild();
- sigToConsole(0, "\n");
- // prevent qlcrash from exiting if call of lcrash fails
- oInitialTimer->start(1000, true);
- setLCrashPath(oConfigManager->item(CFG_GRP_FILES, CFG_ATT_FILES_LCRASH, LCRASH_DEFAULT_PATH));
- runCrash();
- }
- void
- QLcrashDoc::slotChildDied()
- {
- if (oChildManager->retval() != 0) {
- cerr << tr("lcrash exited with an error.") << endl;
- }
- if (oQuitAfterChildExit) {
- emit sigExit(false);
- }
- else {
- emit sigToConsole(0, tr("lcrash exited.") + "\n");
- }
- }
- void
- QLcrashDoc::slotInitialTimeout()
- {
- // oQuitAfterChildExit = true;
- if (lcrashIsReady)
- emit sigLCrashReady();
- }
- void
- QLcrashDoc::runCrash()
- {
- if (!oChildManager->valid()) {
- QMessageBox::critical(
- 0,
- stdCaption(tr("Error")),
- tr("Cannot execute lcrash. Please check the program settings\nand restart lcrash with File->Restart.")
- );
- }
- else {
- oWaitForInit = true;
- lcrashIsReady = false;
- emit sigBusy(true);
- if (!oLcrashArgs.isEmpty()) {
- oChildManager->setArgs(oLcrashArgs);
- }
- oChildManager->forkChild();
- oChildManager->setSignalOnTimeout(SIGINT);
- }
- }
- void
- QLcrashDoc::setLCrashPath(const QString path)
- {
- #if 0
- oChildManager->setChildPath(path);
- // do some sanity checks
- if (!oChildManager->exists()) {
- QMessageBox::critical(
- 0,
- stdCaption(tr("Error")),
- tr("Could not find lcrash at specified position.")
- );
- }
- else if (!oChildManager->executable()) {
- QMessageBox::critical(
- 0,
- stdCaption(tr("Error")),
- tr("You do not have the permission to execute the\nspecified file.")
- );
- }
- #endif
- }
- void
- QLcrashDoc::loadConfig()
- {
- setLCrashPath(oConfigManager->item(CFG_GRP_FILES, CFG_ATT_FILES_LCRASH, LCRASH_DEFAULT_PATH));
- // save directory defaults to the user's home dir
- oLastSaveDir = oConfigManager->homeDir();
- }
- void
- QLcrashDoc::createTree(CNConsole* con, QString typeHint)
- {
- TreeNode* root = oParser->root();
- if (root == 0) {
- emit sigErrToConsole(con, tr("Cannot create struct view") + "\n");
- return;
- }
- CListView* lv = new CListView(0);
- lv->addColumn(tr("Name"));
- lv->addColumn(tr("Value"));
- lv->addColumn(tr("Type"));
- lv->setSorting(-1);
- lv->setFindColumn(0);
- lv->setMinimumSize(200, 100);
- // traverse the tree created by the parser and build a QListView
- createTreeTraverse(root, lv, typeHint);
- emit sigNewGraph(lv);
- if (lv->parentWidget() == 0) {
- delete lv;
- }
- }
- void
- QLcrashDoc::createTreeTraverse(TreeNode* root, CListView* rootItem, QString typeHint)
- {
- // prepare root node...
- StructViewItem* item = new StructViewItem(rootItem);
- item->setType(root->name);
- item->setPixmapType(root->type);
- item->setText(0, root->name);
- item->setText(1, root->value);
- item->setType((root->name.length() > 0) ? root->name : typeHint);
- TreeNode* walker = root->childList.first();
- // get struct info. use type hint from caller if lcrash does not return the type of the structure
- QDict<QString>* map = structInfo(item->type());
- // also use type hint for the tree itself, if we can't obtain a type info from the print output
- if (item->text(0).length() == 0) {
- item->setText(0, typeHint);
- }
- // ...and continue with its children
- StructViewItem* after = 0;
- while (walker != 0) {
- createTreeTraverse(walker, item, map, &after, root->name);
- walker = root->childList.next();
- }
- // expand tree (first level)
- item->setOpen(true);
- }
- void
- QLcrashDoc::createTreeTraverse(TreeNode* parentNode, StructViewItem* parentItem, QDict<QString>* theMap, StructViewItem** after, const QString& pName)
- {
- if (parentNode == 0) {
- return;
- }
- StructViewItem* item = 0; // "0" to avoid a compiler warning
- QString type;
- // the tree might contain null entries which contains the children of the parent node
- if (parentNode->type != Null) {
- #ifdef WIN32
- #pragma warning(push)
- #pragma warning(disable:4390)
- #endif
- if (parentNode->name == "0") { // to set a `conditional' breakpoint in gdb
- if (parentNode);
- }
- #ifdef WIN32
- #pragma warning(pop)
- #endif
- item = (*after == 0) ? new StructViewItem(parentItem) : new StructViewItem(parentItem, *after);
- // item->setPixmapType(parentNode->type);
- item->setText(0, parentNode->name);
- *after = item;
- if (parentNode->type == Array) {
- type = parentNode->arrayType;
- }
- else if (parentNode->type == ArrayStruct) {
- type = parentNode->value;
- }
- else { // Struct and Scalar
- type = parentNode->name;
- if (type != QString::null && theMap != 0) {
- QString* tname = theMap->find(type);
- if (tname != 0) {
- PRINT(cerr << theMap << " " << parentNode->name << endl);
- type = *tname;
- }
- else {
- type = "?";
- }
- }
- else {
- type = "?";
- }
- }
- item->setPixmapType((type.findRev("*") == -1) ? parentNode->type : Pointer);
- item->setType(type);
- if (parentNode->type == Scalar || parentNode->type == Array) {
- item->setText(1, parentNode->value);
- }
- item->setText(2, type);
- }
- else {
- item = parentItem;
- *after = 0;
- }
- // get type information for child tree
- if ((parentNode->type == Struct || parentNode->type == ArrayStruct)) {
- // in case of an array struct, the type is stored as 'value' attribute :(
- QString tmp = (parentNode->type == Struct) ? parentNode->name : parentNode->value;
- QString* tname = 0;
- if (!tmp.isEmpty()) {
- tname = (theMap != 0) ? theMap->find(tmp) : 0;
- /*
- if (tname != 0) {
- theMap = structInfo(*tname);
- }
- */
- /*
- else if (parentNode->type == ArrayStruct && type[0] != '(') {
- theMap = structInfo(tmp);
- }
- */
- theMap = structInfo(pName);
- }
- } // array elments are of the same type as their parent node, so get type of such a parent
- else if (parentNode->type == Array && parentNode->childList.count() > 0 && theMap != 0) {
- QString* tmp = theMap->find(parentNode->name);
- if (tmp != 0) {
- parentNode->arrayType = *tmp;
- // this is a hack to set the array type correctly for display
- item->setText(2, *tmp);
- item->setType(*tmp);
- }
- else {
- parentNode->arrayType = "?";
- }
- }
- TreeNode* walker = parentNode->childList.first();
- StructViewItem* tmp = 0;
- type = parentNode->arrayType;
- if (parentNode->type == Array) { // strip array size from type name for array elements
- if (type.right(1) == "]") {
- type.truncate(type.findRev("["));
- }
- }
- while (walker != 0) {
- // walker is an array -> assign its type. Be aware of the null-nodes (assign type if parent is array)!
- if (walker->type == Array || parentNode->type == Array) {
- walker->arrayType = type;
- }
- // build `path' from this attribute to the root data type
- QString cName = pName;
- if (walker->type != Null) { // this is a node type, not a data type :-O
- if (walker->type != Array) { // ArrayStruct || Struct
- if (walker->type == Struct) {
- cName = cName + "." + walker->name;
- }
- else { // ArrayStruct
- // if (parentNode->type == Null) {
- cName = type;
- // }
- }
- }
- else {
- /* keep cName */
- }
- }
- else { // save name
- // walker->name = parentNode->name;
- }
- createTreeTraverse(walker, item, theMap, &tmp, cName);
- walker = parentNode->childList.next();
- }
- }
- QDict<QString>*
- QLcrashDoc::structInfo(QString str)
- {
- if (str == QString::null || str[0] == '(') {
- return 0;
- }
- /** `whatis' returns weird results if there are no parenthesis around the expression.
- But this doesn't work with subtypes.
- */
- QString search = str;
- if (str.find('.') == -1) { // simple expression
- search.prepend("(");
- search.append(")");
- }
- QDict<QString>* list = oTypeMap[str];
- if (list == 0) {
- /* O.k. retrieve information from lcrash */
- QString q;
- PRINT(cerr << "whatis " + search + " ...");
- bool w = oChildManager->command(QString("whatis ") + search + "\n", q);
- PRINT(cerr << "done" << endl);
- if (w && !q.isEmpty()) {
- oParser->clearDebugString();
- oParser->setString(q);
- oParser->parseWhatIs();
- if (oParser->error()) {
- CParseView* pv = new CParseView(oParser, 0);
- pv->setFont(qApp->font());
- pv->exec();
- delete pv;
- }
- else {
- list = oParser->typeMap();
- if (list != 0) {
- oTypeMap.insert(str, list);
- }
- }
- }
- }
- return list;
- }
- CListView*
- QLcrashDoc::getTree(const QString& name, const QString& addr, const QString& type)
- {
- QString result;
- bool w = oChildManager->command(
- QString("print ") + printFormat() + "*(" + type + ") " + addr, result);
- if (w) {
- if (result.left(6) == "struct" || result.left(6) == "union") {
- oGraph = true;
- oParser->setString(result);
- oParser->parseStruct();
- if (oParser->error()) {
- CParseView* pv = new CParseView(oParser, 0);
- pv->setFont(qApp->font());
- pv->exec();
- delete pv;
- }
- TreeNode* root = oParser->root();
- result = result.stripWhiteSpace();
- if (root != 0) {
- CListView* lv = new CListView(0);
- lv->addColumn(tr("Name"));
- lv->addColumn(tr("Value"));
- lv->addColumn(tr("Type"));
- lv->setSorting(-1);
- lv->setFindColumn(0);
- lv->setMinimumSize(200, 100);
- root->value = addr;
- QString root_t = type;
- if (root_t.right(1) == "*") {
- root_t.truncate(root_t.length() - 1);
- }
- createTreeTraverse(root, lv, root_t);
- oGraph = false;
- return lv;
- }
- }
- else { // no struct
- QString ntype = type;
- CListView* lv = new CListView(0);
- if (result.right(CMD_PROMPT_LEN) == CMD_PROMPT) {
- result.truncate(result.length() - CMD_PROMPT_LEN);
- }
- result = result.stripWhiteSpace();
- lv->addColumn(tr("Name"));
- lv->addColumn(tr("Value"));
- lv->addColumn(tr("Type"));
- // lv->header()->hide();
- lv->setMinimumSize(200, 40);
- if (ntype.right(1) == "*") {
- ntype.truncate(type.length() - 1);
- }
- StructViewItem* svi = new StructViewItem(lv);
- svi->setText(0, name);
- svi->setText(1, result);
- svi->setText(2, ntype);
- svi->setType(ntype);
- svi->setPixmapType((ntype.findRev("*") == -1) ? Scalar : Pointer);
- return lv;
- }
- }
- else {
- emit sigErrToConsole(0, result + "\n" + CMD_PROMPT);
- }
- return 0;
- }
- CListView*
- QLcrashDoc::getArray(const QString& addr, const QString& type, int number)
- {
- CListView* retList = 0;
- // get size info
- int size = sizeinfo(type, "");
- if (size > 0) {
- // get address
- bool ret;
- unsigned long long val = (UINT64)strtoull(addr.mid(2).latin1(), 0, 16);
- if (ret) {
- // O.k., create list
- CListView* lv = new CListView(0, "arrayList");
- lv->addColumn(tr("Name"));
- lv->addColumn(tr("Value"));
- lv->addColumn(tr("Type"));
- lv->setSorting(-1);
- lv->setMinimumSize(200, 100);
- StructViewItem* svi = new StructViewItem(lv);
- svi->setText(0, type);
- svi->setType(type);
- svi->setPixmapType(Array);
- // arrays of pointers are handled different from `normal' arrays
- bool pointer = (type.findRev('*') != -1) ? true : false;
- // ensure that item are appended to the tree at the end
- StructViewItem* after = 0;
- if (pointer) {
- /* pointers are a bit more difficult than other types since
- we have to request the contents of each element from lcrash
- */
- //! assuming that `sizeof(long) == sizeof(void*)' on dump source platform
- size = targetWordSize();
- for (int i = 0; i < number; i++) {
- QString result;
- char newAddrStr[100];
- sprintf(newAddrStr, "%llx",val);
- bool ret = oChildManager->command("print *(void**) 0x" + QString::fromLatin1(newAddrStr), result);
- removeTypeInfo(result);
- if (result.right(CMD_PROMPT_LEN) == CMD_PROMPT) {
- result.truncate(result.length() - CMD_PROMPT_LEN);
- }
- val += size;
- if (ret) {
- result = result.stripWhiteSpace();
- StructViewItem* svch = after ? new StructViewItem(svi, after) : new StructViewItem(svi);
- after = svch;
- svch->setText(0, QString::number(i));
- svch->setText(1, result);
- svch->setText(2, type);
- svch->setType(type);
- svch->setPixmapType(Pointer);
- }
- else { // failed
- delete lv;
- }
- }
- }
- else {
- for (int i = 0; i < number; i++) {
- StructViewItem* svch = after ? new StructViewItem(svi, after) : new StructViewItem(svi);
- char newAddrStr[100];
- sprintf(newAddrStr, "%llx",val);
- after = svch;
- svch->setText(0, QString::number(i));
- svch->setText(1, QString("0x") + QString::fromLatin1(newAddrStr));
- svch->setText(2, type + "*");
- svch->setType(type + "*"); // we display an array of pointers
- svch->setPixmapType(Pointer);
- val += size;
- }
- }
- svi->setOpen(true);
- lv->setCaption(type + "[" + QString::number(number) + "]" + "@" + addr);
- retList = lv;
- }
- }
- return retList;
- }
- CListView*
- QLcrashDoc::getWalk(const QString& name, const QString& addr, const QString& type)
- {
- bool ret;
- QString result;
- // determine if `name' is a list_head
- ret = oChildManager->command("whatis " + type + "." + name, result);
- if (ret) {
- if (result.left(16) == "struct list_head") {
- return getListHead(name, addr, type);
- }
- }
- else {
- printErr(result);
- return 0;
- }
- ret = oChildManager->command("print ((" + type + "*)" + addr + ")->" + name, result);
- if (ret) {
- removeTypeInfo(result);
- // remove trailing prompt
- if (result.right(CMD_PROMPT_LEN) == CMD_PROMPT) {
- result.truncate(result.length() - CMD_PROMPT_LEN);
- }
- result = result.stripWhiteSpace();
- CListView* lv = new CListView(0);
- lv->addColumn(tr("Name"));
- lv->addColumn(tr("Value"));
- lv->addColumn(tr("Type"));
- lv->setMinimumSize(200, 100);
- lv->setSorting(-1);
- StructViewItem* svi = new StructViewItem(lv);
- StructViewItem* after = 0;
- svi->setText(0, type + "." + name);
- svi->setText(1, addr);
- svi->setType(type);
- svi->setPixmapType(Array);
- int i = 0;
- Avl<QString> aset;
- do {
- aset.insert(result);
- StructViewItem* svch = after ? new StructViewItem(svi, after) : new StructViewItem(svi);
- after = svch;
- svch->setText(0, QString::number(i++));
- svch->setText(1, result);
- svch->setText(2, type + "*");
- svch->setType(type + "*");
- svch->setPixmapType(Pointer);
- // avoid infinite recursion
- if (i > WALKMAX) {
- sigErrToConsole(0, tr("Walk has reached WALKMAX (%1)").arg(QString::number(WALKMAX)));
- break;
- }
- ret = oChildManager->command("print ((" + type + "*)" + result + ")->" + name, result);
- if(ret){
- removeTypeInfo(result);
- }
- // remove trailing prompt
- if (ret && result.right(CMD_PROMPT_LEN) == CMD_PROMPT) {
- result.truncate(result.length() - CMD_PROMPT_LEN);
- }
- result = result.stripWhiteSpace();
- } while (ret && result != "0x0" && result[0].latin1() != '(' && !aset.search(result));
- svi->setOpen(true);
- lv->setCaption("walk:" + type + "." + name + "@" + addr);
- return lv;
- }
- return 0;
- }
- CListView*
- QLcrashDoc::getListHead(const QString& name, const QString& addr, const QString& type)
- {
- QString result;
- CListView* tree = 0;
- bool ret = oChildManager->command("walk -h n -t " + type + " " + name + " " + addr, result);
- if (ret) {
- QList<QString>* list = new QList<QString>;
- list->setAutoDelete(true);
- // create a list of addresses using the first column
- const int len = result.length();
- for (int i = 0; i < len; i++) {
- // ignore white space
- while (i < len && (result[i].latin1() == ' ' || result[i].latin1() == '\t'))
- i++;
- if (isdigit(result[i].latin1())) {
- int s = i++;
- while (i < len && isalnum(result[i].latin1()))
- i++;
- list->append(new QString(result.mid(s, i - s)));
- }
- // ignore the rest of the line
- while (i < len && result[i].latin1() != '\n')
- i++;
- }
- // lreate a list view
- CListView* lv = new CListView(0);
- lv->addColumn(tr("Name"));
- lv->addColumn(tr("Value"));
- lv->addColumn(tr("Type"));
- lv->setMinimumSize(200, 100);
- lv->setSorting(-1);
- StructViewItem* svi = new StructViewItem(lv);
- StructViewItem* after = 0;
- svi->setText(0, type + "." + name);
- svi->setText(1, addr);
- svi->setType(type);
- svi->setPixmapType(Array);
- QString* walker = list->first();
- int n = 0;
- while (walker != 0) {
- if (walker->length() > 1) {
- StructViewItem* svch = after ? new StructViewItem(svi, after) : new StructViewItem(svi);
- after = svch;
- svch->setText(0, QString::number(n++));
- svch->setText(1, *walker);
- svch->setText(2, type + "*");
- svch->setType(type + "*");
- svch->setPixmapType(Pointer);
- }
- walker = list->next();
- }
- delete list;
- svi->setOpen(true);
- lv->setCaption("walk:" + type + "." + name + "@" + addr);
- tree = lv;
- }
- return tree;
- }
- void
- QLcrashDoc::slotStderrFromChild(QString str)
- {
- emit sigErrToConsole(0, str);
- }
- void
- QLcrashDoc::slotStdoutFromChild(QString str)
- {
- if (oWaitForInit) {
- if (str.right(CMD_PROMPT_LEN) == CMD_PROMPT) {
- oWaitForInit = false;
- lcrashIsReady = true;
- oInitialTimer->start(1000, true);
- // emit sigLCrashReady();
- // Initial newline
- emit sigToConsole(0, "\n");
- }
- }
- if (oGraph == false) {
- emit sigToConsole(0, str);
- }
- }
- void
- QLcrashDoc::printTypeInfo(const QString& type, const QString& name)
- {
- if (type == "" || type == "?") {
- sigErrToConsole(0, tr("Could not get type info") + "\n");
- }
- else {
- int size = sizeinfo(type, name);
- if (size > 0) {
- emit sigToConsole(0, QString("\n") + tr("Type") + ": " + type + "\n");
- emit sigToConsole(0, tr("sizeof") + ": " + QString::number(size) + " Bytes\n");
- }
- else {
- sigErrToConsole(0, tr("Could not get type info") + "\n");
- }
- }
- emit sigToConsole(0, CMD_PROMPT);
- }
- void
- QLcrashDoc::printWhatis(const QString& type, const QString& name)
- {
- if (type.length() == 0 || type == "?") {
- sigErrToConsole(0, tr("'whatis' failed") + "\n");
- }
- else {
- QString result;
- bool w = oChildManager->command("whatis " + type, result);
- if (w) {
- emit sigToConsole(0, type + " = " + result + "\n");
- }
- else {
- w = oChildManager->command("whatis " + name, result);
- if (w) {
- emit sigToConsole(0, name + " = " + result + "\n");
- }
- else {
- emit sigErrToConsole(0, tr("'whatis' failed") + ".\n");
- }
- }
- }
- emit sigToConsole(0, CMD_PROMPT);
- }
- void
- QLcrashDoc::printTrace(const QString& addr)
- {
- QString result;
- bool w = oChildManager->command(QString("trace") + " " + addr, result);
- if (w) {
- sigToConsole(0, (QString) "\n" + result + "\n");
- }
- emit sigToConsole(0, CMD_PROMPT);
- }
- int
- QLcrashDoc::sizeinfo(const QString& type, const QString& name)
- {
- // a pointer has always the same size
- if (type.right(1) == "*") {
- return targetWordSize();
- }
- // compare types with builtin types
- Avl<QString> set;
- QStringList list = QStringList::split(' ', type);
- for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
- set.insert(*it);
- }
- // check for 'long long'
- Avl<QString>::iterator ait = set.find("long");
- if (ait != set.end()) {
- // is there a second 'long' ?
- if (++ait != set.end() && *ait == "long") {
- return 8;
- }
- return targetWordSize();
- }
- if (set.search("int")) {
- return 4;
- }
- if (set.search("short")) {
- return 2;
- }
- if (set.search("char")) {
- return 1;
- }
- #ifndef WIN32
- #warning "This could become a problem..."
- #endif
- if (set.search("double")) {
- return sizeof(double);
- }
- if (set.search("float")) {
- return sizeof(float);
- }
- // not a builtin type
- QString result;
- bool ret = oChildManager->command("sizeof " + type, result);
- if (!ret) { // try 'whatis' followed by 'sizeof'
- ret = oChildManager->command("whatis (" + type + ")", result);
- if (ret) {
- ret = oChildManager->command("sizeof " + result, result);
- }
- if (!ret && name.length() > 0) { // try attribute name
- ret = oChildManager->command("sizeof " + name, result);
- }
- }
- if (ret) {
- QString num = "";
- int i, len = result.length(),match_len;
- // skip to colon
- QRegExp r(": *[0-9]");
- i=r.match(result,0,&match_len);
- i+=match_len -1;
- // copy number digit by digit
- for (; i < len; i++) {
- char ch = result.at(i).latin1();
- if (!isdigit(ch)) {
- break;
- }
- num.append(ch);
- }
- int val = num.toInt(&ret);
- return ret ? val : 0;
- }
- else {
- sigErrToConsole(0, QString("\n") + tr("Size of `%1' unknown").arg(type) + "\n");
- }
- return 0;
- }
- void
- QLcrashDoc::print(const QString& str)
- {
- sigToConsole(0, str + "\n" + CMD_PROMPT);
- }
- void
- QLcrashDoc::printErr(const QString& str)
- {
- sigErrToConsole(0, str + "\n" + CMD_PROMPT);
- }
- QString
- QLcrashDoc::printFormat() const
- {
- int idx = oConfigManager->item(CFG_GRP_GRAPH, CFG_ATT_GRAPH_PRINTFORMAT, 0);
- if (idx > 0) {
- switch (idx) {
- case 1:
- return " -x ";
- case 2:
- return " -d ";
- case 3:
- return " -o ";
- case 4:
- return " -b ";
- default:
- return " ";
- }
- }
- return " ";
- }
- const unsigned char*
- QLcrashDoc::getDump(const QString& addr)
- {
- if (oWaitForInit) {
- return 0;
- }
- unsigned char* cptr = oDumpCache->find(addr);
- if (cptr == 0) {
- QString sAddr = QString("0x") + addr;
- QString result;
- bool ret = oChildManager->command("dump -B " + sAddr + " 16", result);
- if (ret) {
- cptr = new unsigned char[16];
- oDumpCache->insert(addr, cptr);
- int len = result.length();
- int i;
- // skip to the first colon
- for (i = 0; i < len && result.at(i).latin1() != ':'; i++) { /* empty */ }
- i += 2;
- unsigned char ch;
- int idx = 0, s = -1;
- while (i < len && (ch = result.at(i).latin1()) != ':') {
- i++;
- if (ch == ' ') {
- assert(idx < 16);
- cptr[idx++] = s;
- s = -1;
- continue;
- }
- s = (s == -1) ? hexCharToInt(ch) * 16 : s + hexCharToInt(ch);
- }
- }
- }
- return cptr;
- }
- int
- QLcrashDoc::targetSetup()
- {
- QString result;
- bool ret = oChildManager->command("info -s endian", result);
- if (ret) {
- if(result.mid(0,6) == "little"){
- oTargetEndian=little;
- } else if(result.mid(0,3) == "big") {
- oTargetEndian=big;
- } else {
- cerr << "QLcrashDoc::targetLittleEndian: info -s failed\n";
- oTargetEndian=unknown;
- }
- } else {
- cerr << "QLcrashDoc::targetLittleEndian: info -s failed\n";
- oTargetEndian=unknown;
- }
- ret = oChildManager->command("info -s psize", result);
- if (ret) {
- if(result.mid(0,2) == "32"){
- oTargetWordSize=4;
- } else if(result.mid(0,2) == "64"){
- oTargetWordSize=8;
- } else {
- cerr << "QLcrashDoc::targetWordSize: info -s psize returned '" << result << "'\n";
- oTargetWordSize=-1;
- }
- } else {
- cerr << "QLcrashDoc::targetWordSize: info -s psize failed\n";
- oTargetWordSize=-1;
- }
- return 0;
- }
- bool
- QLcrashDoc::targetLittleEndian() const
- {
- if(oTargetEndian == little)
- return true;
- else
- return false;
- }
- int
- QLcrashDoc::targetWordSize() const
- {
- if(oTargetWordSize == -1)
- return sizeof(long);
- else
- return oTargetWordSize;
-
- }
- QStringList*
- QLcrashDoc::s390AvailableLogs()
- {
- QStringList* list = new QStringList;
- QString result;
- bool ret = oChildManager->command("s390dbf", result);
- if (ret) {
- *list = QStringList::split('\n', result);
- int count = list->count();
- if (count > 2) {
- QStringList::Iterator it = list->begin();
- it = list->remove(it);
- it = list->remove(it);
- for (int i = 2; i < count - 1; i++) {
- (*it) = (*it).simplifyWhiteSpace();
- (*it) = (*it).mid(2);
- ++it;
- }
- list->remove(it);
- }
- }
- return list;
- }
- QStringList*
- QLcrashDoc::s390AvailableViews(const QString& log)
- {
- QStringList* list = new QStringList;
- QString result;
- bool ret = oChildManager->command("s390dbf " + log, result);
- if (ret) {
- *list = QStringList::split('\n', result);
- int count = list->count();
- if (count > 3) {
- QStringList::Iterator it = list->begin();
- it = list->remove(it);
- it = list->remove(it);
- for (int i = 2; i < count - 2; i++) {
- (*it) = (*it).simplifyWhiteSpace();
- // (*it) = QStringList::split(' ', (*it).mid(2)).first();
- (*it) = (*it).mid(2);
- ++it;
- }
- it = list->remove(it);
- list->remove(it);
- }
- }
- return list;
- }
- QString
- QLcrashDoc::s390dbfText(const QString& log, const QString& view)
- {
- QString result;
- oChildManager->command("s390dbf " + log + " " + view, result);
- // remove trailing newline and prompt
- if (result.right(CMD_PROMPT_LEN) == CMD_PROMPT) {
- result.truncate(result.length() - CMD_PROMPT_LEN);
- }
- while (!result.isEmpty() && result.right(1) == "\n") {
- result.truncate(result.length() - 1);
- }
- return result;
- }
- void
- QLcrashDoc::s390dbfSaveToFile(const QString& log, const QString& view, const QString& file)
- {
- QString result;
- bool ret = oChildManager->command("s390dbf -w " + file + " " + log + " " + view, result);
- if (!ret) {
- emit printErr(result);
- }
- }
- bool
- QLcrashDoc::haveDebugFeature()
- {
- if (oWaitForInit) {
- cerr << "QLcrashDoc::haveDebugFeature() called during initialization phase." << endl;
- return false;
- }
- if (oS390dbf == -1) {
- QString result;
- bool ret = oChildManager->command("s390dbf", result);
- oS390dbf = ret ? 1 : 0;
- }
- return oS390dbf;
- }
- QString
- QLcrashDoc::helpHomeURL()
- {
- #ifdef WIN32
- #ifdef _DEBUG
- return QString("file:/") + execdir() + "/../../Doc/Manual/index.html";
- #else
- return QString("file:/") + execdir() + "/Manual/index.html";
- #endif
- #else
- return "file:/" DOCDIR "/index.html";
- #endif
- }
- QString
- QLcrashDoc::lastSaveDir() const
- {
- return oLastSaveDir;
- }
- void
- QLcrashDoc::setLastSaveDir(const QString& lsd)
- {
- oLastSaveDir = lsd;
- }
- QString
- QLcrashDoc::getTypeFromExpression(const QString& expr) const
- {
- int len = expr.length();
- int i = expr.find("print");
- int count = 0;
- QString type;
- if (i != -1) {
- i += 5;
- }
- else {
- i = 0;
- }
- for (; i < len; i++) {
- if (expr[i].latin1() != ' ') {
- break;
- }
- }
- for (; i < len; i++) {
- if (expr[i].latin1() == '*') {
- count--;
- }
- else {
- break;
- }
- }
- for (; i < len; i++) {
- if (expr[i].latin1() == '(') {
- break;
- }
- }
- while (i < len && !isalpha(expr[i].latin1())) {
- i++;
- }
- char ch;
- int start = i;
- while (i < len && (isalpha((ch = expr[i].latin1()))||ch=='_'||ch==' '|| (isdigit(ch) && (start < i)) )) {
- type += ch;
- i++;
- }
- for (; i < len; i++) {
- ch = expr[i].latin1();
- switch (ch) {
- case '*':
- count++;
- break;
- case ')':
- i = len;
- break;
- default:
- continue;
- }
- }
- for (i = 0; i < count; i++) {
- type += '*';
- }
- return (count >= 0) ? type : QString::null;
- }
- QString
- QLcrashDoc::getAddressFromExpression(const QString& expr) const
- {
- QString ret;
- int pos = expr.find("0x");
-
- if (pos >= 0) {
- const int len = expr.length();
- pos += 2;
- ret = "0x";
-
- while (pos < len && isxdigit(expr[pos].latin1())) {
- ret += expr[pos];
- pos++;
- }
- }
-
- return ret;
- }
- QValueList<CDisassemble>
- QLcrashDoc::getDisassemble(const QString& fkt)
- {
- QValueList<CDisassemble> list;
- QString result;
- bool ret = oChildManager->command("dis -F " + fkt, result);
- if (ret) {
- #ifdef USE_REGEX
- regex_t reg;
- regmatch_t sub[4];
- ret = regcomp(
- ®,
- "(0x[0-9a-f]+)[ \t]*(<[^>]+>):[ \t]*(.+)\n",
- REG_EXTENDED | REG_NEWLINE
- );
- assert(!ret);
- int offset = 0, len = result.length();
- while (offset < len && regexec(®, result.latin1() + offset, 4, sub, 0) == 0) {
- QString part;
- CDisassemble cd;
- part = result.mid(offset + sub[1].rm_so, sub[1].rm_eo - sub[1].rm_so);
- cd.setAddr(part.simplifyWhiteSpace());
- part = result.mid(offset + sub[2].rm_so, sub[2].rm_eo - sub[2].rm_so);
- cd.setOffset(part.simplifyWhiteSpace());
- part = result.mid(offset + sub[3].rm_so, sub[3].rm_eo - sub[3].rm_so);
- cd.setMnemonic(part.simplifyWhiteSpace());
- list.append(cd);
- offset = offset + sub[0].rm_eo;
- }
- regfree(®);
- #else
- #if QT_VERSION >= 300
- // New QT 3.0
- QRegExp r("(0x[0-9a-f]+)[ \t]*(<[^>]+>):[ \t]*([^\\n]+)\n");
- int offset = 0, len = result.length();
- while (offset < len && (r.search(result, offset) >= 0)) {
- CDisassemble cd;
- cd.setAddr(r.cap(1).simplifyWhiteSpace());
- cd.setOffset(r.cap(2).simplifyWhiteSpace());
- cd.setMnemonic(r.cap(3).simplifyWhiteSpace());
- list.append(cd);
- offset += r.matchedLength();
- }
- #else
- // Old QT < 3.0
- QRegExp r("0x[0-9a-f]+[ \t]*<[^>]+>:[ \t]*[^\\n]+\\n");
- QRegExp sub1("0x[0-9a-f]+");
- QRegExp sub2("[ \t]*");
- QRegExp sub3("<[^>]+>");
- QRegExp sub4(":[ \t]*");
- QRegExp sub5("[^\\n]+");
- int offset = 0, len = result.length();
- int rlen;
- int rpos;
- while (offset < len && ((rpos = r.match(result, offset, &rlen)) >= 0)) {
- int slen;
- CDisassemble cd;
- sub1.match(result, rpos, &slen);
- cd.setAddr(result.mid(rpos, slen).simplifyWhiteSpace());
- rpos += slen;
- sub2.match(result, rpos, &slen);
- rpos += slen;
- sub3.match(result, rpos, &slen);
- cd.setOffset(result.mid(rpos, slen).simplifyWhiteSpace());
- rpos += slen;
- sub4.match(result, rpos, &slen);
- rpos += slen;
- sub5.match(result, rpos, &slen);
- cd.setMnemonic(result.mid(rpos, slen).simplifyWhiteSpace());
- list.append(cd);
- offset += rlen;
- }
- #endif // !QT 3.0
- #endif // !USE_REGEX
- }
- return list;
- }
- QValueList<CTraceItem>
- QLcrashDoc::getTrace(const QString& addr)
- {
- QValueList<CTraceItem> list;
- QString result;
- bool ret = oChildManager->command("trace " + addr, result);
- if (ret) {
- int offset = 0, len = result.length();
- // skip header and retrieve task name
- while (offset < len && result[offset].latin1() != '(') {
- offset++;
- }
- QString name;
- offset++;
- while (offset < len && result[offset].latin1() != ')') {
- name.append(result[offset]);
- offset++;
- }
- CTraceItem item;
- item.setFunction(name);
- list.append(item);
- while (offset < len && !isdigit(result[offset].latin1())) {
- offset++;
- }
- #ifdef USE_REGEX
- regex_t reg;
- regmatch_t sub[5];
- ret = regcomp(
- ®,
- "[ \t]*([0-9]+)[ \t]*([a-zA-Z0-9_]+)(\\+[0-9]+)?[ \t]*\\[(0x[0-9a-zA-F]+)\\][ \t]*\n",
- REG_EXTENDED | REG_NEWLINE
- );
- assert(!ret);
- while (offset < len && regexec(®, result.latin1() + offset, 5, sub, 0) == 0) {
- QString part;
- CTraceItem ci;
- part = result.mid(offset + sub[1].rm_so, sub[1].rm_eo - sub[1].rm_so);
- ci.setLevel(part);
- part = result.mid(offset + sub[2].rm_so, sub[2].rm_eo - sub[2].rm_so);
- ci.setFunction(part);
- part = result.mid(offset + sub[3].rm_so, sub[3].rm_eo - sub[3].rm_so);
- ci.setOffset(part);
- part = result.mid(offset + sub[4].rm_so, sub[4].rm_eo - sub[4].rm_so);
- ci.setAddress(part);
- offset = offset + sub[0].rm_eo;
- list.append(ci);
- }
- regfree(®);
- #else
- #if QT_VERSION >= 300
- #warning QT3 QRegExp stuff is yet untested
- QRegExp r("[ \t]*([0-9]+)[ \t]*([a-zA-Z0-9_]+)(\\+[0-9]+)?[ \t]*\\[(0x[0-9a-zA-F]+)\\][ \t]*\\n");
- offset = r.search(result,offset);
- while (offset < len && ((offset = r.search(result, offset)) >= 0)) {
- CTraceItem ci;
- ci.setLevel(r.cap(1));
- ci.setFunction(r.cap(2));
- ci.setOffset(r.cap(3));
- ci.setAddress(r.cap(4));
- list.append(ci);
- offset += r.matchedLength();
- }
- #else
- QRegExp r("[ \t]*[0-9]+[ \t]*[a-zA-Z0-9_]+\\+[0-9]+[ \t]*\\[0x[0-9a-zA-F]+\\][ \t]*\\n");
- QRegExp r2("[ \t]*[0-9]+[ \t]*[a-zA-Z0-9_]+[ \t]*\\[0x[0-9a-zA-F]+\\][ \t]*\\n");
- QRegExp sub1("[ \t]*");
- QRegExp sub2("[0-9]+"); // cap
- //QRegExp sub3 = sub1;
- QRegExp sub4("[a-zA-Z0-9_]+"); // cap
- QRegExp sub5("\\+[0-9]+"); // cap
- QRegExp sub6("[ \t]*\\[");
- QRegExp sub7("0x[0-9a-zA-F]+"); // cap
- //QRegExp sub8("\\][ \t]*\\n");
- int rlen;
- int rlen2;
- int rpos;
- int rpos2;
- while (offset < len &&
- (((rpos = r.match(result, offset, &rlen)) >= 0) ||
- ((rpos2 = r2.match(result, offset, &rlen2)) >= 0) )) {
- int slen;
- CTraceItem ci;
- int rofs = (rpos >= 0) ? rpos : rpos2;
- int alen = (rpos >= 0) ? rlen : rlen2;
- offset = rofs + alen;
- sub1.match(result, rofs, &slen);
- rofs += slen;
- sub2.match(result, rofs, &slen);
- ci.setLevel(result.mid(rofs, slen));
- rofs += slen;
- sub1.match(result, rofs, &slen);
- rofs += slen;
- sub4.match(result, rofs, &slen);
- ci.setFunction(result.mid(rofs, slen));
- rofs += slen;
- if (rpos >= 0) {
- sub5.match(result, rofs, &slen);
- ci.setOffset(result.mid(rofs, slen));
- rofs += slen;
- } else
- ci.setOffset("");
- sub6.match(result, rofs, &slen);
- rofs += slen;
- sub7.match(result, rofs, &slen);
- ci.setAddress(result.mid(rofs, slen));
- rofs += slen;
- list.append(ci);
- }
- #endif // !QT >= 3.0
- #endif // !USE_REGEX
- }
- return list;
- }
- CLowcoreList
- QLcrashDoc::getTraceLowcore(const QString& addr)
- {
- CLowcoreList list;
- QString result;
- bool ret = oChildManager->command("trace " + addr, result);
- if (ret) {
- int offset;
- const int len = result.length();
- // check for lowcore info
- if ((offset = result.find("LOWCORE INFO")) != -1) {
- while (offset < len && result[offset].latin1() != '-') {
- offset++;
- }
- QString token;
- pair<QString, QStringList> p;
- while (offset < len) {
- offset = offset + getTraceLowcoreToken(result.latin1() + offset, token);
- if (token[0].latin1() == '-') { // new section
- if (!p.first.isEmpty()) {
- list.append(p);
- }
- p.first = token;
- p.second.clear();
- }
- else { // normal token
- if (token.left(5) == "STACK" || token.at(1).latin1() == '=') {
- break;
- }
- p.second.append(token);
- }
- }
- if (!p.first.isEmpty()) {
- list.append(p);
- }
- }
- }
- return list;
- }
- int
- QLcrashDoc::getTraceLowcoreToken(const char* str, QString& ret)
- {
- bool label = false;
- const char* cptr = str;
- while (*cptr != 0 && (*cptr == ' ' || *cptr == '\t' || *cptr == '\n')) {
- cptr++;
- }
- if (*cptr == '-') {
- label = true;
- ret = "-";
- cptr++;
- }
- else {
- ret = "";
- }
- while (*cptr != 0 && *cptr != (label ? ':' : ' ') && *cptr != '\n') {
- while (*cptr != 0 && *cptr == ' ' && *(cptr-1) == ' ') {
- cptr++;
- }
- while (*cptr != 0 && *cptr == '\n') {
- cptr++;
- }
- if (label && *cptr == ':') {
- cptr++;
- break;
- }
- ret += *cptr++;
- }
- if (label && *cptr == ':') {
- cptr++;
- }
- if (ret.at(ret.length() - 1).latin1() == ':') {
- ret.truncate(ret.length() - 1);
- }
- if (ret.at(ret.length() - 1).latin1() == ' ') {
- ret.truncate(ret.length() - 1);
- }
- return cptr - str;
- }
- QValueList<CTaskItem>
- QLcrashDoc::getTaskList()
- {
- QValueList<CTaskItem> list;
- QString result;
- bool ret = oChildManager->command("task", result);
- if (ret) {
- // skip header
- int offset = 0, len = result.length();
- while (offset < len && !isdigit(result[offset].latin1())) {
- offset++;
- }
- #ifdef USE_REGEX
- regex_t reg;
- regmatch_t sub[6];
- ret = regcomp(
- ®,
- "(0x[a-z0-9]+)[ \t]+" // ADDR
- "[0-9]+[ \t]+" // UID
- "([0-9]+)[ \t]+" // PID
- "[0-9]+[ \t]+" // PPID
- "([0-9]+)[ \t]+" // STATE
- "0[x0-9]*[ \t]+" // FLAGS
- "(-|[0-9]+)[ \t]+" // CPU
- "(.+)\n", // NAME
- REG_EXTENDED | REG_NEWLINE
- );
- assert(!ret);
- // match line by line
- while (offset < len && regexec(®, result.latin1() + offset, 6, sub, 0) == 0) {
- QString part;
- CTaskItem ti;
- part = result.mid(offset + sub[1].rm_so, sub[1].rm_eo - sub[1].rm_so);
- ti.setAddress(part);
- part = result.mid(offset + sub[2].rm_so, sub[2].rm_eo - sub[2].rm_so);
- ti.setPid(part);
- part = result.mid(offset + sub[3].rm_so, sub[3].rm_eo - sub[3].rm_so);
- ti.setStatus(part);
- part = result.mid(offset + sub[4].rm_so, sub[4].rm_eo - sub[4].rm_so);
- ti.setCpu(part);
- part = result.mid(offset + sub[5].rm_so, sub[5].rm_eo - sub[5].rm_so);
- ti.setName(part);
- offset = offset + sub[0].rm_eo;
- list.append(ti);
- }
- regfree(®);
- #else
- #if QT_VERSION >= 300
- #warning QT3 QRegExp stuff is yet untested
- QRegExp r(
- "(0x[a-z0-9]+)[ \t]+" // ADDR
- "[0-9]+[ \t]+" // UID
- "([0-9]+)[ \t]+" // PID
- "[0-9]+[ \t]+" // PPID
- "([0-9]+)[ \t]+" // STATE
- "0[x0-9]*[ \t]+" // FLAGS
- "(-|[0-9]+)[ \t]+" // CPU
- "([^\\n]+)\\n" // NAME
- );
- while (offset < len && (r.search(result, offset) >= 0)) {
- CTaskItem ti;
- ti.setAddress(r.cap(1));
- ti.setPid(r.cap(2));
- ti.setStatus(r.cap(3));
- ti.setCpu(r.cap(4));
- ti.setName(r.cap(5));
- offset += r.matchedLength();
- list.append(ti);
- }
- #else
- QRegExp r(
- "0x[a-z0-9]+[ \t]+" // ADDR
- "[0-9]+[ \t]+" // UID
- "[0-9]+[ \t]+" // PID
- "[0-9]+[ \t]+" // PPID
- "[0-9]+[ \t]+" // STATE
- "0[x0-9]*[ \t]+" // FLAGS
- "[0-9-]+[ \t]+" // CPU
- "[^\\n]+\\n" // NAME
- );
- QRegExp sub1("0x[a-z0-9]+"); // cap
- QRegExp sub2("[ \t]+[0-9]+[ \t]+");
- QRegExp sub3("[0-9]+"); // cap
- // QRegExp sub4 == sub2;
- // QRegExp sub5 == sub3; // cap
- QRegExp sub6("[ \t]+0[x0-9]*[ \t]+");
- QRegExp sub7("[0-9-]+"); // cap
- QRegExp sub8("[ \t]+");
- QRegExp sub9("[^\\n]+"); // cap
- int rlen;
- int rpos;
- while (offset < len && ((rpos = r.match(result, offset, &rlen)) >= 0)) {
- int slen;
- CTaskItem ti;
- sub1.match(result, rpos, &slen);
- ti.setAddress(result.mid(rpos, slen));
- rpos += slen;
- sub2.match(result, rpos, &slen);
- rpos += slen;
- sub3.match(result, rpos, &slen);
- ti.setPid(result.mid(rpos, slen));
- rpos += slen;
- sub2.match(result, rpos, &slen);
- rpos += slen;
- sub3.match(result, rpos, &slen);
- ti.setStatus(result.mid(rpos, slen));
- rpos += slen;
- sub6.match(result, rpos, &slen);
- rpos += slen;
- sub7.match(result, rpos, &slen);
- ti.setCpu(result.mid(rpos, slen));
- rpos += slen;
- sub8.match(result, rpos, &slen);
- rpos += slen;
- sub9.match(result, rpos, &slen);
- ti.setName(result.mid(rpos, slen));
- rpos += slen;
- offset += rlen;
- list.append(ti);
- }
- #endif // !QT >= 3.0
- #endif // !USE_REGEX
- }
- return list;
- }
- QValueList<CSymtabItem>
- QLcrashDoc::getGlobalSymbols()
- {
- QValueList<CSymtabItem> list;
- QString result;
- int new_symtab=0;
- bool ret;
- ret = oChildManager->command("symtab -f -l", result);
- if(strncmp(result, "Argument", 8) == 0){
- // lkcdutils 4.2
- ret = oChildManager->command("symtab -t -l", result);
- new_symtab=1;
- }
- if (ret) {
- int offset = 0;
- const int len = result.length();
- const char* cptr = result.latin1();
- while (offset < len) {
- CSymtabItem item;
- QString part;
- if(new_symtab){
- // A new line...
- // ignore leading spaces
- offset += strspn(cptr + offset, " \t");
- // Address
- size_t pos = strcspn(cptr + offset, " \t");
- part = result.mid(offset, pos);
- // validate line
- if (part.left(2) != "0x") {
- offset += strcspn(cptr + offset, "\n") + 1;
- continue;
- }
- offset += pos;
- item.setAddress(part);
-
- offset += strspn(cptr + offset, " \t");
-
- // Type
- pos = strcspn(cptr + offset, " \n");
- part = result.mid(offset, pos);
- offset += pos;
- item.setType(part);
- offset += strspn(cptr + offset, " \t");
- // Name
- pos = strcspn(cptr + offset, " \t");
- part = result.mid(offset, pos);
- offset += pos;
- item.setName(part);
- list.append(item);
- offset += strcspn(cptr + offset, "\n") + 1;
- } else {
- // A new line...
-
- // ignore leading spaces
- offset += strspn(cptr + offset, " \t");
-
- // Address
- size_t pos = strcspn(cptr + offset, " \n");
- part = result.mid(offset, pos);
- // validate line
- if (part.left(2) != "0x") {
- offset += strcspn(cptr + offset, "\n") + 1;
- continue;
- }
- offset += pos;
- item.setAddress(part);
-
- offset += strspn(cptr + offset, " \t");
-
- // A digit
- pos = strcspn(cptr + offset, " \n");
- offset += pos;
-
- offset += strspn(cptr + offset, " \t");
-
- // Type
- pos = strcspn(cptr + offset, " \n");
- part = result.mid(offset, pos);
- offset += pos;
- item.setType(part);
-
- offset += strspn(cptr + offset, " \t");
-
- // Name
- pos = strcspn(cptr + offset, " \n");
- part = result.mid(offset, pos);
- offset += pos;
- item.setName(part);
-
- list.append(item);
-
- offset += strspn(cptr + offset, " \t\n");
- }
- }
- }
- return list;
- }
- QString
- QLcrashDoc::getLcrashHelp()
- {
- QString str;
- bool ret = oChildManager->command("help", str);
-
- return ret ? str : QString::null;
- }