Skip to content

Commit

Permalink
Increase BPFTRACE_MAX_STRLEN from 64 to 1024
Browse files Browse the repository at this point in the history
Now that we support big-X and printing big-X's, we can increase the
default size to 1024.

Note that this will break anyone assigning a default string to a scratch
variable. However, they have a couple potential remediations:

1. Assign it to a map instead
2. Save the str() call for the print()/printf() argument
3. Clamp the string size

These options are all pretty easy and cover all the use cases I can
think of. And given big strings are something users have been asking
about for years, I think the relatively small pain is a worthwhile
price.
  • Loading branch information
danobi committed Aug 7, 2024
1 parent 0285075 commit eb734db
Show file tree
Hide file tree
Showing 17 changed files with 124 additions and 74 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ and this project adheres to
- [#3249](https://github.com/bpftrace/bpftrace/pull/3249)
- Faster map access for keyless maps by using BPF_MAP_TYPE_ARRAY
- [#3300](https://github.com/bpftrace/bpftrace/pull/3300)
- Increase default string size from 64 to 1024
- [#3371](https://github.com/bpftrace/bpftrace/pull/3371)
#### Deprecated
#### Removed
- Remove the `-dd` CLI option
Expand Down
11 changes: 4 additions & 7 deletions man/adoc/bpftrace.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3443,15 +3443,12 @@ system.

=== max_strlen

Default: 64
Default: 1024

Number of bytes allocated on the BPF stack for the string returned by str().
Make this larger if you wish to read bigger strings with str().
Beware that the BPF stack is small (512 bytes), and that you pay the toll again inside printf() (whilst
it composes a perf event output buffer).
So in practice you can only grow this to about 200 bytes.
The maximum length (in bytes) for values created by `str()`, `buf()` and `path()`.

Support for even larger strings is being discussed: https://github.com/bpftrace/bpftrace/issues/305.
This limit is necessary because BPF requires the size of all dynamically-read strings (and similar) to be declared up front. This is the size for all strings (and similar) in bpftrace unless specified at the call site.
There is no artificial limit on what you can tune this to. But you may be wasting resources (memory and cpu) if you make this too high.

=== max_type_res_iterations

Expand Down
16 changes: 16 additions & 0 deletions src/ast/passes/semantic_analyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2678,6 +2678,22 @@ void SemanticAnalyser::visit(AssignVarStatement &assignment)
if (ty == Type::none)
LOG(ERROR, assignment.expr->loc, err_)
<< "Invalid expression for assignment: " << ty;

// Scratch variables are on the BPF stack, which is only 512 bytes at time
// of writing, so large values do not fit on there. 200 is a ballpark of
// what probably won't work.
auto expr_size = assignTy.GetSize();
if (expr_size > 200) {
LOG(ERROR, assignment.loc, err_)
<< "Value is too big "
<< "(" << expr_size << " bytes) for the stack. "
<< "Try reducing its size, storing it in a map, or creating it in "
"argument position to a helper call.\n\n"
<< "Examples:\n"
<< " `$s = str(..);` => `$s = str(.., 32);`\n"
<< " `$s = str(..);` => `@s = str(..);`\n"
<< " `$s = str(..); print($s);` => `print(str(..));`\n\n";
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Config::Config(bool has_cmd)
{ ConfigKeyInt::max_cat_bytes, { .value = (uint64_t)10240 } },
{ ConfigKeyInt::max_map_keys, { .value = (uint64_t)4096 } },
{ ConfigKeyInt::max_probes, { .value = (uint64_t)512 } },
{ ConfigKeyInt::max_strlen, { .value = (uint64_t)64 } },
{ ConfigKeyInt::max_strlen, { .value = (uint64_t)1024 } },
{ ConfigKeyInt::max_type_res_iterations, { .value = (uint64_t)0 } },
{ ConfigKeyInt::perf_rb_pages, { .value = (uint64_t)64 } },
{ ConfigKeyStackMode::default_, { .value = StackMode::bpftrace } },
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ void usage()
std::cerr << " BPFTRACE_MAX_CAT_BYTES [default: 10k] maximum bytes read by cat builtin" << std::endl;
std::cerr << " BPFTRACE_MAX_MAP_KEYS [default: 4096] max keys in a map" << std::endl;
std::cerr << " BPFTRACE_MAX_PROBES [default: 512] max number of probes" << std::endl;
std::cerr << " BPFTRACE_MAX_STRLEN [default: 64] bytes on BPF stack per str()" << std::endl;
std::cerr << " BPFTRACE_MAX_STRLEN [default: 1024] bytes on BPF stack per str()" << std::endl;
std::cerr << " BPFTRACE_MAX_TYPE_RES_ITERATIONS [default: 0] number of levels of nested field accesses for tracepoint args" << std::endl;
std::cerr << " BPFTRACE_PERF_RB_PAGES [default: 64] pages per CPU to allocate for ring buffer" << std::endl;
std::cerr << " BPFTRACE_STACK_MODE [default: bpftrace] Output format for ustack and kstack builtins" << std::endl;
Expand Down
4 changes: 2 additions & 2 deletions tests/codegen/llvm/call_buf_implicit_size.ll
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }
!47 = !DISubrange(count: 6, lowerBound: 0)
!48 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !49, size: 64, offset: 192)
!49 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !50, size: 64)
!50 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 512, elements: !51)
!50 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 8192, elements: !51)
!51 = !{!52}
!52 = !DISubrange(count: 64, lowerBound: 0)
!52 = !DISubrange(count: 1024, lowerBound: 0)
!53 = !DIGlobalVariableExpression(var: !54, expr: !DIExpression())
!54 = distinct !DIGlobalVariable(name: "event_loss_counter", linkageName: "global", scope: !2, file: !2, type: !55, isLocal: false, isDefinition: true)
!55 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 256, elements: !56)
Expand Down
4 changes: 2 additions & 2 deletions tests/codegen/llvm/call_buf_size_literal.ll
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }
!47 = !DISubrange(count: 6, lowerBound: 0)
!48 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !49, size: 64, offset: 192)
!49 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !50, size: 64)
!50 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 512, elements: !51)
!50 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 8192, elements: !51)
!51 = !{!52}
!52 = !DISubrange(count: 64, lowerBound: 0)
!52 = !DISubrange(count: 1024, lowerBound: 0)
!53 = !DIGlobalVariableExpression(var: !54, expr: !DIExpression())
!54 = distinct !DIGlobalVariable(name: "event_loss_counter", linkageName: "global", scope: !2, file: !2, type: !55, isLocal: false, isDefinition: true)
!55 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 256, elements: !56)
Expand Down
22 changes: 9 additions & 13 deletions tests/codegen/llvm/call_buf_size_nonliteral.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ target triple = "bpf-pc-linux"
%"struct map_t.0" = type { ptr, ptr }
%"struct map_t.1" = type { ptr, ptr, ptr, ptr }
%"struct map_t.2" = type { ptr, ptr, ptr, ptr }
%buffer_60_t = type <{ i32, [60 x i8] }>
%buffer_1020_t = type <{ i32, [1020 x i8] }>

