https://bz.apache.org/bugzilla/show_bug.cgi?id=66649

            Bug ID: 66649
           Summary: apache http2 endless loop in h2_session_send in
                    httpd-2.4.55/56/57
           Product: Apache httpd-2
           Version: 2.4.57
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: mod_http2
          Assignee: bugs@httpd.apache.org
          Reporter: dzwi...@strato.de
  Target Milestone: ---

Created attachment 38589
  --> https://bz.apache.org/bugzilla/attachment.cgi?id=38589&action=edit
workaround for endless loop in h2_session_send (for trunk)

Hello,

starting with the big mod_http2 update in httpd-2.4.55 we see sometimes
an endless loop using 100% of a cpu-core in h2_session.c:h2_session_send.

- the endless loop does not occur when the current httpd-code (httpd-2.4.57)
  is used with mod_http2 from httpd-2.4.54.

- this problem seems to be independent of Bug 66646 reported here:
  https://bz.apache.org/bugzilla/show_bug.cgi?id=66646. It still happens
  when the bugfix from patch r1910386 is applied.
  (https://svn.apache.org/viewvc?view=revision&revision=1910386)

- this problem seems also to be independent of the ngnttp2-library-version.
  It still happens with the most recent nghttp2-v1.54.0 library.

- our servers are configured to run with 64 worker-threads per process,
  and the machines use redhat-linux. For each server which serves about
  20 million requests per day, we see it happen at most once or twice a day.

- traces show that the loop-parameters look always similar when the 
  situation occurs. Some data is buffered, but the loop does not make
  progress anymore. 

- when the loop is broken after 100k iterations with the attached workaround,
  the httpd-child continues without other error messages.

  see patch.

- I include a core dump for the endless-loop situation. Perhaps the
  struct values can help to identify the problem.  

Greetings,
Barnim

Example output with workaround:
------------------------------
[Mon Jun 12 17:58:03 2023] [error] [client ...] http2_session_send
LOOP[100001]: 0 rv: 0 pending: 0 buffered: 154393 thres: 131072 empty: 1
scratch: 0 slen: 0 unflushed: 0 written: 106818 write_size: 16384 -> stop
[Tue Jun 13 07:26:36 2023] [error] [client ...] http2_session_send
LOOP[100001]: 0 rv: 0 pending: 0 buffered: 159877 thres: 131072 empty: 1
scratch: 0 slen: 0 unflushed: 0 written: 97564 write_size: 16384 -> stop
[Wed Jun 14 21:05:47 2023] [error] [client ...] http2_session_send
LOOP[100001]: 0 rv: 0 pending: 0 buffered: 160453 thres: 131072 empty: 1
scratch: 0 slen: 0 unflushed: 0 written: 112932 write_size: 16384 -> stop


Example core (from gcore):
-------------------------
(gdb) bt
  #0  0x00000000005ef868 in h2_c1_io_pending (io=0x7fbe30008770) at
h2_c1_io.c:369
  #1  0x00000000005efc32 in h2_c1_io_assure_flushed
(io=io@entry=0x7fbe30008770) at h2_c1_io.c:386
  #2  0x00000000005de308 in h2_session_send
(session=session@entry=0x7fbe30008730) at h2_session.c:1283
  #3  0x00000000005de4a3 in h2_session_process (session=0x7fbe30008730,
async=0) at h2_session.c:1830
  #4  0x00000000005cb519 in h2_c1_run (c=c@entry=0x7fbf80025c18) at h2_c1.c:130
  #5  0x00000000005cb92d in h2_c1_hook_process_connection (c=0x7fbf80025c18) at
h2_c1.c:278
  #6  0x00000000004dc180 in ap_run_process_connection
(c=c@entry=0x7fbf80025c18) at connection.c:42
  #7  0x00000000004dc6ae in ap_process_connection (c=c@entry=0x7fbf80025c18,
