1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15import { query } from '../SqlLite'; 16import { FuncStruct } from '../ui-worker/ProcedureWorkerFunc'; 17import { SearchFuncBean } from '../../bean/SearchFuncBean'; 18import { SelectionData } from '../../bean/BoxSelection'; 19import { HeapTraceFunctionInfo } from '../../../js-heap/model/DatabaseStruct'; 20import { FunctionItem } from '../../bean/BinderProcessThread'; 21import { StateGroup } from '../../bean/StateModle'; 22import { FuncNameCycle } from '../../bean/BinderProcessThread'; 23import { Utils } from '../../component/trace/base/Utils'; 24 25export const queryFuncNameCycle = ( 26 funcName: string, 27 tIds: string, 28 leftNS: number, 29 rightNS: number 30): Promise<Array<FunctionItem>> => 31 query( 32 'queryFuncNameCycle', 33 ` 34 SELECT 35 c.ts - r.start_ts AS cycleStartTime, 36 c.dur, 37 c.id, 38 t.tid, 39 p.pid 40 FROM 41 callstack c, trace_range r 42 LEFT JOIN 43 thread t 44 ON 45 c.callid = t.id 46 LEFT JOIN 47 process p 48 ON 49 t.ipid = p.id 50 WHERE 51 c.name like '${funcName}%' 52 AND 53 t.tid = ${tIds} 54 AND NOT 55 ((cycleStartTime < ${leftNS}) 56 OR 57 ((c.ts - r.start_ts + c.dur) > ${rightNS})) 58 `, 59 { 60 $funcName: funcName, 61 $tIds: tIds, 62 $leftNS: leftNS, 63 $rightNS: rightNS, 64 }, 65 { traceId: Utils.currentSelectTrace } 66 ); 67 68export const querySingleFuncNameCycle = ( 69 funcName: string, 70 tIds: string, 71 leftNS: number, 72 rightNS: number 73): Promise<Array<FunctionItem>> => 74 query( 75 'querySingleFuncNameCycle', 76 ` 77 SELECT 78 c.name AS funcName, 79 c.ts - r.start_ts AS cycleStartTime, 80 c.dur AS cycleDur, 81 c.id, 82 t.tid, 83 p.pid, 84 c.ts - r.start_ts + c.dur AS endTime 85 FROM 86 callstack c, trace_range r 87 LEFT JOIN 88 thread t 89 ON 90 c.callid = t.id 91 LEFT JOIN 92 process p 93 ON 94 t.ipid = p.id 95 WHERE 96 c.name = '${funcName}' 97 AND 98 t.tid = ${tIds} 99 AND NOT 100 ((cycleStartTime < ${leftNS}) 101 OR 102 (endTime > ${rightNS})) 103 `, 104 { 105 $funcName: funcName, 106 $tIds: tIds, 107 $leftNS: leftNS, 108 $rightNS: rightNS, 109 } 110 ); 111 112export const queryAllFuncNames = async (traceId?: string): Promise<Array<unknown>> => { 113 let allFuncNamesBuffer = await query( 114 'queryAllFuncNames', 115 `select 116 id, 117 name 118 from 119 callstack;`, 120 {}, 121 { traceId: traceId, action: 'exec-buf' } 122 ); 123 // @ts-ignore 124 return Utils.convertJSON(allFuncNamesBuffer); 125}; 126 127export const queryProcessAsyncFunc = ( 128 traceRange: { 129 startTs: number; 130 endTs: number; 131 }, 132 traceId?: string 133): //@ts-ignore 134 Promise<Array<unknown>> => 135 query( 136 'queryProcessAsyncFunc', 137 `SELECT 138 A.tid, 139 P.pid, 140 c.ts-${traceRange.startTs} as startTs, 141 c.dur, 142 c.cat, 143 c.id, 144 c.depth, 145 c.argsetid, 146 c.cookie 147 FROM 148 (SELECT id, ts, parent_id, dur, depth, argsetid, cookie, cat from callstack where cookie NOT NULL) c 149 LEFT JOIN thread A ON A.id = c.parent_id 150 LEFT JOIN process P ON P.id = A.ipid 151 WHERE 152 startTs NOT NULL;`, 153 {}, 154 { traceId: traceId } 155 ); 156 157export const queryProcessAsyncFuncCat = ( 158 traceRange: { 159 startTs: number; 160 endTs: number; 161 } 162): Promise<Array<unknown>> => 163 query( 164 'queryProcessAsyncFuncCat', 165 ` 166 select 167 A.tid, 168 P.pid, 169 c.cat as threadName, 170 c.name as funName, 171 c.ts-${traceRange.startTs} as startTs, 172 c.dur, 173 c.depth, 174 c.cookie 175 from 176 (select callid, name, ts, dur, cat, depth, cookie, parent_id from callstack where cookie not null and cat not null and parent_id is null) C 177 left join 178 thread A on A.id = C.callid 179 left join 180 process P on P.id = A.ipid 181 where 182 startTs not null 183 order by cat; 184 `, 185 {} 186 ); 187 188export const getMaxDepthByTid = (traceId?: string): //@ts-ignore 189 Promise<Array<unknown>> => 190 query( 191 'getMaxDepthByTid', 192 `SELECT 193 tid, 194 ipid, 195 maxDepth 196 FROM 197 thread T 198 LEFT JOIN ( 199 SELECT 200 callid, 201 MAX( c.depth + 1 ) AS maxDepth 202 FROM 203 callstack C 204 WHERE 205 c.ts IS NOT NULL 206 AND c.cookie IS NULL 207 GROUP BY 208 callid 209 ) C ON T.id = C.callid 210 WHERE 211 maxDepth NOT NULL`, 212 {}, 213 { traceId: traceId } 214 ); 215 216export const querySearchFuncData = ( 217 funcName: string, 218 tIds: number, 219 leftNS: number, 220 rightNS: number 221): Promise<Array<SearchFuncBean>> => 222 query( 223 'querySearchFuncData', 224 `select 225 c.ts - r.start_ts as startTime, 226 c.dur 227 from 228 callstack c 229 left join 230 thread t 231 on 232 c.callid = t.id 233 left join 234 process p 235 on 236 t.ipid = p.id 237 left join 238 trace_range r 239 where 240 c.name like '${funcName}%' 241 and 242 t.tid = ${tIds} 243 and 244 not ((startTime < ${leftNS}) or (startTime > ${rightNS})); 245 ` 246 ); 247 248export const queryFuncRowData = (funcName: string, tIds: number): Promise<Array<SearchFuncBean>> => 249 query( 250 'queryFuncRowData', 251 `select 252 c.name as funName, 253 c.ts - r.start_ts as startTime, 254 t.tid as tid 255 from 256 callstack c 257 left join 258 thread t 259 on 260 c.callid = t.id 261 left join 262 process p 263 on 264 t.ipid = p.id 265 left join 266 trace_range r 267 where 268 c.name like '${funcName}%' 269 and 270 t.tid = ${tIds} 271 `, 272 { $search: funcName } 273 ); 274 275export const fuzzyQueryFuncRowData = (funcName: string, tIds: number): 276 Promise<Array<SearchFuncBean>> => 277 query( 278 'fuzzyQueryFuncRowData', 279 `select 280 c.name as funName, 281 c.ts - r.start_ts as startTime, 282 c.ts - r.start_ts + c.dur as endTime, 283 t.tid as tid 284 from 285 callstack c 286 left join 287 thread t 288 on 289 c.callid = t.id 290 left join 291 process p 292 on 293 t.ipid = p.id 294 left join 295 trace_range r 296 where 297 c.name like '%${funcName}%' 298 and 299 t.tid = ${tIds} 300 `, 301 { $search: funcName } 302 ); 303 304export const getTabSlicesAsyncFunc = ( 305 asyncNames: Array<string>, 306 asyncPid: Array<number>, 307 leftNS: number, 308 rightNS: number 309): //@ts-ignore 310 Promise<Array<unknown>> => 311 query<SelectionData>( 312 'getTabSlicesAsyncFunc', 313 `SELECT 314 c.name AS name, 315 sum( c.dur ) AS wallDuration, 316 avg( c.dur ) AS avgDuration, 317 count( c.name ) AS occurrences 318 FROM 319 thread A, 320 trace_range D 321 LEFT JOIN process P ON P.id = A.ipid 322 LEFT JOIN callstack C ON A.id = C.callid 323 where 324 C.ts > 0 325 and 326 c.dur >= -1 327 and 328 c.cookie not null 329 and 330 P.pid in (${asyncPid.join(',')}) 331 and 332 c.name in (${asyncNames.map((it) => "'" + it + "'").join(',')}) 333 and 334 not ((C.ts - D.start_ts + C.dur < $leftNS) or (C.ts - D.start_ts > $rightNS)) 335 group by 336 c.name 337 order by 338 wallDuration desc;`, 339 { $leftNS: leftNS, $rightNS: rightNS } 340 ); 341 342export const getTabDetails = ( 343 asyncNames: Array<string>, 344 asyncPid: Array<number>, 345 leftNS: number, 346 rightNS: number, 347 key: string, 348 funTids?: Array<number> 349): //@ts-ignore 350 Promise<Array<unknown>> => { 351 let asyncCondition = ''; 352 let catCondition = ''; 353 let syncCondition = ''; 354 if (key === 'async') { 355 asyncCondition = ` 356 and c.cookie not null 357 and c.parent_id not null 358 `; 359 } else if (key === 'sync') { 360 syncCondition = ` 361 and A.tid in (${funTids!.join(',')}) 362 and c.cookie is null 363 `; 364 } 365 let condition = ` 366 ${asyncCondition} 367 ${catCondition} 368 ${syncCondition} 369 ${`and P.pid in (${asyncPid.join(',')})`} 370 ${`and c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')})`} 371 `; 372 let sql = ` 373 SELECT 374 c.name AS name, 375 c.dur AS duration, 376 P.pid AS processId, 377 P.name AS process, 378 A.tid AS threadId, 379 A.name AS thread, 380 c.ts - D.start_ts as startNs 381 FROM 382 thread A,trace_range D 383 LEFT JOIN process P ON P.id = A.ipid 384 LEFT JOIN callstack C ON A.id = C.callid 385 where 386 C.ts > 0 387 and 388 c.dur >= -1 389 and 390 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} 391 `; 392 return query('getTabDetails', sql, {}); 393}; 394export const getCatDetails = ( 395 asyncNames: Array<string>, 396 catName: Array<string>, 397 asyncPid: Array<number>, 398 leftNS: number, 399 rightNS: number 400): //@ts-ignore 401 Promise<Array<unknown>> => { 402 let sql = ` 403 SELECT 404 c.name AS name, 405 c.dur AS duration, 406 P.pid AS processId, 407 P.name AS process, 408 A.tid AS threadId, 409 A.name AS thread, 410 c.ts - D.start_ts as startNs 411 FROM 412 thread A,trace_range D 413 LEFT JOIN process P ON P.id = A.ipid 414 LEFT JOIN callstack C ON A.id = C.callid 415 where 416 C.ts > 0 417 and 418 c.dur >= -1 419 and 420 c.cookie not null 421 and 422 c.cat not null 423 and 424 c.parent_id is null 425 and 426 P.pid in (${asyncPid.join(',')}) 427 and 428 c.cat in (${catName.map((it) => '\"' + it + '\"').join(',')}) 429 and 430 c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')}) 431 and 432 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) 433 `; 434 return query('getCatDetails', sql, {}); 435}; 436export const getTabSlicesAsyncCatFunc = ( 437 asyncCatNames: Array<string>, 438 asyncCatPid: Array<number>, 439 leftNS: number, 440 rightNS: number 441): Promise<Array<unknown>> => 442 query<SelectionData>( 443 'getTabSlicesAsyncCatFunc', 444 ` 445 select 446 c.name as name, 447 sum(c.dur) as wallDuration, 448 avg(c.dur) as avgDuration, 449 count(c.name) as occurrences 450 from 451 thread A, trace_range D 452 left join process P on P.id = A.ipid 453 left join callstack C on A.id = C.callid 454 where 455 C.ts > 0 456 and 457 c.dur >= -1 458 and 459 c.cookie not null 460 and 461 c.cat not null 462 and 463 P.pid in (${asyncCatPid.join(',')}) 464 and 465 c.cat in (${asyncCatNames.map((it) => "'" + it + "'").join(',')}) 466 and 467 not ((C.ts - D.start_ts + C.dur < $leftNS) or (C.ts - D.start_ts > $rightNS)) 468 group by 469 c.name 470 order by 471 wallDuration desc;`, 472 { $leftNS: leftNS, $rightNS: rightNS } 473 ); 474 475export const querySearchFunc = (search: string): Promise<Array<SearchFuncBean>> => 476 query( 477 'querySearchFunc', 478 ` 479 select c.cookie, 480 c.id, 481 c.name as funName, 482 c.ts - r.start_ts as startTime, 483 c.dur, 484 c.depth, 485 t.tid, 486 t.name as threadName, 487 p.pid, 488 c.argsetid, 489 'func' as type 490 from callstack c left join thread t on c.callid = t.id left join process p on t.ipid = p.id 491 left join trace_range r 492 where c.name like '%${search}%' and startTime > 0 and cookie IS NULL; 493 `, 494 { $search: search }, 495 { traceId: Utils.currentSelectTrace } 496 ); 497 498export const querySceneSearchFunc = (search: string, processList: Array<string>): 499 Promise<Array<SearchFuncBean>> => 500 query( 501 'querySceneSearchFunc', 502 `select c.cookie, 503 c.id, 504 c.name as funName, 505 c.ts - r.start_ts as startTime, 506 c.dur, 507 c.depth, 508 t.tid, 509 t.name as threadName, 510 p.pid, 511 c.argsetid, 512 'func' as type 513 from callstack c left join thread t on c.callid = t.id left join process p on t.ipid = p.id 514 left join trace_range r 515 where c.name like '%${search}%' ESCAPE '\\' and startTime > 0 and p.pid in (${processList.join(',')}) 516 and cookie IS NULL; 517 `, 518 { $search: search }, 519 { traceId: Utils.currentSelectTrace } 520 ); 521 522export const queryHeapFunction = (fileId: number): Promise<Array<HeapTraceFunctionInfo>> => 523 query( 524 'queryHeapFunction', 525 `SELECT 526 function_index as index , 527 function_id as id , 528 name, 529 script_name as scriptName, 530 script_id as scriptId, 531 line, 532 column 533 FROM js_heap_trace_function_info WHERE file_id = ${fileId}` 534 ); 535 536export const queryHeapTraceNode = ( 537 fileId: number 538): //@ts-ignore 539 Promise<Array<unknown>> => 540 query( 541 'queryHeapTraceNode', 542 `SELECT F.name, 543 F.script_name as scriptName, 544 F.script_id as scriptId, 545 F.column, 546 F.line, 547 N.id, 548 N.function_info_index as functionInfoIndex, 549 N.parent_id as parentId, 550 N.count, 551 N.size, 552 IFNULL( S.live_count, 0 ) AS liveCount, 553 IFNULL( S.live_size, 0 ) AS liveSize 554 FROM 555 js_heap_trace_node N 556 LEFT JOIN ( 557 SELECT 558 trace_node_id as traceNodeId, 559 SUM( self_size ) AS liveSize, 560 count( * ) AS liveCount 561 FROM 562 js_heap_nodes 563 WHERE 564 file_id = ${fileId} 565 AND trace_node_id != 0 566 GROUP BY 567 trace_node_id 568 ) S ON N.id = S.trace_node_id 569 LEFT JOIN js_heap_trace_function_info F ON (F.file_id = N.file_id 570 AND F.function_index = N.function_info_index) 571 WHERE 572 N.file_id = ${fileId} 573 ORDER BY 574 N.id` 575 ); 576 577export const queryTaskPoolOtherRelationData = (ids: Array<number>, tid: number): 578 Promise<Array<FuncStruct>> => { 579 let sqlStr = `select 580 c.ts-D.start_ts as startTs, 581 c.dur, 582 c.name as funName, 583 c.argsetid, 584 c.depth, 585 c.id as id, 586 A.itid as itid, 587 A.ipid as ipid 588 from thread A,trace_range D 589 left join callstack C on A.id = C.callid 590 where startTs not null and c.cookie is null and tid = $tid and c.id in (${ids.join(',')})`; 591 return query('queryTaskPoolOtherRelationData', sqlStr, { $ids: ids, $tid: tid }); 592}; 593 594export const queryTaskPoolRelationData = (ids: Array<number>, tids: Array<number>): 595 Promise<Array<FuncStruct>> => { 596 let sqlStr = `select 597 c.ts-D.start_ts as startTs, 598 c.dur, 599 c.name as funName, 600 c.argsetid, 601 c.depth, 602 c.id as id, 603 A.itid as itid, 604 A.ipid as ipid 605 from thread A,trace_range D 606 left join callstack C on A.id = C.callid 607 where startTs not null and c.cookie is null and c.id in (${ids.join(',')}) and tid in (${tids.join( 608 ',' 609 )})`; 610 return query('queryTaskPoolRelationData', sqlStr, { $ids: ids, $tids: tids }); 611}; 612 613export const queryStatesCut = (tIds: Array<number>, leftNS: number, rightNS: number): 614 Promise<Array<StateGroup>> => 615 query<StateGroup>( 616 'queryBinderByThreadId', 617 ` 618 select 619 B.id, 620 B.pid, 621 B.tid, 622 B.dur, 623 B.cpu, 624 B.state, 625 B.ts - C.start_ts AS ts, 626 B.dur + B.ts as endTs 627 from 628 thread_state AS B,trace_range AS C 629 where 630 B.tid in (${tIds.join(',')}) 631 and 632 not ((B.ts + + ifnull(B.dur,0) < ($leftStartNs + C.start_ts)) 633 or (B.ts + B.dur > ($rightEndNs + C.start_ts))) 634 order by 635 B.pid; 636 `, 637 { 638 $tIds: tIds, 639 $leftStartNs: leftNS, 640 $rightEndNs: rightNS, 641 } 642 ); 643 644export const queryLoopFuncNameCycle = ( 645 funcName: string, 646 tIds: string, 647 leftNS: number, 648 rightNS: number 649): Promise<Array<FuncNameCycle>> => 650 query( 651 'queryLoopFuncNameCycle', 652 ` 653 SELECT 654 c.name AS funcName, 655 c.ts - r.start_ts AS cycleStartTime, 656 0 AS cycleDur, 657 c.id, 658 t.tid, 659 p.pid 660 FROM 661 callstack c, trace_range r 662 LEFT JOIN 663 thread t 664 ON 665 c.callid = t.id 666 LEFT JOIN 667 process p 668 ON 669 t.ipid = p.id 670 WHERE 671 c.name like '${funcName}%' 672 AND 673 t.tid = ${tIds} 674 AND NOT 675 ((cycleStartTime < ${leftNS}) 676 OR 677 (cycleStartTime > ${rightNS})) 678 `, 679 { 680 $funcName: funcName, 681 $tIds: tIds, 682 $leftNS: leftNS, 683 $rightNS: rightNS, 684 } 685 ); 686 687export const querySingleFuncNameCycleStates = ( 688 funcName: string, 689 tIds: string, 690 leftNS: number, 691 rightNS: number 692): Promise<Array<FuncNameCycle>> => 693 query( 694 'querySingleFuncNameCycle', 695 ` 696 SELECT 697 c.name AS funcName, 698 c.ts - r.start_ts AS cycleStartTime, 699 c.dur AS cycleDur, 700 c.id, 701 t.tid, 702 p.pid, 703 c.ts - r.start_ts + c.dur AS endTime 704 FROM 705 callstack c, trace_range r 706 LEFT JOIN 707 thread t 708 ON 709 c.callid = t.id 710 LEFT JOIN 711 process p 712 ON 713 t.ipid = p.id 714 WHERE 715 c.name like '${funcName}%' 716 AND 717 t.tid = ${tIds} 718 AND NOT 719 ((cycleStartTime < ${leftNS}) 720 OR 721 (endTime > ${rightNS})) 722 `, 723 { 724 $funcName: funcName, 725 $tIds: tIds, 726 $leftNS: leftNS, 727 $rightNS: rightNS, 728 } 729 ); 730