@LICENSE = global [4 x i8] c"GPL\00", section "license"
@AT_x = dso_local global %"struct map_t" zeroinitializer, section ".maps", !dbg !0
Expand All @@ -24,8 +24,8 @@ entry:
%lookup_str_key = alloca i32, align 4
%1 = getelementptr i64, ptr %0, i64 13
%arg1 = load volatile i64, ptr %1, align 8
%length.cmp = icmp ule i64 %arg1, 60
%length.select = select i1 %length.cmp, i64 %arg1, i64 60
%length.cmp = icmp ule i64 %arg1, 1020
%length.select = select i1 %length.cmp, i64 %arg1, i64 1020
call void @llvm.lifetime.start.p0(i64 -1, ptr %lookup_str_key)
store i32 0, ptr %lookup_str_key, align 4
%lookup_str_map = call ptr inttoptr (i64 1 to ptr)(ptr @str_buffer, ptr %lookup_str_key)
Expand All @@ -37,14 +37,14 @@ lookup_str_failure: ; preds = %entry
ret i64 0

lookup_str_merge: ; preds = %entry
%2 = getelementptr %buffer_60_t, ptr %lookup_str_map, i32 0, i32 0
%2 = getelementptr %buffer_1020_t, ptr %lookup_str_map, i32 0, i32 0
%3 = trunc i64 %length.select to i32
store i32 %3, ptr %2, align 4
%4 = getelementptr %buffer_60_t, ptr %lookup_str_map, i32 0, i32 1
call void @llvm.memset.p0.i64(ptr align 1 %4, i8 0, i64 60, i1 false)
%4 = getelementptr %buffer_1020_t, ptr %lookup_str_map, i32 0, i32 1
%probe_read_kernel = call i64 inttoptr (i64 113 to ptr)(ptr %4, i32 1020, ptr null)
%5 = getelementptr i64, ptr %0, i64 14
%arg0 = load volatile i64, ptr %5, align 8
%probe_read_kernel = call i64 inttoptr (i64 113 to ptr)(ptr %4, i32 %3, i64 %arg0)
%probe_read_kernel1 = call i64 inttoptr (i64 113 to ptr)(ptr %4, i32 %3, i64 %arg0)
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@x_key")
store i64 0, ptr %"@x_key", align 8
%update_elem = call i64 inttoptr (i64 2 to ptr)(ptr @AT_x, ptr %"@x_key", ptr %lookup_str_map, i64 0)
Expand All @@ -58,12 +58,8 @@ declare void @llvm.lifetime.start.p0(i64 immarg %0, ptr nocapture %1) #1
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg %0, ptr nocapture %1) #1

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly %0, i8 %1, i64 %2, i1 immarg %3) #2