csd=csd@entry=0x7fbf80025a00) at connection.c:217
  #8  0x000000000082191b in process_socket (bucket_alloc=0x7fbe2c0008e8,
my_thread_num=40, my_child_num=96, sock=0x7fbf80025a00, p=0x7fbf80025978,
thd=0x1d5aca8) at worker.c:485
  #9  worker_thread (thd=0x1d5aca8, dummy=<optimized out>) at worker.c:814
  #10 0x00007fbfccb81ea5 in start_thread () from /lib64/libpthread.so.0
  #11 0x00007fbfcc6a6b0d in clone () from /lib64/libc.so.6
(gdb) frame 2
(gdb) info locals
  ngrv = 0
  pending = 1
  rv = 0
(gdb) p *session
  $1 = {child_num = 40924, id = 12, c1 = 0x7fbf80025c18, r = 0x0, s =
0x1de0638, pool = 0x7fbe300086b8, mplx = 0x7fbe30008da0, workers = 0x1de8410,
cin = 0x0, io = {
    session = 0x7fbe30008730, output = 0x7fbe2c007040, is_tls = 1, unflushed =
0, cooldown_usecs = 0, warmup_size = 1048576, write_size = 16384, last_write =
0, 
    bytes_read = 1209, bytes_written = 28498, buffer_output = 1, buffered_len =
131146, flush_threshold = 131072, is_flushed = 0, is_passing = 0, scratch =
0x0, ssize = 0, 
    slen = 0}, padding_max = 0, padding_always = 1, ngh2 = 0x7fbe2400a140,
state = H2_SESSION_ST_DONE, local = {accepted_max = 17, completed_max = 19,
emitted_count = 0, 
    emitted_max = 0, error = 104, error_msg = 0x0, accepting = 0, shutdown =
1}, remote = {accepted_max = 0, completed_max = 0, emitted_count = 10,
emitted_max = 19, error = 0, 
    error_msg = 0x0, accepting = 1, shutdown = 0}, reprioritize = 0, flush = 0,
wait_us = 0, push_diary = 0x7fbe30008ed8, monitor = 0x7fbe30008c98,
open_streams = 8, 
  streams_done = 2, responses_submitted = 2, streams_reset = 0, pushes_promised
= 0, pushes_submitted = 0, pushes_reset = 0, frames_received = 12, frames_sent
= 15, 
  max_stream_count = 100, max_stream_mem = 32768, idle_frames = 1, idle_delay =
0, bbtmp = 0x7fbe30008e98, 
  status = "[10/2] done: stream 19, GET /.../news/profileviewrss/foxfeed",
last_status_code = 0, last_status_msg = 0x0, input_flushed = 0, out_c1_blocked
= 0x7fbe30008938, 
  ready_to_process = 0x7fbe30008ae8}
