2 // callstackbrowser.cpp - Call Stack
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
8 // Who When (M/D/Y) What
9 // --- ------------ -----------------------------------------------------------
10 // JPM 08/31/2018 Created this file
11 // JPM 09/12/2018 Added a status bar and better status report
12 // JPM 10/20/2018 Added the return address information in the call stack
13 // JPM 08/09/2019 Prevent crash in case of call stack is out of range
14 // JPM 03/16/2020 Modified the layout window and added source filename from the called source line
15 // JPM April/2021 Added a #line information
18 // To set the information display at the right
19 // To use DWARF frame information?
20 // To check if call stack pointer is used (DWARF information?)
23 #include "debugger/callstackbrowser.h"
25 #include "debugger/DBGManager.h"
26 #include "m68000/m68kinterface.h"
31 CallStackBrowserWindow::CallStackBrowserWindow(QWidget
* parent
/*= 0*/) : QWidget(parent
, Qt::Dialog
),
33 text(new QTextBrowser
),
35 TableView(new QTableView
),
36 model(new QStandardItemModel
),
38 statusbar(new QStatusBar
),
39 layout(new QVBoxLayout
)
41 setWindowTitle(tr("Call Stack"));
44 QFont
fixedFont("Lucida Console", 8, QFont::Normal
);
45 fixedFont
.setStyleHint(QFont::TypeWriter
);
48 // Set original layout
49 text
->setFont(fixedFont
);
50 layout
->addWidget(text
);
52 // Set the new layout with proper identation and readibility
53 model
->setColumnCount(5);
54 model
->setHeaderData(0, Qt::Horizontal
, QObject::tr("Function"));
55 model
->setHeaderData(1, Qt::Horizontal
, QObject::tr("#Line"));
56 model
->setHeaderData(2, Qt::Horizontal
, QObject::tr("Line"));
57 model
->setHeaderData(3, Qt::Horizontal
, QObject::tr("Return address"));
58 model
->setHeaderData(4, Qt::Horizontal
, QObject::tr("Filename"));
60 TableView
->setModel(model
);
61 TableView
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
62 TableView
->setShowGrid(0);
63 TableView
->setFont(fixedFont
);
64 TableView
->verticalHeader()->setDefaultSectionSize(TableView
->verticalHeader()->minimumSectionSize());
65 TableView
->verticalHeader()->setDefaultAlignment(Qt::AlignRight
);
66 layout
->addWidget(TableView
);
70 layout
->addWidget(statusbar
);
76 CallStackBrowserWindow::~CallStackBrowserWindow(void)
82 void CallStackBrowserWindow::RefreshContents(void)
85 size_t Error
= CS_NOERROR
;
86 DBGstatus FilenameStatus
;
87 unsigned int a6
, Sa6
, ret
;
100 #ifndef CS_LAYOUTTEXTS
101 model
->setRowCount(0);
103 if ((a6
= m68k_get_reg(NULL
, M68K_REG_A6
)) && DBGManager_GetType())
105 while ((Sa6
= a6
) && !NumError
)
107 if ((Sa6
>= (m68k_get_reg(NULL
, M68K_REG_SP
) - 4)) && (Sa6
< vjs
.DRAM_size
))
109 a6
= GET32(jaguarMainRAM
, Sa6
);
110 ret
= GET32(jaguarMainRAM
, Sa6
+ 4);
111 #ifdef CS_LAYOUTTEXTS
112 sprintf(string
, "0x%06X | Ret: 0x%06X | From: %s - 0x%06X | Line: %s", Sa6
, ret
, (Name
= DBGManager_GetFunctionName(ret
)), (unsigned int)DBGManager_GetAdrFromSymbolName(Name
), DBGManager_GetLineSrcFromAdr(ret
, DBG_NO_TAG
));
113 CallStack
+= QString(string
);
116 CallStack
+= QString("<br>");
120 model
->insertRow(NbRaw
);
121 // display the function name
122 model
->setItem(NbRaw
, 0, new QStandardItem(QString("%1").arg((Name
= DBGManager_GetFunctionName(ret
)) ? Name
: "(N/A)")));
123 // display the line number
124 sprintf(msg
, "%zi", DBGManager_GetNumLineFromAdr(ret
, DBG_NO_TAG
));
125 model
->setItem(NbRaw
, 1, new QStandardItem(QString("%1").arg((msg
[0] != '0') ? msg
: "(N/A)")));
126 // display the called line
127 FunctionName
= QString(Name
= DBGManager_GetLineSrcFromAdr(ret
, DBG_NO_TAG
));
128 //FunctionName.replace(" ", " ");
129 FunctionName
= FunctionName
.trimmed();
130 model
->setItem(NbRaw
, 2, new QStandardItem(QString("%1").arg(Name
? FunctionName
: "(N/A)")));
131 // display the return address
132 sprintf(msg
, "0x%06X", ret
);
133 model
->setItem(NbRaw
, 3, new QStandardItem(QString("%1").arg(msg
)));
134 // display the source filename from called source line
135 model
->setItem(NbRaw
++, 4, new QStandardItem(QString("%1").arg(((Name
= DBGManager_GetFullSourceFilenameFromAdr(ret
, &FilenameStatus
)) && !FilenameStatus
) ? Name
: "(N/A)")));
143 #ifdef CS_LAYOUTTEXTS
145 text
->setText(CallStack
);
150 sprintf(msg
, "Ready");
155 sprintf(msg
, "Call Stack out of range");
160 sprintf(msg
, "Call Stack in limbo");
167 sprintf(msg
, "Call Stack not available");
168 Error
= CS_NOCALLSTACK
;
169 #ifdef CS_LAYOUTTEXTS
174 // Display status bar
177 if ((Error
& CS_WARNING
))
179 statusbar
->setStyleSheet("background-color: lightyellow; font: bold");
183 statusbar
->setStyleSheet("background-color: tomato; font: bold");
188 statusbar
->setStyleSheet("background-color: lightgreen; font: bold");
190 statusbar
->showMessage(QString(msg
));
196 void CallStackBrowserWindow::keyPressEvent(QKeyEvent
* e
)
198 if (e
->key() == Qt::Key_Escape
)