Skip to content

Commit 8031c35

Browse files
Fixed an issue where the debugger hangs when stepping into nested function/procedure. #8443
1 parent 8cf1422 commit 8031c35

File tree

3 files changed

+129
-81
lines changed

3 files changed

+129
-81
lines changed

web/pgadmin/tools/debugger/__init__.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
# Constants
4242
PLDBG_EXTN = 'pldbgapi'
4343
ASYNC_OK = 1
44+
BUSY = 3
4445
DEBUGGER_SQL_PATH = 'debugger/sql'
4546
DEBUGGER_SQL_V1_PATH = 'debugger/sql/v1'
4647
DEBUGGER_SQL_V3_PATH = 'debugger/sql/v3'
@@ -263,6 +264,9 @@ def index():
263264

264265

265266
def execute_dict_search_path(conn, sql, search_path):
267+
if conn.transaction_status() == 1:
268+
return True, BUSY
269+
266270
sql_search = SET_SEARCH_PATH.format(search_path)
267271
status, res = conn.execute_void(sql_search)
268272

@@ -276,6 +280,9 @@ def execute_dict_search_path(conn, sql, search_path):
276280

277281

278282
def execute_async_search_path(conn, sql, search_path):
283+
if conn.transaction_status() == 1:
284+
return True, BUSY
285+
279286
sql_search = SET_SEARCH_PATH.format(search_path)
280287
status, res = conn.execute_void(sql_search)
281288

@@ -1214,18 +1221,24 @@ def execute_debugger_query(trans_id, query_type):
12141221
status, result = execute_async_search_path(
12151222
conn, sql, de_inst.debugger_data['search_path'])
12161223

1224+
if result == BUSY:
1225+
return make_json_response(
1226+
data={'status': 'Busy', 'result': []}
1227+
)
1228+
12171229
if result and 'select() failed waiting for target' in result:
12181230
status = True
12191231
result = None
12201232

12211233
if not status:
12221234
return internal_server_error(errormsg=result)
1235+
12231236
return make_json_response(
12241237
data={'status': status, 'result': result}
12251238
)
1226-
12271239
status, result = execute_dict_search_path(
12281240
conn, sql, de_inst.debugger_data['search_path'])
1241+
12291242
if not status:
12301243
return internal_server_error(errormsg=result)
12311244
if query_type == 'abort_target':
@@ -1234,6 +1247,11 @@ def execute_debugger_query(trans_id, query_type):
12341247
data={'status': 'Success', 'result': result}
12351248
)
12361249

1250+
if result == BUSY:
1251+
return make_json_response(
1252+
data={'status': 'Busy', 'result': []}
1253+
)
1254+
12371255
return make_json_response(
12381256
data={'status': 'Success', 'result': result['rows']}
12391257
)
@@ -1356,6 +1374,11 @@ def start_execution(trans_id, port_num):
13561374
if not status_port:
13571375
return internal_server_error(errormsg=res_port)
13581376

1377+
if res_port == BUSY:
1378+
return make_json_response(
1379+
data={'status': 'Busy', 'result': []}
1380+
)
1381+
13591382
de_inst.debugger_data['restart_debug'] = 0
13601383
de_inst.debugger_data['frame_id'] = 0
13611384
de_inst.debugger_data['exe_conn_id'] = exe_conn_id
@@ -1430,6 +1453,11 @@ def set_clear_breakpoint(trans_id, line_no, set_type):
14301453
if not status:
14311454
return internal_server_error(errormsg=res_stack)
14321455

1456+
if res_stack == BUSY:
1457+
return make_json_response(
1458+
data={'status': 'Busy', 'result': []}
1459+
)
1460+
14331461
# For multilevel function debugging, we need to fetch current selected
14341462
# frame's function oid for setting the breakpoint. For single function
14351463
# the frame id will be 0.
@@ -1450,9 +1478,16 @@ def set_clear_breakpoint(trans_id, line_no, set_type):
14501478

14511479
status, result = execute_dict_search_path(
14521480
conn, sql, de_inst.debugger_data['search_path'])
1453-
result = result['rows']
1481+
14541482
if not status:
14551483
return internal_server_error(errormsg=result)
1484+
1485+
if result == BUSY:
1486+
return make_json_response(
1487+
data={'status': 'Busy', 'result': []}
1488+
)
1489+
1490+
result = result['rows']
14561491
else:
14571492
status = False
14581493
result = SERVER_CONNECTION_CLOSED
@@ -1536,6 +1571,11 @@ def clear_all_breakpoint(trans_id):
15361571
conn, sql, de_inst.debugger_data['search_path'])
15371572
if not status:
15381573
return internal_server_error(errormsg=result)
1574+
1575+
if result == BUSY:
1576+
return make_json_response(
1577+
data={'status': 'Busy', 'result': []}
1578+
)
15391579
result = result['rows']
15401580
else:
15411581
return make_json_response(data={'status': False})
@@ -1599,6 +1639,11 @@ def deposit_parameter_value(trans_id):
15991639
if not status:
16001640
return internal_server_error(errormsg=result)
16011641

1642+
if result == BUSY:
1643+
return make_json_response(
1644+
data={'status': 'Busy', 'result': []}
1645+
)
1646+
16021647
# Check if value deposited successfully or not and depending on
16031648
# the result, return the message information.
16041649
if result['rows'][0]['pldbg_deposit_value']:
@@ -1670,6 +1715,12 @@ def select_frame(trans_id, frame_id):
16701715

16711716
status, result = execute_dict_search_path(
16721717
conn, sql, de_inst.debugger_data['search_path'])
1718+
1719+
if result == BUSY:
1720+
return make_json_response(
1721+
data={'status': 'Busy', 'result': []}
1722+
)
1723+
16731724
if not status:
16741725
return internal_server_error(errormsg=result)
16751726
else:

0 commit comments

Comments
 (0)