| 1294 | |
| 1295 | |
| 1296 | bool EXE_get_stack_trace(const Request* request, string& sTrace) |
| 1297 | { |
| 1298 | sTrace = ""; |
| 1299 | for (const Request* req = request; req; req = req->req_caller) |
| 1300 | { |
| 1301 | const Statement* const statement = req->getStatement(); |
| 1302 | |
| 1303 | string context, name; |
| 1304 | |
| 1305 | if (statement->triggerName.length()) |
| 1306 | { |
| 1307 | context = "At trigger"; |
| 1308 | name = statement->triggerName.c_str(); |
| 1309 | } |
| 1310 | else if (statement->procedure) |
| 1311 | { |
| 1312 | context = statement->parentStatement ? "At sub procedure" : "At procedure"; |
| 1313 | name = statement->procedure->getName().toString(); |
| 1314 | } |
| 1315 | else if (statement->function) |
| 1316 | { |
| 1317 | context = statement->parentStatement ? "At sub function" : "At function"; |
| 1318 | name = statement->function->getName().toString(); |
| 1319 | } |
| 1320 | else if (req->req_src_line) |
| 1321 | { |
| 1322 | context = "At block"; |
| 1323 | } |
| 1324 | |
| 1325 | if (context.hasData()) |
| 1326 | { |
| 1327 | name.trim(); |
| 1328 | |
| 1329 | if (name.hasData()) |
| 1330 | context += string(" '") + name + string("'"); |
| 1331 | |
| 1332 | if (sTrace.length() + context.length() > MAX_STACK_TRACE) |
| 1333 | break; |
| 1334 | |
| 1335 | if (sTrace.hasData()) |
| 1336 | sTrace += "\n"; |
| 1337 | |
| 1338 | sTrace += context; |
| 1339 | |
| 1340 | if (req->req_src_line) |
| 1341 | { |
| 1342 | string src_info; |
| 1343 | src_info.printf(" line: %" ULONGFORMAT", col: %" ULONGFORMAT, |
| 1344 | req->req_src_line, req->req_src_column); |
| 1345 | |
| 1346 | if (sTrace.length() + src_info.length() > MAX_STACK_TRACE) |
| 1347 | break; |
| 1348 | |
| 1349 | sTrace += src_info; |
| 1350 | } |
| 1351 | } |
| 1352 | } |
| 1353 | |