attributes #0 = { nounwind }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }

!llvm.dbg.cu = !{!55}
!llvm.module.flags = !{!57}
Expand All @@ -89,10 +85,10 @@ attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }
!18 = !DIBasicType(name: "int32", size: 32, encoding: DW_ATE_signed)
!19 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !20, size: 64, offset: 192)
!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !21, size: 64)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 512, elements: !23)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 8192, elements: !23)
!22 = !DIBasicType(name: "int8", size: 8, encoding: DW_ATE_signed)
!23 = !{!24}
!24 = !DISubrange(count: 64, lowerBound: 0)
!24 = !DISubrange(count: 1024, lowerBound: 0)
!25 = !DIGlobalVariableExpression(var: !26, expr: !DIExpression())
!26 = distinct !DIGlobalVariable(name: "ringbuf", linkageName: "global", scope: !2, file: !2, type: !27, isLocal: false, isDefinition: true)
!27 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 128, elements: !28)
Expand Down
12 changes: 4 additions & 8 deletions tests/codegen/llvm/call_str.ll
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ lookup_str_failure: ; preds = %entry
ret i64 0

lookup_str_merge: ; preds = %entry
call void @llvm.memset.p0.i64(ptr align 1 %lookup_str_map, i8 0, i64 64, i1 false)
%probe_read_kernel = call i64 inttoptr (i64 113 to ptr)(ptr %lookup_str_map, i32 1024, ptr null)
%1 = getelementptr i64, ptr %0, i64 14
%arg0 = load volatile i64, ptr %1, align 8
%probe_read_kernel_str = call i64 inttoptr (i64 115 to ptr)(ptr %lookup_str_map, i32 64, i64 %arg0)
%probe_read_kernel_str = call i64 inttoptr (i64 115 to ptr)(ptr %lookup_str_map, i32 1024, i64 %arg0)
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@x_key")
store i64 0, ptr %"@x_key", align 8
%update_elem = call i64 inttoptr (i64 2 to ptr)(ptr @AT_x, ptr %"@x_key", ptr %lookup_str_map, i64 0)
Expand All @@ -49,12 +49,8 @@ declare void @llvm.lifetime.start.p0(i64 immarg %0, ptr nocapture %1) #1
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg %0, ptr nocapture %1) #1

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly %0, i8 %1, i64 %2, i1 immarg %3) #2

