Extend copyright to 2018.
[kdbg.git] / kdbg / gdbdriver.cpp
blobeb0d133ad95ec84966d90619aae2577ea040d26e
1 /*
2 * Copyright Johannes Sixt
3 * This file is licensed under the GNU General Public License Version 2.
4 * See the file COPYING in the toplevel directory of the source directory.
5 */
7 #include "gdbdriver.h"
8 #include "exprwnd.h"
9 #include <QFileInfo>
10 #include <QRegExp>
11 #include <QStringList>
12 #include <klocalizedstring.h> /* i18n */
13 #include <ctype.h>
14 #include <signal.h>
15 #include <stdlib.h> /* strtol, atoi */
16 #include <string.h> /* strcpy */
18 #include "assert.h"
19 #include "mydebug.h"
21 static void skipString(const char*& p);
22 static void skipNested(const char*& s, char opening, char closing);
23 static ExprValue* parseVar(const char*& s);
24 static bool parseName(const char*& s, QString& name, VarTree::NameKind& kind);
25 static bool parseValue(const char*& s, ExprValue* variable);
26 static bool parseNested(const char*& s, ExprValue* variable);
27 static bool parseVarSeq(const char*& s, ExprValue* variable);
28 static bool parseValueSeq(const char*& s, ExprValue* variable);
30 #define PROMPT "(kdbg)"
31 #define PROMPT_LEN 6
33 // TODO: make this cmd info stuff non-static to allow multiple
34 // simultaneous gdbs to run!
36 struct GdbCmdInfo {
37 DbgCommand cmd;
38 const char* fmt; /* format string */
39 enum Args {
40 argNone, argString, argNum,
41 argStringNum, argNumString,
42 argString2, argNum2
43 } argsNeeded;
46 #if 0
47 // This is how the QString data print statement generally looks like.
48 // It is set by KDebugger via setPrintQStringDataCmd().
50 static const char printQStringStructFmt[] =
51 // if the string data is junk, fail early
52 "print ($qstrunicode=($qstrdata=(%s))->unicode)?"
53 // print an array of shorts
54 "(*(unsigned short*)$qstrunicode)@"
55 // limit the length
56 "(($qstrlen=(unsigned int)($qstrdata->len))>100?100:$qstrlen)"
57 // if unicode data is 0, report a special value
58 ":1==0\n";
59 #endif
60 static const char printQStringStructFmt[] = "print (0?\"%s\":$kdbgundef)\n";
63 * The following array of commands must be sorted by the DC* values,
64 * because they are used as indices.
66 static GdbCmdInfo cmds[] = {
67 { DCinitialize, "", GdbCmdInfo::argNone },
68 { DCtty, "tty %s\n", GdbCmdInfo::argString },
69 { DCexecutable, "file \"%s\"\n", GdbCmdInfo::argString },
70 { DCtargetremote, "target remote %s\n", GdbCmdInfo::argString },
71 #ifdef __FreeBSD__
72 { DCcorefile, "target FreeBSD-core %s\n", GdbCmdInfo::argString },
73 #else
74 { DCcorefile, "target core %s\n", GdbCmdInfo::argString },
75 #endif
76 { DCattach, "attach %s\n", GdbCmdInfo::argString },
77 { DCinfolinemain, "kdbg_infolinemain\n", GdbCmdInfo::argNone },
78 { DCinfolocals, "kdbg__alllocals\n", GdbCmdInfo::argNone },
79 { DCinforegisters, "info all-registers\n", GdbCmdInfo::argNone},
80 { DCexamine, "x %s %s\n", GdbCmdInfo::argString2 },
81 { DCinfoline, "info line %s:%d\n", GdbCmdInfo::argStringNum },
82 { DCdisassemble, "disassemble %s %s\n", GdbCmdInfo::argString2 },
83 { DCsetargs, "set args %s\n", GdbCmdInfo::argString },
84 { DCsetenv, "set env %s %s\n", GdbCmdInfo::argString2 },
85 { DCunsetenv, "unset env %s\n", GdbCmdInfo::argString },
86 { DCsetoption, "setoption %s %d\n", GdbCmdInfo::argStringNum},
87 { DCcd, "cd %s\n", GdbCmdInfo::argString },
88 { DCbt, "bt\n", GdbCmdInfo::argNone },
89 { DCrun, "run\n", GdbCmdInfo::argNone },
90 { DCcont, "cont\n", GdbCmdInfo::argNone },
91 { DCstep, "step\n", GdbCmdInfo::argNone },
92 { DCstepi, "stepi\n", GdbCmdInfo::argNone },
93 { DCnext, "next\n", GdbCmdInfo::argNone },
94 { DCnexti, "nexti\n", GdbCmdInfo::argNone },
95 { DCfinish, "finish\n", GdbCmdInfo::argNone },
96 { DCuntil, "until %s:%d\n", GdbCmdInfo::argStringNum },
97 { DCkill, "kill\n", GdbCmdInfo::argNone },
98 { DCdetach, "detach\n", GdbCmdInfo::argNone },
99 { DCbreaktext, "break %s\n", GdbCmdInfo::argString },
100 { DCbreakline, "break %s:%d\n", GdbCmdInfo::argStringNum },
101 { DCtbreakline, "tbreak %s:%d\n", GdbCmdInfo::argStringNum },
102 { DCbreakaddr, "break *%s\n", GdbCmdInfo::argString },
103 { DCtbreakaddr, "tbreak *%s\n", GdbCmdInfo::argString },
104 { DCwatchpoint, "watch %s\n", GdbCmdInfo::argString },
105 { DCdelete, "delete %d\n", GdbCmdInfo::argNum },
106 { DCenable, "enable %d\n", GdbCmdInfo::argNum },
107 { DCdisable, "disable %d\n", GdbCmdInfo::argNum },
108 { DCprint, "print %s\n", GdbCmdInfo::argString },
109 { DCprintDeref, "print *(%s)\n", GdbCmdInfo::argString },
110 { DCprintStruct, "print %s\n", GdbCmdInfo::argString },
111 { DCprintQStringStruct, printQStringStructFmt, GdbCmdInfo::argString},
112 { DCprintPopup, "print %s\n", GdbCmdInfo::argString },
113 { DCframe, "frame %d\n", GdbCmdInfo::argNum },
114 { DCfindType, "whatis %s\n", GdbCmdInfo::argString },
115 { DCinfosharedlib, "info sharedlibrary\n", GdbCmdInfo::argNone },
116 { DCthread, "thread %d\n", GdbCmdInfo::argNum },
117 { DCinfothreads, "info threads\n", GdbCmdInfo::argNone },
118 { DCinfobreak, "info breakpoints\n", GdbCmdInfo::argNone },
119 { DCcondition, "condition %d %s\n", GdbCmdInfo::argNumString},
120 { DCsetpc, "set variable $pc=%s\n", GdbCmdInfo::argString },
121 { DCignore, "ignore %d %d\n", GdbCmdInfo::argNum2},
122 { DCprintWChar, "print ($s=%s)?*$s@wcslen($s):0x0\n", GdbCmdInfo::argString },
123 { DCsetvariable, "set variable %s=%s\n", GdbCmdInfo::argString2 },
126 #define NUM_CMDS (int(sizeof(cmds)/sizeof(cmds[0])))
127 #define MAX_FMTLEN 200
129 GdbDriver::GdbDriver() :
130 DebuggerDriver()
132 #ifndef NDEBUG
133 // check command info array
134 const char* perc;
135 for (int i = 0; i < NUM_CMDS; i++) {
136 // must be indexable by DbgCommand values, i.e. sorted by DbgCommand values
137 assert(i == cmds[i].cmd);
138 // a format string must be associated
139 assert(cmds[i].fmt != 0);
140 assert(strlen(cmds[i].fmt) <= MAX_FMTLEN);
141 // format string must match arg specification
142 switch (cmds[i].argsNeeded) {
143 case GdbCmdInfo::argNone:
144 assert(strchr(cmds[i].fmt, '%') == 0);
145 break;
146 case GdbCmdInfo::argString:
147 perc = strchr(cmds[i].fmt, '%');
148 assert(perc != 0 && perc[1] == 's');
149 assert(strchr(perc+2, '%') == 0);
150 break;
151 case GdbCmdInfo::argNum:
152 perc = strchr(cmds[i].fmt, '%');
153 assert(perc != 0 && perc[1] == 'd');
154 assert(strchr(perc+2, '%') == 0);
155 break;
156 case GdbCmdInfo::argStringNum:
157 perc = strchr(cmds[i].fmt, '%');
158 assert(perc != 0 && perc[1] == 's');
159 perc = strchr(perc+2, '%');
160 assert(perc != 0 && perc[1] == 'd');
161 assert(strchr(perc+2, '%') == 0);
162 break;
163 case GdbCmdInfo::argNumString:
164 perc = strchr(cmds[i].fmt, '%');
165 assert(perc != 0 && perc[1] == 'd');
166 perc = strchr(perc+2, '%');
167 assert(perc != 0 && perc[1] == 's');
168 assert(strchr(perc+2, '%') == 0);
169 break;
170 case GdbCmdInfo::argString2:
171 perc = strchr(cmds[i].fmt, '%');
172 assert(perc != 0 && perc[1] == 's');
173 perc = strchr(perc+2, '%');
174 assert(perc != 0 && perc[1] == 's');
175 assert(strchr(perc+2, '%') == 0);
176 break;
177 case GdbCmdInfo::argNum2:
178 perc = strchr(cmds[i].fmt, '%');
179 assert(perc != 0 && perc[1] == 'd');
180 perc = strchr(perc+2, '%');
181 assert(perc != 0 && perc[1] == 'd');
182 assert(strchr(perc+2, '%') == 0);
183 break;
186 assert(strlen(printQStringStructFmt) <= MAX_FMTLEN);
187 #endif
190 GdbDriver::~GdbDriver()
195 QString GdbDriver::driverName() const
197 return "GDB";
200 QString GdbDriver::defaultGdb()
202 return
203 "gdb"
204 " --fullname" /* to get standard file names each time the prog stops */
205 " --nx"; /* do not execute initialization files */
208 QString GdbDriver::defaultInvocation() const
210 if (m_defaultCmd.isEmpty()) {
211 return defaultGdb();
212 } else {
213 return m_defaultCmd;
217 QStringList GdbDriver::boolOptionList() const
219 // no options
220 return QStringList();
223 bool GdbDriver::startup(QString cmdStr)
225 if (!DebuggerDriver::startup(cmdStr))
226 return false;
228 static const char gdbInitialize[] =
230 * Work around buggy gdbs that do command line editing even if they
231 * are not on a tty. The readline library echos every command back
232 * in this case, which is confusing for us.
234 "set editing off\n"
235 "set confirm off\n"
236 "set print static-members off\n"
237 "set print asm-demangle on\n"
239 * Sometimes, gdb prints [New Thread ...] during 'info threads';
240 * we will not look at thread events anyway, so turn them off.
242 "set print thread-events off\n"
244 * We do not want Python pretty printer support, because their
245 * output is unpredictable, and we cannot parse it.
247 "set auto-load python off\n"
249 * Nevertheless, some Python messages get through, for example,
250 * when a backtrace is printed without the Python gdb module loaded.
252 "set python print-stack none\n"
254 * Don't assume that program functions invoked from a watch expression
255 * always succeed.
257 "set unwindonsignal on\n"
259 * Write a short macro that prints all locals: local variables and
260 * function arguments.
262 "define kdbg__alllocals\n"
263 "info locals\n" /* local vars supersede args with same name */
264 "info args\n" /* therefore, arguments must come last */
265 "end\n"
267 * Work around a bug in gdb-6.3: "info line main" crashes gdb.
269 "define kdbg_infolinemain\n"
270 "list\n"
271 "info line\n"
272 "end\n"
273 // check endianness for memory dumps
274 "show endian\n"
275 // change prompt string and synchronize with gdb
276 "set prompt " PROMPT "\n"
279 executeCmdString(DCinitialize, gdbInitialize, false);
281 // assume that QString::null is ok
282 cmds[DCprintQStringStruct].fmt = printQStringStructFmt;
284 return true;
287 void GdbDriver::commandFinished(CmdQueueItem* cmd)
289 // command string must be committed
290 if (!cmd->m_committed) {
291 // not commited!
292 TRACE("calling " + (__PRETTY_FUNCTION__ + (" with uncommited command:\n\t" +
293 cmd->m_cmdString)));
294 return;
297 switch (cmd->m_cmd) {
298 case DCinitialize:
301 * Check for GDB 7.1 or later; the syntax for the disassemble
302 * command has changed.
303 * This RE picks the last version number in the first line,
304 * because at least OpenSUSE writes its own version number
305 * in the first line (but before GDB's version number).
307 QRegExp re(
308 " " // must be preceded by space
309 "[(]?" // SLES 10 embeds in parentheses
310 "(\\d+)\\.(\\d+)" // major, minor
311 "[^ ]*\\n" // no space until end of line
313 int pos = re.indexIn(m_output);
314 const char* disass = "disassemble %s %s\n";
315 if (pos >= 0) {
316 int major = re.cap(1).toInt();
317 int minor = re.cap(2).toInt();
318 if (major > 7 || (major == 7 && minor >= 1))
320 disass = "disassemble %s, %s\n";
323 cmds[DCdisassemble].fmt = disass;
325 m_littleendian = m_output.contains("little endian");
327 break;
328 default:;
331 /* ok, the command is ready */
332 emit commandReceived(cmd, m_output.constData());
334 switch (cmd->m_cmd) {
335 case DCcorefile:
336 case DCinfolinemain:
337 case DCinfoline:
338 case DCframe:
339 case DCattach:
340 case DCrun:
341 case DCcont:
342 case DCstep:
343 case DCstepi:
344 case DCnext:
345 case DCnexti:
346 case DCfinish:
347 case DCuntil:
348 parseMarker(cmd);
349 default:;
353 int GdbDriver::findPrompt(const QByteArray& output) const
356 * If there's a prompt string in the collected output, it must be at
357 * the very end.
359 * Note: It could nevertheless happen that a character sequence that is
360 * equal to the prompt string appears at the end of the output,
361 * although it is very, very unlikely (namely as part of a string that
362 * lingered in gdb's output buffer due to some timing/heavy load
363 * conditions for a very long time such that that buffer overflowed
364 * exactly at the end of the prompt string look-a-like).
366 int len = output.length();
367 if (len >= PROMPT_LEN &&
368 strncmp(output.data()+len-PROMPT_LEN, PROMPT, PROMPT_LEN) == 0)
370 return len-PROMPT_LEN;
372 return -1;
376 * The --fullname option makes gdb send a special normalized sequence print
377 * each time the program stops and at some other points. The sequence has
378 * the form "\032\032filename:lineno:charoffset:(beg|middle):address".
380 void GdbDriver::parseMarker(CmdQueueItem* cmd)
382 char* startMarker = strstr(m_output.data(), "\032\032");
383 if (startMarker == 0)
384 return;
386 // extract the marker
387 startMarker += 2;
388 TRACE(QString("found marker: ") + startMarker);
389 char* endMarker = strchr(startMarker, '\n');
390 if (endMarker == 0)
391 return;
393 *endMarker = '\0';
395 // extract filename and line number
396 static QRegExp MarkerRE(":(\\d+):\\d+:[begmidl]+:0x");
398 int lineNoStart = MarkerRE.indexIn(startMarker);
399 if (lineNoStart >= 0) {
400 int lineNo = MarkerRE.cap(1).toInt();
402 // get address unless there is one in cmd
403 DbgAddr address = cmd->m_addr;
404 if (address.isEmpty()) {
405 const char* addrStart = startMarker + lineNoStart +
406 MarkerRE.matchedLength() - 2;
407 address = QString(addrStart).trimmed();
410 // now show the window
411 startMarker[lineNoStart] = '\0'; /* split off file name */
412 emit activateFileLine(startMarker, lineNo-1, address);
418 * Escapes characters that might lead to problems when they appear on gdb's
419 * command line.
421 static void normalizeStringArg(QString& arg)
424 * Remove trailing backslashes. This approach is a little simplistic,
425 * but we know that there is at the moment no case where a trailing
426 * backslash would make sense.
428 while (!arg.isEmpty() && arg[arg.length()-1] == '\\') {
429 arg = arg.left(arg.length()-1);
434 QString GdbDriver::makeCmdString(DbgCommand cmd, QString strArg)
436 assert(cmd >= 0 && cmd < NUM_CMDS);
437 assert(cmds[cmd].argsNeeded == GdbCmdInfo::argString);
439 normalizeStringArg(strArg);
441 if (cmd == DCcd) {
442 // need the working directory when parsing the output
443 m_programWD = strArg;
444 } else if (cmd == DCsetargs && !m_redirect.isEmpty()) {
446 * Use saved redirection. We prepend it in front of the user's
447 * arguments so that the user can override the redirections.
449 strArg = m_redirect + " " + strArg;
452 QString cmdString;
453 cmdString.sprintf(cmds[cmd].fmt, strArg.toUtf8().constData());
454 return cmdString;
457 QString GdbDriver::makeCmdString(DbgCommand cmd, int intArg)
459 assert(cmd >= 0 && cmd < NUM_CMDS);
460 assert(cmds[cmd].argsNeeded == GdbCmdInfo::argNum);
462 QString cmdString;
463 cmdString.sprintf(cmds[cmd].fmt, intArg);
464 return cmdString;
467 QString GdbDriver::makeCmdString(DbgCommand cmd, QString strArg, int intArg1, int intArg2)
469 assert(cmd == DCexamine);
471 normalizeStringArg(strArg);
473 QString cmdString;
475 if (cmd == DCexamine) {
476 // make a format specifier from the intArg
477 static const char size[16] = {
478 '\0', 'b', 'h', 'w', 'g'
480 static const char format[16] = {
481 '\0', 'x', 'd', 'u', 'o', 't',
482 'a', 'c', 'f', 's', 'i'
484 assert(MDTsizemask == 0xf); /* lowest 4 bits */
485 assert(MDTformatmask == 0xf0); /* next 4 bits */
486 int count = intArg2; /* number of entities to print */
487 char sizeSpec = size[intArg1 & MDTsizemask];
488 char formatSpec = format[(intArg1 & MDTformatmask) >> 4];
489 assert(sizeSpec != '\0');
490 assert(formatSpec != '\0');
492 QString spec;
493 spec.sprintf("/%d%c%c", count, sizeSpec, formatSpec);
494 cmdString = makeCmdString(DCexamine, spec, strArg);
497 return cmdString;
500 QString GdbDriver::makeCmdString(DbgCommand cmd, QString strArg, int intArg)
502 assert(cmd >= 0 && cmd < NUM_CMDS);
503 assert(cmds[cmd].argsNeeded == GdbCmdInfo::argStringNum ||
504 cmds[cmd].argsNeeded == GdbCmdInfo::argNumString ||
505 cmd == DCtty);
507 normalizeStringArg(strArg);
509 QString cmdString;
511 if (cmd == DCtty)
514 * intArg specifies which channels should be redirected to
515 * /dev/null. It is a value or'ed together from RDNstdin,
516 * RDNstdout, RDNstderr. We store the value for a later DCsetargs
517 * command.
519 * Note: We rely on that after the DCtty a DCsetargs will follow,
520 * which will ultimately apply the redirection.
522 static const char* const runRedir[8] = {
524 "</dev/null",
525 ">/dev/null",
526 "</dev/null >/dev/null",
527 "2>/dev/null",
528 "</dev/null 2>/dev/null",
529 ">/dev/null 2>&1",
530 "</dev/null >/dev/null 2>&1"
532 if (strArg.isEmpty())
533 intArg = 7; /* failsafe if no tty */
534 m_redirect = runRedir[intArg & 7];
536 return makeCmdString(DCtty, strArg); /* note: no problem if strArg empty */
539 if (cmds[cmd].argsNeeded == GdbCmdInfo::argStringNum)
541 // line numbers are zero-based
542 if (cmd == DCuntil || cmd == DCbreakline ||
543 cmd == DCtbreakline || cmd == DCinfoline)
545 intArg++;
547 if (cmd == DCinfoline)
549 // must split off file name part
550 strArg = QFileInfo(strArg).fileName();
552 cmdString.sprintf(cmds[cmd].fmt, strArg.toUtf8().constData(), intArg);
554 else
556 cmdString.sprintf(cmds[cmd].fmt, intArg, strArg.toUtf8().constData());
558 return cmdString;
561 QString GdbDriver::makeCmdString(DbgCommand cmd, QString strArg1, QString strArg2)
563 assert(cmd >= 0 && cmd < NUM_CMDS);
564 assert(cmds[cmd].argsNeeded == GdbCmdInfo::argString2);
566 normalizeStringArg(strArg1);
567 normalizeStringArg(strArg2);
569 QString cmdString;
570 cmdString.sprintf(cmds[cmd].fmt,
571 strArg1.toUtf8().constData(),
572 strArg2.toUtf8().constData());
573 return cmdString;
576 QString GdbDriver::makeCmdString(DbgCommand cmd, int intArg1, int intArg2)
578 assert(cmd >= 0 && cmd < NUM_CMDS);
579 assert(cmds[cmd].argsNeeded == GdbCmdInfo::argNum2);
581 QString cmdString;
582 cmdString.sprintf(cmds[cmd].fmt, intArg1, intArg2);
583 return cmdString;
586 QString GdbDriver::makeCmdString(DbgCommand cmd)
588 assert(cmd >= 0 && cmd < NUM_CMDS);
589 assert(cmds[cmd].argsNeeded == GdbCmdInfo::argNone);
591 return cmds[cmd].fmt;
594 void GdbDriver::terminate()
596 if (m_state != DSidle)
598 ::kill(pid(), SIGINT);
599 m_state = DSinterrupted;
601 flushCommands();
602 closeWriteChannel();
605 void GdbDriver::detachAndTerminate()
607 ::kill(pid(), SIGINT);
608 flushCommands();
609 executeCmdString(DCinitialize, "detach\nquit\n", true);
612 void GdbDriver::interruptInferior()
614 ::kill(pid(), SIGINT);
615 // remove accidentally queued commands
616 flushHiPriQueue();
619 static bool isErrorExpr(const char* output)
621 return
622 strncmp(output, "Cannot access memory at", 23) == 0 ||
623 strncmp(output, "Attempt to dereference a generic pointer", 40) == 0 ||
624 strncmp(output, "Attempt to take contents of ", 28) == 0 ||
625 strncmp(output, "Attempt to use a type name as an expression", 43) == 0 ||
626 strncmp(output, "There is no member or method named", 34) == 0 ||
627 strncmp(output, "A parse error in expression", 27) == 0 ||
628 strncmp(output, "No symbol \"", 11) == 0 ||
629 strncmp(output, "Internal error: ", 16) == 0;
632 static void skipSpace(const char*& p)
634 while (isspace(*p))
635 p++;
638 static void skipDecimal(const char*& p)
640 while (isdigit(*p))
641 p++;
645 * Returns true if the output is an error message. If wantErrorValue is
646 * true, a new ExprValue object is created and filled with the error message.
647 * If there are warnings, they are skipped and output points past the warnings
648 * on return (even if there \e are errors).
650 static bool parseErrorMessage(const char*& output,
651 ExprValue*& variable, bool wantErrorValue)
653 skipSpace(output);
655 // skip warnings
656 while (strncmp(output, "warning:", 8) == 0)
658 const char* end = strchr(output+8, '\n');
659 if (end == 0)
660 output += strlen(output);
661 else
662 output = end+1;
663 skipSpace(output);
666 if (isErrorExpr(output))
668 if (wantErrorValue) {
669 // put the error message as value in the variable
670 variable = new ExprValue(QString(), VarTree::NKplain);
671 const char* endMsg = strchr(output, '\n');
672 if (endMsg == 0)
673 endMsg = output + strlen(output);
674 variable->m_value = QString::fromLatin1(output, endMsg-output);
675 } else {
676 variable = 0;
678 return true;
680 return false;
683 #if QT_VERSION >= 300
684 union Qt2QChar {
685 short s;
686 struct {
687 uchar row;
688 uchar cell;
689 } qch;
691 #endif
693 void GdbDriver::setPrintQStringDataCmd(const char* cmd)
695 // don't accept the command if it is empty
696 if (cmd == 0 || *cmd == '\0')
697 return;
698 assert(strlen(cmd) <= MAX_FMTLEN);
699 cmds[DCprintQStringStruct].fmt = cmd;
702 ExprValue* GdbDriver::parseQCharArray(const char* output, bool wantErrorValue, bool qt3like)
704 ExprValue* variable = 0;
707 * Parse off white space. gdb sometimes prints white space first if the
708 * printed array leaded to an error.
710 skipSpace(output);
712 // special case: empty string (0 repetitions)
713 if (strncmp(output, "Invalid number 0 of repetitions", 31) == 0)
715 variable = new ExprValue(QString(), VarTree::NKplain);
716 variable->m_value = "\"\"";
717 return variable;
720 // check for error conditions
721 if (parseErrorMessage(output, variable, wantErrorValue))
722 return variable;
724 // parse the array
726 // find '='
727 const char* p = output;
728 p = strchr(p, '=');
729 if (p == 0) {
730 goto error;
732 p++;
733 skipSpace(p);
735 if (*p == '{')
737 // this is the real data
738 p++; /* skip '{' */
740 // parse the array
741 QString result;
742 QString repeatCount;
743 enum { wasNothing, wasChar, wasRepeat } lastThing = wasNothing;
745 * A matrix for separators between the individual "things"
746 * that are added to the string. The first index is a bool,
747 * the second index is from the enum above.
749 static const char* separator[2][3] = {
750 { "\"", 0, ", \"" }, /* normal char is added */
751 { "'", "\", '", ", '" } /* repeated char is added */
754 while (isdigit(*p)) {
755 // parse a number
756 char* end;
757 unsigned short value = (unsigned short) strtoul(p, &end, 0);
758 if (end == p)
759 goto error; /* huh? no valid digits */
760 // skip separator and search for a repeat count
761 p = end;
762 while (isspace(*p) || *p == ',')
763 p++;
764 bool repeats = strncmp(p, "<repeats ", 9) == 0;
765 if (repeats) {
766 const char* start = p;
767 p = strchr(p+9, '>'); /* search end and advance */
768 if (p == 0)
769 goto error;
770 p++; /* skip '>' */
771 repeatCount = QString::fromLatin1(start, p-start);
772 while (isspace(*p) || *p == ',')
773 p++;
775 // p is now at the next char (or the end)
777 // interpret the value as a QChar
778 // TODO: make cross-architecture compatible
779 QChar ch;
780 if (qt3like) {
781 ch = QChar(value);
782 } else {
783 #if QT_VERSION < 300
784 (unsigned short&)ch = value;
785 #else
786 Qt2QChar c;
787 c.s = value;
788 ch.setRow(c.qch.row);
789 ch.setCell(c.qch.cell);
790 #endif
793 // escape a few frequently used characters
794 char escapeCode = '\0';
795 switch (ch.toLatin1()) {
796 case '\n': escapeCode = 'n'; break;
797 case '\r': escapeCode = 'r'; break;
798 case '\t': escapeCode = 't'; break;
799 case '\b': escapeCode = 'b'; break;
800 case '\"': escapeCode = '\"'; break;
801 case '\\': escapeCode = '\\'; break;
802 case '\0': if (value == 0) { escapeCode = '0'; } break;
805 // add separator
806 result += separator[repeats][lastThing];
807 // add char
808 if (escapeCode != '\0') {
809 result += '\\';
810 ch = escapeCode;
812 result += ch;
814 // fixup repeat count and lastThing
815 if (repeats) {
816 result += "' ";
817 result += repeatCount;
818 lastThing = wasRepeat;
819 } else {
820 lastThing = wasChar;
823 if (*p != '}')
824 goto error;
826 // closing quote
827 if (lastThing == wasChar)
828 result += "\"";
830 // assign the value
831 variable = new ExprValue(QString(), VarTree::NKplain);
832 variable->m_value = result;
834 else if (strncmp(p, "true", 4) == 0)
836 variable = new ExprValue(QString(), VarTree::NKplain);
837 variable->m_value = "QString::null";
839 else if (strncmp(p, "false", 5) == 0)
841 variable = new ExprValue(QString(), VarTree::NKplain);
842 variable->m_value = "(null)";
844 else
845 goto error;
846 return variable;
848 error:
849 if (wantErrorValue) {
850 variable = new ExprValue(QString(), VarTree::NKplain);
851 variable->m_value = "internal parse error";
853 return variable;
856 static ExprValue* parseVar(const char*& s)
858 const char* p = s;
860 skipSpace(p);
862 QString name;
863 VarTree::NameKind kind;
865 * Detect anonymouse struct values: The 'name =' part is missing:
866 * s = { a = 1, { b = 2 }}
867 * Note that this detection works only inside structs when the anonymous
868 * struct is not the first member:
869 * s = {{ a = 1 }, b = 2}
870 * This is misparsed (by parseNested()) because it is mistakenly
871 * interprets the second opening brace as the first element of an array
872 * of structs.
874 if (*p == '{')
876 name = i18n("<anonymous struct or union>");
877 kind = VarTree::NKanonymous;
879 else
881 if (!parseName(p, name, kind)) {
882 return 0;
885 // go for '='
886 skipSpace(p);
887 if (*p != '=') {
888 TRACE("parse error: = not found after " + name);
889 return 0;
891 // skip the '=' and more whitespace
892 p++;
893 skipSpace(p);
896 ExprValue* variable = new ExprValue(name, kind);
898 if (!parseValue(p, variable)) {
899 delete variable;
900 return 0;
902 s = p;
903 return variable;
906 static void skipNested(const char*& s, char opening, char closing)
908 const char* p = s;
910 // parse a nested type
911 int nest = 1;
912 p++;
914 * Search for next matching `closing' char, skipping nested pairs of
915 * `opening' and `closing'.
917 while (*p && nest > 0) {
918 if (*p == opening) {
919 nest++;
920 } else if (*p == closing) {
921 nest--;
923 p++;
925 if (nest != 0) {
926 TRACE(QString().sprintf("parse error: mismatching %c%c at %-20.20s", opening, closing, s));
928 s = p;
932 * This function skips text that is delimited by nested angle bracktes, '<>'.
933 * A complication arises because the delimited text can contain the names of
934 * operator<<, operator>>, operator<, and operator>, which have to be treated
935 * specially so that they do not count towards the nesting of '<>'.
936 * This function assumes that the delimited text does not contain strings.
938 static void skipNestedAngles(const char*& s)
940 const char* p = s;
942 int nest = 1;
943 p++; // skip the initial '<'
944 while (*p && nest > 0)
946 // Below we can check for p-s >= 9 instead of 8 because
947 // *s is '<' and cannot be part of "operator".
948 if (*p == '<')
950 if (p-s >= 9 && strncmp(p-8, "operator", 8) == 0) {
951 if (p[1] == '<')
952 p++;
953 } else {
954 nest++;
957 else if (*p == '>')
959 if (p-s >= 9 && strncmp(p-8, "operator", 8) == 0) {
960 if (p[1] == '>')
961 p++;
962 } else {
963 nest--;
966 p++;
968 if (nest != 0) {
969 TRACE(QString().sprintf("parse error: mismatching <> at %-20.20s", s));
971 s = p;
975 * Find the end of line that is not inside braces
977 static void findEnd(const char*& s)
979 const char* p = s;
980 while (*p && *p!='\n') {
981 while (*p && *p!='\n' && *p!='{')
982 p++;
983 if (*p=='{') {
984 p++;
985 skipNested(p, '{', '}'); p--;
988 s = p;
991 static bool isNumberish(const char ch)
993 return (ch>='0' && ch<='9') || ch=='.' || ch=='x';
996 void skipString(const char*& p)
998 // wchar_t strings begin with L
999 if (*p == 'L')
1000 ++p;
1002 moreStrings:
1003 // opening quote
1004 char quote = *p++;
1005 while (*p != quote) {
1006 if (*p == '\\') {
1007 // skip escaped character
1008 // no special treatment for octal values necessary
1009 p++;
1011 // simply return if no more characters
1012 if (*p == '\0')
1013 return;
1014 p++;
1016 // closing quote
1017 p++;
1019 * Strings can consist of several parts, some of which contain repeated
1020 * characters.
1022 if (quote == '\'') {
1023 // look ahaead for <repeats 123 times>
1024 const char* q = p+1;
1025 skipSpace(q);
1026 if (strncmp(q, "<repeats ", 9) == 0) {
1027 p = q+9;
1028 while (*p != '\0' && *p != '>')
1029 p++;
1030 if (*p != '\0') {
1031 p++; /* skip the '>' */
1035 // Is the string continued? If so, there is no L in wchar_t strings
1036 if (*p == ',')
1038 // look ahead for another quote
1039 const char* q = p+1;
1040 skipSpace(q);
1041 if (*q == '"' || *q == '\'') {
1042 // yes!
1043 p = q;
1044 goto moreStrings;
1047 // some strings can end in <incomplete sequence ...>
1048 if (strncmp(q, "<incomplete sequence", 20) == 0)
1050 p = q+20;
1051 while (*p != '\0' && *p != '>')
1052 p++;
1053 if (*p != '\0') {
1054 p++; /* skip the '>' */
1059 * There's a bug in gdb where it prints the beginning of the string
1060 * continuation and the comma-blank in the wrong order if the new string
1061 * begins with an incomplete multi-byte character. For now, let's check
1062 * for this in a very narrow condition, particularly, where the next
1063 * character is given in octal notation. Example:
1064 * 'a' <repeats 20 times>"\240, b"
1066 if (*p == '"' && p[1] == '\\' && isdigit(p[2])) {
1067 int i = 3;
1068 while (isdigit(p[i]))
1069 ++i;
1070 if (p[i] == ',' && p[i+1] == ' ') {
1071 // just treat everything beginning at the dquote as string
1072 goto moreStrings;
1075 /* very long strings are followed by `...' */
1076 if (*p == '.' && p[1] == '.' && p[2] == '.') {
1077 p += 3;
1081 static void skipNestedWithString(const char*& s, char opening, char closing)
1083 const char* p = s;
1085 // parse a nested expression
1086 int nest = 1;
1087 p++;
1089 * Search for next matching `closing' char, skipping nested pairs of
1090 * `opening' and `closing' as well as strings.
1092 while (*p && nest > 0) {
1093 if (*p == opening) {
1094 nest++;
1095 } else if (*p == closing) {
1096 nest--;
1097 } else if (*p == '\'' || *p == '\"') {
1098 skipString(p);
1099 continue;
1101 p++;
1103 if (nest > 0) {
1104 TRACE(QString().sprintf("parse error: mismatching %c%c at %-20.20s", opening, closing, s));
1106 s = p;
1109 static void skipName(const char*& p)
1111 // allow : (for enumeration values) and $ and . (for _vtbl.)
1112 while (isalnum(*p) || *p == '_' || *p == ':' || *p == '$' || *p == '.')
1113 p++;
1116 static void skipFunctionName(const char*& p)
1118 while (*p)
1120 if (*p == '<') {
1121 // skip template parameter list
1122 skipNestedAngles(p);
1123 } else if (*p == '(') {
1124 // this skips "(anonymous namespace)" as well as the formal
1125 // parameter list of the containing function if this is a member
1126 // of a nested class
1127 skipNestedWithString(p, '(', ')');
1128 } else if (isalnum(*p) || *p == '_' || *p == ':') {
1129 const char* start = p;
1130 skipName(p);
1131 // check for operator
1132 if (p-start >= 8 &&
1133 strncmp(p-8, "operator", 8) == 0 &&
1134 // do not mistake this as the tail of some identifier
1135 (p-start == 8 || !(isalnum(p[-9]) || p[-9] == '_')))
1137 // skip forward until we find the opening parenthesis
1138 // this catches both operator()(...) as well as
1139 // type conversion operators, e.g.
1140 // operator char const*() const
1141 // operator void(*)()
1142 while (*p && *p != '(')
1143 p++;
1145 } else if (strncmp(p, " const", 6) == 0 &&
1146 // must not mistake "const" as the beginning of
1147 // a subequent identifier
1148 !isalnum(p[6]) && p[6] != '_') {
1149 p += 6;
1150 } else {
1151 break;
1156 static bool parseName(const char*& s, QString& name, VarTree::NameKind& kind)
1158 kind = VarTree::NKplain;
1160 const char* p = s;
1161 // examples of names:
1162 // name
1163 // <Object>
1164 // <string<a,b<c>,7> >
1166 if (*p == '<') {
1167 skipNestedAngles(p);
1168 name = QString::fromLatin1(s, p - s);
1169 kind = VarTree::NKtype;
1171 else
1173 // name, which might be "static"; allow dot for "_vtbl."
1174 skipName(p);
1175 if (p == s) {
1176 TRACE(QString().sprintf("parse error: not a name %-20.20s", s));
1177 return false;
1179 int len = p - s;
1180 if (len == 6 && strncmp(s, "static", 6) == 0) {
1181 kind = VarTree::NKstatic;
1183 // its a static variable, name comes now
1184 skipSpace(p);
1185 s = p;
1186 skipName(p);
1187 if (p == s) {
1188 TRACE(QString().sprintf("parse error: not a name after static %-20.20s", s));
1189 return false;
1191 len = p - s;
1193 name = QString::fromLatin1(s, len);
1195 // return the new position
1196 s = p;
1197 return true;
1200 static bool parseValue(const char*& s, ExprValue* variable)
1202 variable->m_value = "";
1204 repeat:
1205 if (*s == '{') {
1206 // Sometimes we find the following output:
1207 // {<text variable, no debug info>} 0x40012000 <access>
1208 // {<data variable, no debug info>}
1209 // {<variable (not text or data), no debug info>}
1210 if (strncmp(s, "{<text variable, ", 17) == 0 ||
1211 strncmp(s, "{<data variable, ", 17) == 0 ||
1212 strncmp(s, "{<variable (not text or data), ", 31) == 0)
1214 const char* start = s;
1215 skipNested(s, '{', '}');
1216 variable->m_value = QString::fromLatin1(start, s-start);
1217 variable->m_value += ' '; // add only a single space
1218 skipSpace(s);
1219 goto repeat;
1221 else
1223 s++;
1224 if (!parseNested(s, variable)) {
1225 return false;
1227 // must be the closing brace
1228 if (*s != '}') {
1229 TRACE("parse error: missing } of " + variable->m_name);
1230 return false;
1232 s++;
1233 // final white space
1234 skipSpace(s);
1237 // Sometimes we find a warning; it ends at the next LF
1238 else if (strncmp(s, "warning: ", 9) == 0) {
1239 const char* end = strchr(s, '\n');
1240 s = end ? end : s+strlen(s);
1241 // skip space at start of next line
1242 skipSpace(s);
1243 goto repeat;
1244 } else {
1245 // examples of leaf values (cannot be the empty string):
1246 // 123
1247 // -123
1248 // 23.575e+37
1249 // 0x32a45
1250 // @0x012ab4
1251 // (DwContentType&) @0x8123456: {...}
1252 // 0x32a45 "text"
1253 // 10 '\n'
1254 // <optimized out>
1255 // 0x823abc <Array<int> virtual table>
1256 // 0x40240f <globarstr> "test"
1257 // (void (*)()) 0x8048480 <f(E *, char)>
1258 // (E *) 0xbffff450
1259 // red
1260 // &parseP (HTMLClueV *, char *)
1261 // &virtual table offset 0, this adjustment 140737488346016
1262 // &virtual Dl::operator char const*() const
1263 // Variable "x" is not available.
1264 // The value of variable 'x' is distributed...
1265 // -nan(0xfffff081defa0)
1266 // @0x100400f08: <error reading variable>
1267 // (void (Templated<double>::*)(Templated<double> * const)) 0x400d74 <MostDerived::PrintV()>, this adjustment -16
1269 const char*p = s;
1271 // check for type
1272 QString type;
1273 if (*p == '(') {
1274 skipNested(p, '(', ')');
1276 skipSpace(p);
1277 variable->m_value = QString::fromLatin1(s, p - s);
1280 bool reference = false;
1281 if (*p == '@') {
1282 // skip reference marker
1283 p++;
1284 reference = true;
1286 const char* start = p;
1287 if (*p == '-')
1288 p++;
1290 // some values consist of more than one token
1291 bool checkMultiPart = false;
1293 if (p[0] == '0' && p[1] == 'x') {
1294 // parse hex number
1295 p += 2;
1296 while (isxdigit(*p))
1297 p++;
1300 * Assume this is a pointer, but only if it's not a reference, since
1301 * references can't be expanded.
1303 if (!reference) {
1304 variable->m_varKind = VarTree::VKpointer;
1305 } else {
1307 * References are followed by a colon, in which case we'll
1308 * find the value following the reference address.
1310 if (*p == ':') {
1311 p++;
1312 } else {
1313 // Paranoia. (Can this happen, i.e. reference not followed by ':'?)
1314 reference = false;
1317 checkMultiPart = true;
1318 } else if (isdigit(*p)) {
1319 // parse decimal number, possibly a float
1320 skipDecimal(p);
1321 if (*p == '.') { /* TODO: obey i18n? */
1322 // In long arrays an integer may be followed by '...'.
1323 // We test for this situation and don't gobble the '...'.
1324 if (p[1] != '.' || p[0] != '.') {
1325 // fractional part
1326 p++;
1327 skipDecimal(p);
1330 if (*p == 'e' || *p == 'E') {
1331 p++;
1332 // exponent
1333 if (*p == '-' || *p == '+')
1334 p++;
1335 skipDecimal(p);
1338 // for char variables there is the char, eg. 10 '\n'
1339 checkMultiPart = true;
1340 } else if (*p == '<') {
1341 // e.g. <optimized out>
1342 skipNestedAngles(p);
1343 } else if (*p == '"' || *p == '\'') {
1344 // character may have multipart: '\000' <repeats 11 times>
1345 checkMultiPart = *p == '\'';
1346 // found a string
1347 skipString(p);
1348 } else if (*p == 'L' && (p[1] == '"' || p[1] == '\'')) {
1349 // ditto for wchar_t strings
1350 checkMultiPart = p[1] == '\'';
1351 skipString(p);
1352 } else if (*p == '&') {
1353 p++;
1354 if (strncmp(p, "virtual ", 8) == 0) {
1355 p += 8;
1356 if (strncmp(p, "table offset ", 13) == 0) {
1357 p += 13;
1358 skipDecimal(p);
1359 checkMultiPart = true;
1360 } else {
1361 skipFunctionName(p);
1363 } else {
1364 // function pointer
1365 skipName(p);
1366 skipSpace(p);
1367 if (*p == '(') {
1368 skipNested(p, '(', ')');
1371 } else if (strncmp(p, "Variable \"", 10) == 0) {
1372 // Variable "x" is not available.
1373 p += 10; // skip to "
1374 skipName(p);
1375 if (strncmp(p, "\" is not available.", 19) == 0) {
1376 p += 19;
1378 } else if (strncmp(p, "The value of variable '", 23) == 0) {
1379 p += 23;
1380 skipName(p);
1381 const char* e = strchr(p, '.');
1382 if (e == 0) {
1383 p += strlen(p);
1384 } else {
1385 p = e+1;
1387 } else {
1388 moreEnum:
1389 // must be an enumeration value
1390 skipName(p);
1391 // nan (floating point Not a Number) is followed by a number in ()
1392 // enum values can look like A::(anonymous namespace)::blue
1393 if (*p == '(') {
1394 bool isAnonNS = strncmp(p+1, "anonymous namespace)", 20) == 0;
1395 skipNested(p, '(', ')');
1396 if (isAnonNS)
1397 goto moreEnum;
1400 variable->m_value += QString::fromLatin1(start, p - start);
1402 // remove line breaks from the value; this is ok since
1403 // string values never contain a literal line break
1404 variable->m_value.replace('\n', ' ');
1406 while (checkMultiPart) {
1407 // white space
1408 skipSpace(p);
1409 // may be followed by a string or <...>
1410 // if this was a pointer with a string,
1411 // reset that pointer flag since we have now a value
1412 start = p;
1413 checkMultiPart = false;
1415 if (*p == '"' || *p == '\'') {
1416 skipString(p);
1417 variable->m_varKind = VarTree::VKsimple;
1418 } else if (*p == 'L' && (p[1] == '"' || p[1] == '\'')) {
1419 skipString(p); // wchar_t string
1420 variable->m_varKind = VarTree::VKsimple;
1421 } else if (*p == '<') {
1422 // if this value is part of an array, it might be followed
1423 // by <repeats 15 times>, which we don't skip here
1424 if (strncmp(p, "<repeats ", 9) == 0)
1426 // sometimes, a reference is followed by an error message:
1427 // @0x100400f08: <error reading variable>
1428 // in this case, we do not skip the text here, but leave it
1429 // for the subsequent parsing pass induced by the reference
1430 else if (reference && strncmp(p, "<error reading", 14) == 0)
1432 else {
1433 skipNestedAngles(p);
1434 checkMultiPart = true;
1436 } else if (strncmp(p, ", this adjustment ", 18) == 0) {
1437 // pointers-to-member are sometimes followed by
1438 // a "this adjustment" hint
1439 p += 18;
1440 if (*p == '-')
1441 p++;
1442 skipDecimal(p);
1443 // we know that this is not a dereferencable pointer
1444 variable->m_varKind = VarTree::VKsimple;
1445 ++start; // skip ',', will be picked up below
1447 if (p != start) {
1448 // there is always a blank before the string,
1449 // which we will include in the final string value
1450 variable->m_value += QString::fromLatin1(start-1, (p - start)+1);
1454 if (variable->m_value.length() == 0) {
1455 TRACE("parse error: no value for " + variable->m_name);
1456 return false;
1459 // final white space
1460 skipSpace(p);
1461 s = p;
1464 * If this was a reference, the value follows. It might even be a
1465 * composite variable!
1467 if (reference) {
1468 goto repeat;
1472 return true;
1475 static bool parseNested(const char*& s, ExprValue* variable)
1477 // could be a structure or an array
1478 skipSpace(s);
1480 const char* p = s;
1481 bool isStruct = false;
1483 * If there is a name followed by an = or an < -- which starts a type
1484 * name -- or "static", it is a structure
1486 if (*p == '<' || *p == '}') {
1487 isStruct = true;
1488 } else if (strncmp(p, "static ", 7) == 0) {
1489 isStruct = true;
1490 } else if (isalpha(*p) || *p == '_' || *p == '$') {
1491 // look ahead for a comma after the name
1492 skipName(p);
1493 skipSpace(p);
1494 if (*p == '=') {
1495 isStruct = true;
1497 p = s; /* rescan the name */
1499 if (isStruct) {
1500 if (!parseVarSeq(p, variable)) {
1501 return false;
1503 variable->m_varKind = VarTree::VKstruct;
1504 } else {
1505 if (!parseValueSeq(p, variable)) {
1506 return false;
1508 variable->m_varKind = VarTree::VKarray;
1510 s = p;
1511 return true;
1514 static bool parseVarSeq(const char*& s, ExprValue* variable)
1516 // parse a comma-separated sequence of variables
1517 ExprValue* var = variable; /* var != 0 to indicate success if empty seq */
1518 for (;;) {
1519 if (*s == '}')
1520 break;
1521 if (strncmp(s, "<No data fields>}", 17) == 0)
1523 // no member variables, so break out immediately
1524 s += 16; /* go to the closing brace */
1525 break;
1527 var = parseVar(s);
1528 if (var == 0)
1529 break; /* syntax error */
1530 variable->appendChild(var);
1531 if (*s != ',')
1532 break;
1533 // skip the comma and whitespace
1534 s++;
1535 skipSpace(s);
1537 return var != 0;
1540 static bool parseValueSeq(const char*& s, ExprValue* variable)
1542 // parse a comma-separated sequence of variables
1543 int index = 0;
1544 bool good;
1545 for (;;) {
1546 QString name;
1547 name.sprintf("[%d]", index);
1548 ExprValue* var = new ExprValue(name, VarTree::NKplain);
1549 good = parseValue(s, var);
1550 if (!good) {
1551 delete var;
1552 return false;
1554 // a value may be followed by "<repeats 45 times>"
1555 if (strncmp(s, "<repeats ", 9) == 0) {
1556 s += 9;
1557 char* end;
1558 int l = strtol(s, &end, 10);
1559 if (end == s || strncmp(end, " times>", 7) != 0) {
1560 // should not happen
1561 delete var;
1562 return false;
1564 TRACE(QString().sprintf("found <repeats %d times> in array", l));
1565 // replace name and advance index
1566 name.sprintf("[%d .. %d]", index, index+l-1);
1567 var->m_name = name;
1568 index += l;
1569 // skip " times>" and space
1570 s = end+7;
1571 // possible final space
1572 skipSpace(s);
1573 } else {
1574 index++;
1576 variable->appendChild(var);
1577 // long arrays may be terminated by '...'
1578 if (strncmp(s, "...", 3) == 0) {
1579 s += 3;
1580 ExprValue* var = new ExprValue("...", VarTree::NKplain);
1581 var->m_value = i18n("<additional entries of the array suppressed>");
1582 variable->appendChild(var);
1583 break;
1585 if (*s != ',') {
1586 break;
1588 // skip the comma and whitespace
1589 s++;
1590 skipSpace(s);
1591 // sometimes there is a closing brace after a comma
1592 // if (*s == '}')
1593 // break;
1595 return true;
1599 * Parses a stack frame.
1601 static void parseFrameInfo(const char*& s, QString& func,
1602 QString& file, int& lineNo, DbgAddr& address)
1604 const char* p = s;
1606 // next may be a hexadecimal address
1607 if (*p == '0') {
1608 const char* start = p;
1609 p++;
1610 if (*p == 'x')
1611 p++;
1612 while (isxdigit(*p))
1613 p++;
1614 address = QString::fromLatin1(start, p-start);
1615 if (strncmp(p, " in ", 4) == 0)
1616 p += 4;
1617 } else {
1618 address = DbgAddr();
1620 const char* start = p;
1621 // check for special signal handler frame
1622 if (strncmp(p, "<signal handler called>", 23) == 0) {
1623 func = QString::fromLatin1(start, 23);
1624 file = QString();
1625 lineNo = -1;
1626 s = p+23;
1627 if (*s == '\n')
1628 s++;
1629 return;
1633 * Skip the function name. It is terminated by a left parenthesis
1634 * which does not delimit "(anonymous namespace)" and which is
1635 * outside the angle brackets <> of template parameter lists
1636 * and is preceded by a space.
1638 while (*p != '\0')
1640 if (*p == '<') {
1641 // check for operator<< and operator<
1642 if (p-start >= 8 && strncmp(p-8, "operator", 8) == 0)
1644 p++;
1645 if (*p == '<')
1646 p++;
1648 else
1650 // skip template parameter list
1651 skipNestedAngles(p);
1653 } else if (*p == '(') {
1654 // this skips "(anonymous namespace)" as well as the formal
1655 // parameter list of the containing function if this is a member
1656 // of a nested class
1657 skipNestedWithString(p, '(', ')');
1658 } else if (*p == ' ') {
1659 ++p;
1660 if (*p == '(')
1661 break; // parameter list found
1662 } else {
1663 p++;
1667 if (*p == '\0') {
1668 func = start;
1669 file = QString();
1670 lineNo = -1;
1671 s = p;
1672 return;
1675 * Skip parameters. But notice that for complicated conversion
1676 * functions (eg. "operator int(**)()()", ie. convert to pointer to
1677 * pointer to function) as well as operator()(...) we have to skip
1678 * additional pairs of parentheses. Furthermore, recent gdbs write the
1679 * demangled name followed by the arguments in a pair of parentheses,
1680 * where the demangled name can end in "const".
1682 do {
1683 skipNestedWithString(p, '(', ')');
1684 skipSpace(p);
1685 // skip "const"
1686 if (strncmp(p, "const", 5) == 0) {
1687 p += 5;
1688 skipSpace(p);
1690 } while (*p == '(');
1692 // check for file position
1693 if (strncmp(p, "at ", 3) == 0) {
1694 p += 3;
1695 const char* fileStart = p;
1696 // go for the end of the line
1697 while (*p != '\0' && *p != '\n')
1698 p++;
1699 // search back for colon
1700 const char* colon = p;
1701 do {
1702 --colon;
1703 } while (*colon != ':');
1704 file = QString::fromLatin1(fileStart, colon-fileStart);
1705 lineNo = atoi(colon+1)-1;
1706 // skip new-line
1707 if (*p != '\0')
1708 p++;
1709 } else {
1710 // check for "from shared lib"
1711 if (strncmp(p, "from ", 5) == 0) {
1712 p += 5;
1713 // go for the end of the line
1714 while (*p != '\0' && *p != '\n')
1715 p++;
1716 // skip new-line
1717 if (*p != '\0')
1718 p++;
1720 file = "";
1721 lineNo = -1;
1723 // construct the function name (including file info)
1724 if (*p == '\0') {
1725 func = start;
1726 } else {
1727 func = QString::fromLatin1(start, p-start-1); /* don't include \n */
1729 s = p;
1732 * Replace \n (and whitespace around it) in func by a blank. We cannot
1733 * use QString::simplified() for this because this would also
1734 * simplify space that belongs to a string arguments that gdb sometimes
1735 * prints in the argument lists of the function.
1737 ASSERT(!isspace(func[0].toLatin1())); // there must be non-white before first \n
1738 int nl = 0;
1739 while ((nl = func.indexOf('\n', nl)) >= 0) {
1740 // search back to the beginning of the whitespace
1741 int startWhite = nl;
1742 do {
1743 --startWhite;
1744 } while (isspace(func[startWhite].toLatin1()));
1745 startWhite++;
1746 // search forward to the end of the whitespace
1747 do {
1748 nl++;
1749 } while (isspace(func[nl].toLatin1()));
1750 // replace
1751 func.replace(startWhite, nl-startWhite, " ");
1752 /* continue searching for more \n's at this place: */
1753 nl = startWhite+1;
1759 * Parses a stack frame including its frame number
1761 static bool parseFrame(const char*& s, int& frameNo, QString& func,
1762 QString& file, int& lineNo, DbgAddr& address)
1764 // Example:
1765 // #1 0x8048881 in Dl::Dl (this=0xbffff418, r=3214) at testfile.cpp:72
1766 // Breakpoint 3, Cl::f(int) const (this=0xbffff3c0, x=17) at testfile.cpp:155
1768 // must start with a hash mark followed by number
1769 // or with "Breakpoint " followed by number and comma
1770 if (s[0] == '#') {
1771 if (!isdigit(s[1]))
1772 return false;
1773 s++; /* skip the hash mark */
1774 } else if (strncmp(s, "Breakpoint ", 11) == 0) {
1775 if (!isdigit(s[11]))
1776 return false;
1777 s += 11; /* skip "Breakpoint" */
1778 } else
1779 return false;
1781 // frame number
1782 frameNo = atoi(s);
1783 skipDecimal(s);
1784 // space and comma
1785 while (isspace(*s) || *s == ',')
1786 s++;
1787 parseFrameInfo(s, func, file, lineNo, address);
1788 return true;
1791 void GdbDriver::parseBackTrace(const char* output, std::list<StackFrame>& stack)
1793 QString func, file;
1794 int lineNo, frameNo;
1795 DbgAddr address;
1797 while (::parseFrame(output, frameNo, func, file, lineNo, address)) {
1798 stack.push_back(StackFrame());
1799 StackFrame* frm = &stack.back();
1800 frm->frameNo = frameNo;
1801 frm->fileName = file;
1802 frm->lineNo = lineNo;
1803 frm->address = address;
1804 frm->var = new ExprValue(func, VarTree::NKplain);
1808 bool GdbDriver::parseFrameChange(const char* output, int& frameNo,
1809 QString& file, int& lineNo, DbgAddr& address)
1811 QString func;
1812 return ::parseFrame(output, frameNo, func, file, lineNo, address);
1816 bool GdbDriver::parseBreakList(const char* output, std::list<Breakpoint>& brks)
1818 // skip first line, which is the headline
1819 const char* p = strchr(output, '\n');
1820 if (p == 0)
1821 return false;
1822 p++;
1823 if (*p == '\0')
1824 return false;
1826 // split up a line
1827 const char* end;
1828 char* dummy;
1829 while (*p != '\0') {
1830 Breakpoint bp;
1831 // get Num
1832 bp.id = strtol(p, &dummy, 10); /* don't care about overflows */
1833 p = dummy;
1834 // check for continued <MULTIPLE> breakpoint
1835 if (*p == '.' && isdigit(p[1]))
1837 // continuation: skip type and disposition
1839 else
1841 // get Type
1842 skipSpace(p);
1843 if (strncmp(p, "breakpoint", 10) == 0) {
1844 p += 10;
1845 } else if (strncmp(p, "hw watchpoint", 13) == 0) {
1846 bp.type = Breakpoint::watchpoint;
1847 p += 13;
1848 } else if (strncmp(p, "watchpoint", 10) == 0) {
1849 bp.type = Breakpoint::watchpoint;
1850 p += 10;
1852 skipSpace(p);
1853 if (*p == '\0')
1854 break;
1855 // get Disp
1856 bp.temporary = *p++ == 'd';
1858 while (*p != '\0' && !isspace(*p)) /* "keep" or "del" */
1859 p++;
1860 skipSpace(p);
1861 if (*p == '\0')
1862 break;
1863 // get Enb
1864 bp.enabled = *p++ == 'y';
1865 while (*p != '\0' && !isspace(*p)) /* "y" or "n" */
1866 p++;
1867 skipSpace(p);
1868 if (*p == '\0')
1869 break;
1870 // the address, if present
1871 if (bp.type == Breakpoint::breakpoint &&
1872 strncmp(p, "0x", 2) == 0)
1874 const char* start = p;
1875 while (*p != '\0' && !isspace(*p))
1876 p++;
1877 bp.address = QString::fromLatin1(start, p-start);
1878 while (isspace(*p) && *p != '\n')
1879 p++;
1880 if (*p == '\0')
1881 break;
1883 // remainder is location, hit and ignore count, condition
1884 end = strchr(p, '\n');
1885 if (end == 0) {
1886 bp.location = p;
1887 p += bp.location.length();
1888 } else {
1889 // location of a <MULTIPLE> filled in from subsequent breakpoints
1890 if (strncmp(p, "<MULTIPLE>", 10) != 0)
1891 bp.location = QString::fromLatin1(p, end-p).trimmed();
1892 p = end+1; /* skip over \n */
1895 // may be continued in next line
1896 while (isspace(*p)) { /* p points to beginning of line */
1897 // skip white space at beginning of line
1898 skipSpace(p);
1900 // seek end of line
1901 end = strchr(p, '\n');
1902 if (end == 0)
1903 end = p+strlen(p);
1905 if (strncmp(p, "breakpoint already hit", 22) == 0) {
1906 // extract the hit count
1907 p += 22;
1908 bp.hitCount = strtol(p, &dummy, 10);
1909 TRACE(QString("hit count %1").arg(bp.hitCount));
1910 } else if (strncmp(p, "stop only if ", 13) == 0) {
1911 // extract condition
1912 p += 13;
1913 bp.condition = QString::fromLatin1(p, end-p).trimmed();
1914 TRACE("condition: "+bp.condition);
1915 } else if (strncmp(p, "ignore next ", 12) == 0) {
1916 // extract ignore count
1917 p += 12;
1918 bp.ignoreCount = strtol(p, &dummy, 10);
1919 TRACE(QString("ignore count %1").arg(bp.ignoreCount));
1920 } else {
1921 // indeed a continuation
1922 bp.location += " " + QString::fromLatin1(p, end-p).trimmed();
1924 p = end;
1925 if (*p != '\0')
1926 p++; /* skip '\n' */
1929 if (brks.empty() || brks.back().id != bp.id) {
1930 brks.push_back(bp);
1931 } else {
1932 // this is a continuation; fill in location if not yet set
1933 // otherwise, drop this breakpoint
1934 Breakpoint& mbp = brks.back();
1935 if (mbp.location.isEmpty() && !bp.location.isEmpty()) {
1936 mbp.location = bp.location;
1937 mbp.address = bp.address;
1938 } else if (mbp.address.isEmpty() && !bp.address.isEmpty()) {
1939 mbp.address = bp.address;
1943 return true;
1946 std::list<ThreadInfo> GdbDriver::parseThreadList(const char* output)
1948 std::list<ThreadInfo> threads;
1949 if (strcmp(output, "\n") == 0 ||
1950 strncmp(output, "No stack.", 9) == 0 ||
1951 strncmp(output, "No threads.", 11) == 0) {
1952 // no threads
1953 return threads;
1956 bool newFormat = false;
1957 const char* p = output;
1958 while (*p != '\0') {
1959 ThreadInfo thr;
1960 // seach look for thread id, watching out for the focus indicator
1961 thr.hasFocus = false;
1962 skipSpace(p); /* may be \n from prev line: see "No stack" below */
1964 // recent GDBs write a header line; skip it
1965 if (threads.empty() && strncmp(p, "Id Target", 11) == 0) {
1966 p = strchr(p, '\n');
1967 if (p == NULL)
1968 break;
1969 newFormat = true;
1970 continue; // next line please, '\n' is skipped above
1973 if (*p == '*') {
1974 thr.hasFocus = true;
1975 p++;
1976 // there follows only whitespace
1978 const char* end;
1979 char *temp_end = NULL; /* we need a non-const 'end' for strtol to use...*/
1980 thr.id = strtol(p, &temp_end, 10);
1981 end = temp_end;
1982 if (p == end) {
1983 // syntax error: no number found; bail out
1984 return threads;
1986 p = end;
1988 skipSpace(p);
1991 * Now follows the thread's SYSTAG.
1993 if (!newFormat) {
1994 // In the old format, it is terminated by two blanks.
1995 end = strstr(p, " ");
1996 if (end == 0) {
1997 // syntax error; bail out
1998 return threads;
2000 end += 2;
2001 } else {
2002 // In the new format lies crazyness: there is no definitive
2003 // end marker. At best we can guess when the SYSTAG ends.
2004 // A typical thread list on Linux looks like this:
2006 // Id Target Id Frame
2007 // 2 Thread 0x7ffff7854700 (LWP 10827) "thrserver" 0x00007ffff7928631 in clone () from /lib64/libc.so.6
2008 // * 1 Thread 0x7ffff7fcc700 (LWP 10808) "thrserver" main () at thrserver.c:84
2010 // Looking at GDB's code, the Target Id ends in tokens that
2011 // are bracketed by parentheses or quotes. Therefore,
2012 // we skip (at most) two tokens ('Thread' and the address),
2013 // and then all parts that are in parentheses or quotes.
2014 int n = 0;
2015 end = p;
2016 while (*end) {
2017 if (*end == '"') {
2018 skipString(end);
2019 n = 2;
2020 } else if (*end == '(') {
2021 skipNested(end, '(', ')');
2022 n = 2;
2023 } else if (n < 2) {
2024 while (*end && !isspace(*end))
2025 ++end;
2026 ++n;
2027 } else {
2028 break;
2030 skipSpace(end);
2033 thr.threadName = QString::fromLatin1(p, end-p).trimmed();
2034 p = end;
2037 * Now follows a standard stack frame. Sometimes, however, gdb
2038 * catches a thread at an instant where it doesn't have a stack.
2040 if (strncmp(p, "[No stack.]", 11) != 0) {
2041 ::parseFrameInfo(p, thr.function, thr.fileName, thr.lineNo, thr.address);
2042 } else {
2043 thr.function = "[No stack]";
2044 thr.lineNo = -1;
2045 p += 11; /* \n is skipped above */
2048 threads.push_back(thr);
2050 return threads;
2053 static bool parseNewBreakpoint(const char* o, int& id,
2054 QString& file, int& lineNo, QString& address);
2055 static bool parseNewWatchpoint(const char* o, int& id,
2056 QString& expr);
2058 bool GdbDriver::parseBreakpoint(const char* output, int& id,
2059 QString& file, int& lineNo, QString& address)
2061 // skip lines of that begin with "(Cannot find"
2062 while (strncmp(output, "(Cannot find", 12) == 0 ||
2063 strncmp(output, "Note: breakpoint", 16) == 0)
2065 output = strchr(output, '\n');
2066 if (output == 0)
2067 return false;
2068 output++; /* skip newline */
2071 if (strncmp(output, "Breakpoint ", 11) == 0) {
2072 output += 11; /* skip "Breakpoint " */
2073 return ::parseNewBreakpoint(output, id, file, lineNo, address);
2074 } else if (strncmp(output, "Temporary breakpoint ", 21) == 0) {
2075 output += 21;
2076 return ::parseNewBreakpoint(output, id, file, lineNo, address);
2077 } else if (strncmp(output, "Hardware watchpoint ", 20) == 0) {
2078 output += 20;
2079 return ::parseNewWatchpoint(output, id, address);
2080 } else if (strncmp(output, "Watchpoint ", 11) == 0) {
2081 output += 11;
2082 return ::parseNewWatchpoint(output, id, address);
2084 return false;
2087 static bool parseNewBreakpoint(const char* o, int& id,
2088 QString& file, int& lineNo, QString& address)
2090 // breakpoint id
2091 char* p;
2092 id = strtoul(o, &p, 10);
2093 if (p == o)
2094 return false;
2096 // check for the address
2097 if (strncmp(p, " at 0x", 6) == 0) {
2098 char* start = p+4; /* skip " at ", but not 0x */
2099 p += 6;
2100 while (isxdigit(*p))
2101 ++p;
2102 address = QString::fromLatin1(start, p-start);
2106 * Mostly, GDB responds with this syntax:
2108 * Breakpoint 1 at 0x400b94: file multibrkpt.cpp, line 9. (2 locations)
2110 * but sometimes it uses this syntax:
2112 * Breakpoint 4 at 0x804f158: lotto739.cpp:95. (3 locations)
2114 const char* fileEnd, *numStart = 0;
2115 const char* fileStart = strstr(p, "file ");
2116 if (fileStart != 0)
2118 fileStart += 5;
2119 fileEnd = strstr(fileStart, ", line ");
2120 if (fileEnd != 0)
2121 numStart = fileEnd + 7;
2123 if (numStart == 0 && p[0] == ':' && p[1] == ' ')
2125 fileStart = p+2;
2126 skipSpace(fileStart);
2127 fileEnd = strchr(fileStart, ':');
2128 if (fileEnd != 0)
2129 numStart = fileEnd + 1;
2131 if (numStart == 0)
2132 return !address.isEmpty(); /* parse error only if there's no address */
2134 QString fileName = QString::fromLatin1(fileStart, fileEnd-fileStart);
2135 int line = strtoul(numStart, &p, 10);
2136 if (numStart == p)
2137 return false;
2139 file = fileName;
2140 lineNo = line-1; /* zero-based! */
2141 return true;
2144 static bool parseNewWatchpoint(const char* o, int& id,
2145 QString& expr)
2147 // watchpoint id
2148 char* p;
2149 id = strtoul(o, &p, 10);
2150 if (p == o)
2151 return false;
2153 if (strncmp(p, ": ", 2) != 0)
2154 return false;
2155 p += 2;
2157 // all the rest on the line is the expression
2158 expr = QString::fromLatin1(p, strlen(p)).trimmed();
2159 return true;
2162 void GdbDriver::parseLocals(const char* output, std::list<ExprValue*>& newVars)
2164 // check for possible error conditions
2165 if (strncmp(output, "No symbol table", 15) == 0)
2167 return;
2170 while (*output != '\0') {
2171 skipSpace(output);
2172 if (*output == '\0')
2173 break;
2174 // skip occurrences of "No locals" and "No args"
2175 if (strncmp(output, "No locals", 9) == 0 ||
2176 strncmp(output, "No arguments", 12) == 0)
2178 output = strchr(output, '\n');
2179 if (output == 0) {
2180 break;
2182 continue;
2185 ExprValue* variable = parseVar(output);
2186 if (variable == 0) {
2187 break;
2189 // do not add duplicates
2190 for (std::list<ExprValue*>::iterator o = newVars.begin(); o != newVars.end(); ++o) {
2191 if ((*o)->m_name == variable->m_name) {
2192 delete variable;
2193 goto skipDuplicate;
2196 newVars.push_back(variable);
2197 skipDuplicate:;
2201 ExprValue* GdbDriver::parsePrintExpr(const char* output, bool wantErrorValue)
2203 ExprValue* var = 0;
2204 // check for error conditions
2205 if (!parseErrorMessage(output, var, wantErrorValue))
2207 // parse the variable
2208 var = parseVar(output);
2210 return var;
2213 bool GdbDriver::parseChangeWD(const char* output, QString& message)
2215 bool isGood = false;
2216 message = QString(output).simplified();
2217 if (message.isEmpty()) {
2218 message = i18n("New working directory: ") + m_programWD;
2219 isGood = true;
2221 return isGood;
2224 bool GdbDriver::parseChangeExecutable(const char* output, QString& message)
2226 message = output;
2229 * Lines starting with the following do not indicate errors:
2230 * Using host libthread_db
2231 * (no debugging symbols found)
2232 * Reading symbols from
2234 while (strncmp(output, "Reading symbols from", 20) == 0 ||
2235 strncmp(output, "done.", 5) == 0 ||
2236 strncmp(output, "Missing separate debuginfo", 26) == 0 ||
2237 strncmp(output, "Try: ", 5) == 0 ||
2238 strncmp(output, "Using host libthread_db", 23) == 0 ||
2239 strncmp(output, "(no debugging symbols found)", 28) == 0)
2241 // this line is good, go to the next one
2242 const char* end = strchr(output, '\n');
2243 if (end == 0)
2244 output += strlen(output);
2245 else
2246 output = end+1;
2250 * If we've parsed all lines, there was no error.
2252 return output[0] == '\0';
2255 bool GdbDriver::parseCoreFile(const char* output)
2257 // if command succeeded, gdb emits a line starting with "#0 "
2258 return strstr(output, "\n#0 ") != 0;
2261 uint GdbDriver::parseProgramStopped(const char* output, bool haveCoreFile,
2262 QString& message)
2264 // optionally: "program changed, rereading symbols",
2265 // followed by:
2266 // "Program exited normally"
2267 // "Program terminated with wignal SIGSEGV"
2268 // "Program received signal SIGINT" or other signal
2269 // "Breakpoint..."
2270 // GDB since 7.3 prints
2271 // "[Inferior 1 (process 13400) exited normally]"
2272 // "[Inferior 1 (process 14698) exited with code 01]"
2274 // go through the output, line by line, checking what we have
2275 const char* start = output - 1;
2276 uint flags = SFprogramActive;
2277 message = QString();
2278 do {
2279 start++; /* skip '\n' */
2281 if (strncmp(start, "Program ", 8) == 0 ||
2282 strncmp(start, "ptrace: ", 8) == 0) {
2284 * When we receive a signal, the program remains active.
2286 * Special: If we "stopped" in a corefile, the string "Program
2287 * terminated with signal"... is displayed. (Normally, we see
2288 * "Program received signal"... when a signal happens.)
2290 if (strncmp(start, "Program exited", 14) == 0 ||
2291 (strncmp(start, "Program terminated", 18) == 0 && !haveCoreFile) ||
2292 strncmp(start, "ptrace: ", 8) == 0)
2294 flags &= ~SFprogramActive;
2297 // set message
2298 const char* endOfMessage = strchr(start, '\n');
2299 if (endOfMessage == 0)
2300 endOfMessage = start + strlen(start);
2301 message = QString::fromLatin1(start, endOfMessage-start);
2302 } else if (strncmp(start, "[Inferior ", 10) == 0) {
2303 const char* p = start + 10;
2304 // skip number and space
2305 while (*p && !isspace(*p))
2306 ++p;
2307 skipSpace(p);
2308 if (*p == '(') {
2309 skipNested(p, '(', ')');
2310 if (strncmp(p, " exited ", 8) == 0) {
2311 flags &= ~SFprogramActive;
2313 // set message
2314 const char* end = strchr(p, '\n');
2315 if (end == 0)
2316 end = p + strlen(p);
2317 // strip [] from the message
2318 message = QString::fromLatin1(start+1, end-start-2);
2321 } else if (strncmp(start, "Breakpoint ", 11) == 0) {
2323 * We stopped at a (permanent) breakpoint (gdb doesn't tell us
2324 * that it stopped at a temporary breakpoint).
2326 flags |= SFrefreshBreak;
2327 } else if (strstr(start, "re-reading symbols.") != 0) {
2328 flags |= SFrefreshSource;
2331 // next line, please
2332 start = strchr(start, '\n');
2333 } while (start != 0);
2336 * Gdb only notices when new threads have appeared, but not when a
2337 * thread finishes. So we always have to assume that the list of
2338 * threads has changed.
2340 flags |= SFrefreshThreads;
2342 return flags;
2345 QStringList GdbDriver::parseSharedLibs(const char* output)
2347 QStringList shlibs;
2348 if (strncmp(output, "No shared libraries loaded", 26) == 0)
2349 return shlibs;
2351 // parse the table of shared libraries
2353 // strip off head line
2354 output = strchr(output, '\n');
2355 if (output == 0)
2356 return shlibs;
2357 output++; /* skip '\n' */
2358 QString shlibName;
2359 while (*output != '\0') {
2360 // format of a line is
2361 // 0x404c5000 0x40580d90 Yes /lib/libc.so.5
2362 // 3 blocks of non-space followed by space
2363 for (int i = 0; *output != '\0' && i < 3; i++) {
2364 while (*output != '\0' && !isspace(*output)) { /* non-space */
2365 output++;
2367 skipSpace(output); /* space */
2369 if (*output == '\0')
2370 return shlibs;
2371 const char* start = output;
2372 output = strchr(output, '\n');
2373 if (output == 0)
2374 output = start + strlen(start);
2375 shlibName = QString::fromLatin1(start, output-start);
2376 if (*output != '\0')
2377 output++;
2378 shlibs.append(shlibName);
2379 TRACE("found shared lib " + shlibName);
2381 return shlibs;
2384 bool GdbDriver::parseFindType(const char* output, QString& type)
2386 if (strncmp(output, "type = ", 7) != 0)
2387 return false;
2390 * Everything else is the type. We strip off any leading "const" and any
2391 * trailing "&" on the grounds that neither affects the decoding of the
2392 * object. We also strip off all white-space from the type.
2394 output += 7;
2395 if (strncmp(output, "const ", 6) == 0)
2396 output += 6;
2397 type = output;
2398 type.replace(QRegExp("\\s+"), "");
2399 if (type.endsWith("&"))
2400 type.truncate(type.length() - 1);
2401 return true;
2404 std::list<RegisterInfo> GdbDriver::parseRegisters(const char* output)
2406 std::list<RegisterInfo> regs;
2407 if (strncmp(output, "The program has no registers now", 32) == 0) {
2408 return regs;
2411 // parse register values
2412 while (*output != '\0')
2414 RegisterInfo reg;
2415 // skip space at the start of the line
2416 skipSpace(output);
2418 // register name
2419 const char* start = output;
2420 while (*output != '\0' && !isspace(*output))
2421 output++;
2422 if (*output == '\0')
2423 break;
2424 reg.regName = QString::fromLatin1(start, output-start);
2426 skipSpace(output);
2428 QString value;
2431 * If we find a brace now, this is a vector register. We look for
2432 * the closing brace and treat the result as cooked value.
2434 if (*output == '{')
2436 start = output;
2437 skipNested(output, '{', '}');
2438 value = QString::fromLatin1(start, output-start).simplified();
2439 // skip space, but not the end of line
2440 while (isspace(*output) && *output != '\n')
2441 output++;
2442 // get rid of the braces at the begining and the end
2443 value.remove(0, 1);
2444 if (value[value.length()-1] == '}') {
2445 value = value.left(value.length()-1);
2447 // gdb 5.3 doesn't print a separate set of raw values
2448 if (*output == '{') {
2449 // another set of vector follows
2450 // what we have so far is the raw value
2451 reg.rawValue = value;
2453 start = output;
2454 skipNested(output, '{', '}');
2455 value = QString::fromLatin1(start, output-start).simplified();
2456 } else {
2457 // for gdb 5.3
2458 // find first type that does not have an array, this is the RAW value
2459 const char* end=start;
2460 findEnd(end);
2461 const char* cur=start;
2462 while (cur<end) {
2463 while (*cur != '=' && cur<end)
2464 cur++;
2465 cur++;
2466 while (isspace(*cur) && cur<end)
2467 cur++;
2468 if (isNumberish(*cur)) {
2469 end=cur;
2470 while (*end && (*end!='}') && (*end!=',') && (*end!='\n'))
2471 end++;
2472 QString rawValue = QString::fromLatin1(cur, end-cur).simplified();
2473 reg.rawValue = rawValue;
2475 if (rawValue.left(2)=="0x") {
2476 // ok we have a raw value, now get it's type
2477 end=cur-1;
2478 while (isspace(*end) || *end=='=') end--;
2479 end++;
2480 cur=end-1;
2481 while (*cur!='{' && *cur!=' ')
2482 cur--;
2483 cur++;
2484 reg.type = QString::fromLatin1(cur, end-cur);
2487 // end while loop
2488 cur=end;
2491 // skip to the end of line
2492 while (*output != '\0' && *output != '\n')
2493 output++;
2494 // get rid of the braces at the begining and the end
2495 value.remove(0, 1);
2496 if (value[value.length()-1] == '}') {
2497 value.truncate(value.length()-1);
2500 reg.cookedValue = value;
2502 else
2504 continuation:
2505 // the rest of the line is the register value
2506 start = output;
2507 output = strchr(output,'\n');
2508 if (output == 0)
2509 output = start + strlen(start);
2510 value += QString::fromLatin1(start, output-start).simplified();
2513 * Look ahead: if the subsequent line is indented, it continues
2514 * the current register value.
2516 if (output != 0 && isspace(output[1]))
2518 ++output;
2519 value += ' ';
2520 goto continuation;
2524 * We split the raw from the cooked values.
2525 * Some modern gdbs explicitly say: "0.1234 (raw 0x3e4567...)".
2526 * Here, the cooked value comes first, and the raw value is in
2527 * the second part.
2529 int pos = value.indexOf(" (raw ");
2530 if (pos >= 0)
2532 reg.cookedValue = value.left(pos);
2533 reg.rawValue = value.mid(pos+6);
2534 if (reg.rawValue.right(1) == ")") // remove closing bracket
2535 reg.rawValue.truncate(reg.rawValue.length()-1);
2537 else
2540 * In other cases we split off the first token (separated by
2541 * whitespace). It is the raw value. The remainder of the line
2542 * is the cooked value.
2544 int pos = value.indexOf(' ');
2545 if (pos < 0) {
2546 reg.rawValue = value;
2547 reg.cookedValue = QString();
2548 } else {
2549 reg.rawValue = value.left(pos);
2550 reg.cookedValue = value.mid(pos+1);
2554 if (*output != '\0')
2555 output++; /* skip '\n' */
2557 regs.push_back(reg);
2559 return regs;
2562 bool GdbDriver::parseInfoLine(const char* output, QString& addrFrom, QString& addrTo)
2564 // "is at address" or "starts at address"
2565 const char* start = strstr(output, "s at address ");
2566 if (start == 0)
2567 return false;
2569 start += 13;
2570 const char* p = start;
2571 while (*p != '\0' && !isspace(*p))
2572 p++;
2573 addrFrom = QString::fromLatin1(start, p-start);
2575 start = strstr(p, "and ends at ");
2576 if (start == 0) {
2577 addrTo = addrFrom;
2578 return true;
2581 start += 12;
2582 p = start;
2583 while (*p != '\0' && !isspace(*p))
2584 p++;
2585 addrTo = QString::fromLatin1(start, p-start);
2587 return true;
2590 std::list<DisassembledCode> GdbDriver::parseDisassemble(const char* output)
2592 std::list<DisassembledCode> code;
2594 if (strncmp(output, "Dump of assembler", 17) != 0) {
2595 // error message?
2596 DisassembledCode c;
2597 c.code = output;
2598 code.push_back(c);
2599 return code;
2602 // remove first line
2603 const char* p = strchr(output, '\n');
2604 if (p == 0)
2605 return code; /* not a regular output */
2607 p++;
2609 // remove last line
2610 const char* end = strstr(output, "End of assembler");
2611 if (end == 0)
2612 end = p + strlen(p);
2614 // remove function offsets from the lines
2615 while (p != end)
2617 DisassembledCode c;
2618 // skip initial space or PC pointer ("=>", since gdb 7.1)
2619 while (p != end) {
2620 if (isspace(*p))
2621 ++p;
2622 else if (p[0] == '=' && p[1] == '>')
2623 p += 2;
2624 else
2625 break;
2627 const char* start = p;
2628 // address
2629 while (p != end && !isspace(*p))
2630 p++;
2631 c.address = QString::fromLatin1(start, p-start);
2633 // function name (enclosed in '<>', followed by ':')
2634 while (p != end && *p != '<')
2635 p++;
2636 if (*p == '<')
2637 skipNestedAngles(p);
2638 if (*p == ':')
2639 p++;
2641 // space until code
2642 while (p != end && isspace(*p))
2643 p++;
2645 // code until end of line
2646 start = p;
2647 while (p != end && *p != '\n')
2648 p++;
2649 if (p != end) /* include '\n' */
2650 p++;
2652 c.code = QString::fromLatin1(start, p-start);
2653 code.push_back(c);
2655 return code;
2658 QString GdbDriver::parseMemoryDump(const char* output, std::list<MemoryDump>& memdump)
2660 if (isErrorExpr(output)) {
2661 // error; strip space
2662 QString msg = output;
2663 return msg.trimmed();
2666 const char* p = output; /* save typing */
2667 const char* end_output = p + strlen(p);
2669 // check if there is end of memory region
2670 const char* end_region = strstr(p, "Cannot access memory at address");
2671 if (end_region)
2672 end_output = end_region;
2674 while (p < end_output)
2676 MemoryDump md;
2678 // the address
2679 skipSpace(p); /* remove leading space, detected on instructions output format */
2681 const char* start = p;
2683 while (*p != '\0' && *p != ':' && !isspace(*p))
2684 p++;
2685 md.address = QString::fromLatin1(start, p-start);
2687 if (*p != ':') {
2688 // parse function offset
2689 skipSpace(p);
2690 start = p;
2691 while (*p != '\0' && !(*p == ':' && isspace(p[1])))
2692 p++;
2693 md.address.fnoffs = QString::fromLatin1(start, p-start);
2695 if (*p == ':')
2696 p++;
2697 // skip space; this may skip a new-line char!
2698 skipSpace(p);
2699 // everything to the end of the line is the memory dump
2700 const char* end = strchr(p, '\n');
2701 if (!end || (end_region && end > end_region))
2702 end = end_output;
2703 md.dump = QString::fromLatin1(p, end-p);
2704 p = end;
2705 if (*p)
2706 ++p; // skip '\n' or 'C' of "Cannot access..."
2708 md.littleendian = m_littleendian;
2709 memdump.push_back(md);
2712 if (end_region && !memdump.empty())
2713 memdump.back().endOfDump = true;
2715 return QString();
2718 QString GdbDriver::editableValue(VarTree* value)
2720 QByteArray ba = value->value().toLatin1();
2721 const char* s = ba.constData();
2723 // if the variable is a pointer value that contains a cast,
2724 // remove the cast
2725 if (*s == '(') {
2726 skipNested(s, '(', ')');
2727 // skip space
2728 skipSpace(s);
2731 repeat:
2732 const char* start = s;
2734 if (strncmp(s, "0x", 2) == 0)
2736 s += 2;
2737 while (isxdigit(*s))
2738 ++s;
2741 * What we saw so far might have been a reference. If so, edit the
2742 * referenced value. Otherwise, edit the pointer.
2744 if (*s == ':') {
2745 // a reference
2746 ++s;
2747 goto repeat;
2749 // a pointer
2750 // if it's a pointer to a string, remove the string
2751 const char* end = s;
2752 skipSpace(s);
2753 if (*s == '"') {
2754 // a string
2755 return QString::fromLatin1(start, end-start);
2756 } else {
2757 // other pointer
2758 return QString::fromLatin1(start, strlen(start));
2762 // else leave it unchanged (or stripped of the reference preamble)
2763 return s;
2766 QString GdbDriver::parseSetVariable(const char* output)
2768 // if there is any output, it is an error message
2769 QString msg = output;
2770 return msg.trimmed();
2774 #include "gdbdriver.moc"