(gdb) p *session.io.output
  $2 = {p = 0x7fbf80025978, list = {next = 0x7fbe2c007048, prev =
0x7fbe2c007048}, bucket_alloc = 0x7fbe2c0008e8}
(gdb) p *session.ngh2
  $3 = {streams = {table = 0x7fbe24008400, mem = 0x7fbe2400ab20, size = 9,
tablelen = 16, tablelenbits = 4}, root = {pq_entry = {index = 0}, obq = {q =
0x7fbe24008300, 
      mem = 0x7fbe2400ab20, length = 1, capacity = 4, less = 0x7d78e0
<stream_less>}, content_length = -1, recv_content_length = 0,
descendant_last_cycle = 171490, cycle = 0, 
    descendant_next_seq = 13, seq = 0, dep_prev = 0x0, dep_next =
0x7fbe2400b6a0, sib_prev = 0x0, sib_next = 0x0, closed_prev = 0x0, closed_next
= 0x0, stream_user_data = 0x0, 
    item = 0x0, last_writelen = 16375, stream_id = 0, remote_window_size = 0,
recv_window_size = 0, consumed_size = 0, recv_reduction = 0, local_window_size
= 0, weight = 16, 
    pending_penalty = 0, sum_dep_weight = 220, state = NGHTTP2_STREAM_IDLE,
status_code = -1, http_flags = 0, flags = 0 '\000', shut_flags = 0 '\000',
queued = 0 '\000', 
    window_update_queued = 0 '\000', extpri = 3 '\003', http_extpri = 3
'\003'}, ob_urgent = {head = 0x0, tail = 0x0, n = 0}, ob_reg = {head = 0x0,
tail = 0x0, n = 0}, ob_syn = {
    head = 0x0, tail = 0x0, n = 0}, sched = {{ob_data = {q = 0x0, mem =
0x7fbe2400ab20, length = 0, capacity = 0, less = 0x7d8c90 <stream_less>}},
{ob_data = {q = 0x0, 
        mem = 0x7fbe2400ab20, length = 0, capacity = 0, less = 0x7d8c90
<stream_less>}}, {ob_data = {q = 0x0, mem = 0x7fbe2400ab20, length = 0,
capacity = 0, 
        less = 0x7d8c90 <stream_less>}}, {ob_data = {q = 0x0, mem =
0x7fbe2400ab20, length = 0, capacity = 0, less = 0x7d8c90 <stream_less>}},
{ob_data = {q = 0x0, 
        mem = 0x7fbe2400ab20, length = 0, capacity = 0, less = 0x7d8c90
<stream_less>}}, {ob_data = {q = 0x0, mem = 0x7fbe2400ab20, length = 0,
capacity = 0, 
        less = 0x7d8c90 <stream_less>}}, {ob_data = {q = 0x0, mem =
0x7fbe2400ab20, length = 0, capacity = 0, less = 0x7d8c90 <stream_less>}},
{ob_data = {q = 0x0, 
        mem = 0x7fbe2400ab20, length = 0, capacity = 0, less = 0x7d8c90
<stream_less>}}}, aob = {item = 0x7fbe240225b0, framebufs = {head =
0x7fbe24009000, cur = 0x7fbe24009000, 
      mem = 0x7fbe2400ab20, chunk_length = 16394, max_chunk = 4, chunk_used =
1, chunk_keep = 1, offset = 10}, state = NGHTTP2_OB_SEND_DATA}, iframe = {frame
= {hd = {length = 0, 
        stream_id = 0, type = 0 '\000', flags = 0 '\000', reserved = 0 '\000'},
data = {hd = {length = 0, stream_id = 0, type = 0 '\000', flags = 0 '\000',
reserved = 0 '\000'}, 
        padlen = 0}, headers = {hd = {length = 0, stream_id = 0, type = 0
'\000', flags = 0 '\000', reserved = 0 '\000'}, padlen = 0, pri_spec =
{stream_id = 0, weight = 0, 
          exclusive = 0 '\000'}, nva = 0x0, nvlen = 0, cat =
NGHTTP2_HCAT_REQUEST}, priority = {hd = {length = 0, stream_id = 0, type = 0
'\000', flags = 0 '\000', 
          reserved = 0 '\000'}, pri_spec = {stream_id = 0, weight = 0,
exclusive = 0 '\000'}}, rst_stream = {hd = {length = 0, stream_id = 0, type = 0
'\000', flags = 0 '\000', 
          reserved = 0 '\000'}, error_code = 0}, settings = {hd = {length = 0,
stream_id = 0, type = 0 '\000', flags = 0 '\000', reserved = 0 '\000'}, niv =
0, iv = 0x0}, 
      push_promise = {hd = {length = 0, stream_id = 0, type = 0 '\000', flags =
0 '\000', reserved = 0 '\000'}, padlen = 0, nva = 0x0, nvlen = 0,
promised_stream_id = 0, 
        reserved = 0 '\000'}, ping = {hd = {length = 0, stream_id = 0, type = 0
'\000', flags = 0 '\000', reserved = 0 '\000'}, opaque_data =
"\000\000\000\000\000\000\000"}, 
      goaway = {hd = {length = 0, stream_id = 0, type = 0 '\000', flags = 0
'\000', reserved = 0 '\000'}, last_stream_id = 0, error_code = 0, opaque_data =
0x0, 
        opaque_data_len = 0, reserved = 0 '\000'}, window_update = {hd =
{length = 0, stream_id = 0, type = 0 '\000', flags = 0 '\000', reserved = 0
'\000'}, 
        window_size_increment = 0, reserved = 0 '\000'}, ext = {hd = {length =
0, stream_id = 0, type = 0 '\000', flags = 0 '\000', reserved = 0 '\000'},
payload = 0x0}}, 
    ext_frame_payload = {altsvc = {origin = 0x0, origin_len = 0, field_value =
0x0, field_value_len = 0}, origin = {nov = 0, ov = 0x0}, priority_update =
{stream_id = 0, 
        field_value = 0x0, field_value_len = 0}}, iv = 0x0, sbuf = {begin =
0x7fbe2400a4fc "\200", end = 0x7fbe2400a51c "", pos = 0x7fbe2400a4fc "\200", 
      last = 0x7fbe2400a4fc "\200", mark = 0x7fbe2400a505 ""}, lbuf = {begin =
0x0, end = 0x0, pos = 0x0, last = 0x0, mark = 0x0}, raw_lbuf = 0x0, niv = 0,
max_niv = 0, 
    payloadleft = 0, padlen = 0, state = NGHTTP2_IB_READ_HEAD, raw_sbuf =
"\200\000\000\021\222\000\000\000\023", '\000' <repeats 22 times>}, hd_deflater
= {ctx = {hd_table = {
        buffer = 0x7fbe2400ac90, mask = 127, first = 18446744073709551609, len
= 7}, mem = 0x7fbe2400ab20, hd_table_bufsize = 428, hd_table_bufsize_max =
4096, next_seq = 7, 
      bad = 0 '\000'}, map = {table = {0x0 <repeats 21 times>, 0x7fbe24008f20,
0x0 <repeats 60 times>, 0x7fbe24022940, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x7fbe24022890, 
        0x0 <repeats 12 times>, 0x7fbe24012540, 0x0, 0x0, 0x0, 0x0,
0x7fbe24008ec0, 0x0 <repeats 20 times>}}, deflate_hd_table_bufsize_max = 4096, 
    min_hd_table_bufsize_max = 4294967295, notify_table_size_change = 0
'\000'}, hd_inflater = {ctx = {hd_table = {buffer = 0x7fbe2400b0a0, mask = 127, 
        first = 18446744073709551609, len = 7}, mem = 0x7fbe2400ab20,
hd_table_bufsize = 654, hd_table_bufsize_max = 4096, next_seq = 7, bad = 0
'\000'}, huff_decode_ctx = {
      fstate = 16448}, namebuf = {begin = 0x7fbe24008c38 "bytes", end =
0x7fbe24008c41 "", pos = 0x7fbe24008c38 "bytes", last = 0x7fbe24008c3d "", mark
= 0x7fbe24008c38 "bytes"}, 
    valuebuf = {begin = 0x7fbe2401c448
"/.../news/profileviewrss/foxfeedspro/2023/01/....jpg", end = 0x7fbe2401c4c1
"", 
      pos = 0x7fbe2401c448
"/.../news/profileviewrss/foxfeedspro/2023/01/....jpg", last = 0x7fbe2401c49c
"", 
      mark = 0x7fbe2401c448
"/.../news/profileviewrss/foxfeedspro/2023/01/....jpg"}, namercbuf = 0x0,
valuercbuf = 0x0, nv_name_keep = 0x0, 
    nv_value_keep = 0x0, left = 62, index = 61, settings_hd_table_bufsize_max =
4096, min_hd_table_bufsize_max = 4294967295, shift = 0, opcode =
NGHTTP2_HD_OPCODE_INDEXED, 
    state = NGHTTP2_HD_STATE_INFLATE_START, huffman_encoded = 1 '\001',
index_required = 0 '\000', no_index = 0 '\000'}, callbacks = {send_callback =
0x5da360 <send_cb>, 
    recv_callback = 0x0, on_frame_recv_callback = 0x5dd2e0 <on_frame_recv_cb>,
on_invalid_frame_recv_callback = 0x5dc280 <on_invalid_frame_recv_cb>, 
    on_data_chunk_recv_callback = 0x5da160 <on_data_chunk_recv_cb>,
before_frame_send_callback = 0x0, on_frame_send_callback = 0x5dbf50
<on_frame_send_cb>, 
    on_frame_not_send_callback = 0x0, on_stream_close_callback = 0x5da030
<on_stream_close_cb>, on_begin_headers_callback = 0x5daa60
<on_begin_headers_cb>, 
    on_header_callback = 0x5da8f0 <on_header_cb>, on_header_callback2 = 0x0,
on_invalid_header_callback = 0x5d9740 <on_invalid_header_cb>,
on_invalid_header_callback2 = 0x0, 
    select_padding_callback = 0x5d95b0 <select_padding_cb>,
read_length_callback = 0x0, on_begin_frame_callback = 0x0, send_data_callback =
0x5d98a0 <on_send_data_cb>, 
    pack_extension_callback = 0x0, unpack_extension_callback = 0x0,
on_extension_chunk_recv_callback = 0x0, error_callback = 0x0, error_callback2 =
0x0}, mem = {
    mem_user_data = 0x0, malloc = 0x7ed3f0 <default_malloc>, free = 0x7ed3e0
<default_free>, calloc = 0x7ed3d0 <default_calloc>, realloc = 0x7ed3c0
<default_realloc>}, 
  user_data = 0x7fbe30008730, closed_stream_head = 0x0, closed_stream_tail =
0x0, idle_stream_head = 0x0, idle_stream_tail = 0x0, inflight_settings_head =
0x7fbe24009610, 
  stream_seq = 0, num_outgoing_streams = 0, num_incoming_streams = 9,
num_incoming_reserved_streams = 0, max_incoming_reserved_streams = 200,
num_closed_streams = 0, 
  num_idle_streams = 0, nvbuflen = 0, obq_flood_counter_ = 0, max_outbound_ack
= 1000, max_send_header_block_length = 65536, max_settings = 32, next_stream_id
= 2, 
  last_sent_stream_id = 0, last_recv_stream_id = 19, last_proc_stream_id = 19,
next_unique_id = 0, local_last_stream_id = 2147483647, remote_last_stream_id =
2147483647, 
  remote_window_size = 15569316, recv_window_size = 0, consumed_size = 0,
recv_reduction = 0, local_window_size = 2147483647, remote_settings_received =
1 '\001', 
  remote_settings = {header_table_size = 65536, enable_push = 1,
max_concurrent_streams = 1000, initial_window_size = 6291456, max_frame_size =
16384, 
    max_header_list_size = 4294967295, enable_connect_protocol = 0,
no_rfc7540_priorities = 0}, local_settings = {header_table_size = 4096,
enable_push = 1, 
    max_concurrent_streams = 4294967295, initial_window_size = 65535,
max_frame_size = 16384, max_header_list_size = 4294967295,
enable_connect_protocol = 0, 
    no_rfc7540_priorities = 4294967295}, opt_flags = 81,
pending_local_max_concurrent_stream = 100, builtin_recv_ext_types = 0,
pending_enable_push = 1 '\001', 
  pending_enable_connect_protocol = 0 '\000', pending_no_rfc7540_priorities = 0
'\000', fallback_rfc7540_priorities = 0 '\000', server = 1 '\001', goaway_flags
= 0 '\000', 
  window_update_queued = 0 '\000', user_recv_ext_types = '\000' <repeats 31
times>}

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscr...@httpd.apache.org
For additional commands, e-mail: bugs-h...@httpd.apache.org

Reply via email to