attributes #0 = { nounwind }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }

!llvm.dbg.cu = !{!55}
!llvm.module.flags = !{!57}
Expand All @@ -80,10 +76,10 @@ attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }
!18 = !DIBasicType(name: "int32", size: 32, encoding: DW_ATE_signed)
!19 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !20, size: 64, offset: 192)
!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !21, size: 64)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 512, elements: !23)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 8192, elements: !23)
!22 = !DIBasicType(name: "int8", size: 8, encoding: DW_ATE_signed)
!23 = !{!24}
!24 = !DISubrange(count: 64, lowerBound: 0)
!24 = !DISubrange(count: 1024, lowerBound: 0)
!25 = !DIGlobalVariableExpression(var: !26, expr: !DIExpression())
!26 = distinct !DIGlobalVariable(name: "ringbuf", linkageName: "global", scope: !2, file: !2, type: !27, isLocal: false, isDefinition: true)
!27 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 128, elements: !28)
Expand Down
14 changes: 5 additions & 9 deletions tests/codegen/llvm/call_str_2_expr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ entry:
%1 = getelementptr i64, ptr %0, i64 13
%arg1 = load volatile i64, ptr %1, align 8
%2 = add i64 %arg1, 1
%str.min.cmp = icmp ule i64 %2, 64
%str.min.select = select i1 %str.min.cmp, i64 %2, i64 64
%str.min.cmp = icmp ule i64 %2, 1024
%str.min.select = select i1 %str.min.cmp, i64 %2, i64 1024
call void @llvm.lifetime.start.p0(i64 -1, ptr %lookup_str_key)
store i32 0, ptr %lookup_str_key, align 4
%lookup_str_map = call ptr inttoptr (i64 1 to ptr)(ptr @str_buffer, ptr %lookup_str_key)
Expand All @@ -37,7 +37,7 @@ lookup_str_failure: ; preds = %entry
ret i64 0

lookup_str_merge: ; preds = %entry
call void @llvm.memset.p0.i64(ptr align 1 %lookup_str_map, i8 0, i64 64, i1 false)
%probe_read_kernel = call i64 inttoptr (i64 113 to ptr)(ptr %lookup_str_map, i32 1024, ptr null)
%3 = getelementptr i64, ptr %0, i64 14
%arg0 = load volatile i64, ptr %3, align 8
%4 = trunc i64 %str.min.select to i32
Expand All @@ -55,12 +55,8 @@ declare void @llvm.lifetime.start.p0(i64 immarg %0, ptr nocapture %1) #1
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg %0, ptr nocapture %1) #1

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly %0, i8 %1, i64 %2, i1 immarg %3) #2

attributes #0 = { nounwind }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }

!llvm.dbg.cu = !{!55}
!llvm.module.flags = !{!57}
Expand All @@ -86,10 +82,10 @@ attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }
!18 = !DIBasicType(name: "int32", size: 32, encoding: DW_ATE_signed)
!19 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !20, size: 64, offset: 192)
!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !21, size: 64)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 512, elements: !23)
!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 8192, elements: !23)
!22 = !DIBasicType(name: "int8", size: 8, encoding: DW_ATE_signed)
!23 = !{!24}
!24 = !DISubrange(count: 64, lowerBound: 0)
!24 = !DISubrange(count: 1024, lowerBound: 0)
!25 = !DIGlobalVariableExpression(var: !26, expr: !DIExpression())
!26 = distinct !DIGlobalVariable(name: "ringbuf", linkageName: "global", scope: !2, file: !2, type: !27, isLocal: false, isDefinition: true)
!27 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 128, elements: !28)
Expand Down
10 changes: 3 additions & 7 deletions tests/codegen/llvm/call_str_2_lit.ll
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ lookup_str_failure: ; preds = %entry
ret i64 0

lookup_str_merge: ; preds = %entry
call void @llvm.memset.p0.i64(ptr align 1 %lookup_str_map, i8 0, i64 64, i1 false)
%probe_read_kernel = call i64 inttoptr (i64 113 to ptr)(ptr %lookup_str_map, i32 1024, ptr null)
%1 = getelementptr i64, ptr %0, i64 14
%arg0 = load volatile i64, ptr %1, align 8
%probe_read_kernel_str = call i64 inttoptr (i64 115 to ptr)(ptr %lookup_str_map, i32 7, i64 %arg0)
Expand All @@ -49,12 +49,8 @@ declare void @llvm.lifetime.start.p0(i64 immarg %0, ptr nocapture %1) #1
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg %0, ptr nocapture %1) #1

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly %0, i8 %1, i64 %2, i1 immarg %3) #2

attributes #0 = { nounwind }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }

!llvm.dbg.cu = !{!58}
!llvm.module.flags = !{!60}
Expand Down Expand Up @@ -107,9 +103,9 @@ attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }
!45 = !DICompositeType(tag: DW_TAG_array_type, baseType: !8, size: 192, elements: !23)
!46 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !47, size: 64, offset: 192)
!47 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !48, size: 64)
!48 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 512, elements: !49)
!48 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 8192, elements: !49)
!49 = !{!50}
!50 = !DISubrange(count: 64, lowerBound: 0)
!50 = !DISubrange(count: 1024, lowerBound: 0)
!51 = !DIGlobalVariableExpression(var: !52, expr: !DIExpression())
!52 = distinct !DIGlobalVariable(name: "event_loss_counter", linkageName: "global", scope: !2, file: !2, type: !53, isLocal: false, isDefinition: true)
!53 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 256, elements: !54)
Expand Down
8 changes: 4 additions & 4 deletions tests/codegen/llvm/optional_positional_parameter.ll
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ lookup_str_failure: ; preds = %entry
ret i64 0

lookup_str_merge: ; preds = %entry
call void @llvm.memset.p0.i64(ptr align 1 %lookup_str_map, i8 0, i64 64, i1 false)
%probe_read_kernel = call i64 inttoptr (i64 113 to ptr)(ptr %lookup_str_map, i32 1024, ptr null)
call void @llvm.lifetime.start.p0(i64 -1, ptr %str)
call void @llvm.memset.p0.i64(ptr align 1 %str, i8 0, i64 1, i1 false)
store [1 x i8] zeroinitializer, ptr %str, align 1
%1 = ptrtoint ptr %str to i64
%probe_read_kernel_str = call i64 inttoptr (i64 115 to ptr)(ptr %lookup_str_map, i32 64, i64 %1)
%probe_read_kernel_str = call i64 inttoptr (i64 115 to ptr)(ptr %lookup_str_map, i32 1024, i64 %1)
call void @llvm.lifetime.end.p0(i64 -1, ptr %str)
call void @llvm.lifetime.start.p0(i64 -1, ptr %"@y_key")
store i64 0, ptr %"@y_key", align 8
Expand Down Expand Up @@ -102,10 +102,10 @@ attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) }
!25 = !{!5, !11, !16, !26}
!26 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !2, file: !2, baseType: !27, size: 64, offset: 192)
!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !28, size: 64)
!28 = !DICompositeType(tag: DW_TAG_array_type, baseType: !29, size: 512, elements: !30)
!28 = !DICompositeType(tag: DW_TAG_array_type, baseType: !29, size: 8192, elements: !30)
!29 = !DIBasicType(name: "int8", size: 8, encoding: DW_ATE_signed)
!30 = !{!31}
!31 = !DISubrange(count: 64, lowerBound: 0)
!31 = !DISubrange(count: 1024, lowerBound: 0)
!32 = !DIGlobalVariableExpression(var: !33, expr: !DIExpression())
!33 = distinct !DIGlobalVariable(name: "ringbuf", linkageName: "global", scope: !2, file: !2, type: !34, isLocal: false, isDefinition: true)
!34 = !DICompositeType(tag: DW_TAG_structure_type, scope: !2, file: !2, size: 128, elements: !35)
Expand Down
Loading

0 comments on commit eb734db

Please sign in to comment.