[xcode] LLDB에서 배열보기 : Xcode 4.1의 GDB ‘@’연산자와 동일

포인터가 가리키는 요소 배열을보고 싶습니다. GDB에서는 ‘@’연산자를 사용하여 지정된 길이의 인공 배열로 지적 메모리를 처리하여 다음과 같이 수행 할 수 있습니다.

*pointer @ length

length보고 싶은 요소의 수는 어디에 있습니까 ?

위의 구문은 Xcode 4.1과 함께 제공되는 LLDB에서 작동하지 않습니다.

LLDB에서 위의 작업을 수행하는 방법이 있습니까?



답변

lldb에는 두 가지 방법이 있습니다.

가장 일반적으로 parraya COUNT및 an 을 취하는 lldb 명령을 사용합니다 EXPRESSION. EXPRESSION평가되고 메모리에 대한 포인터가됩니다. 그러면 lldb는 COUNT해당 주소에 해당 유형의 항목 을 인쇄 합니다. 예 :

parray 10 ptr

어디 ptr유형 int *입니다.

또는 포인터를 배열에 대한 포인터로 캐스팅하여 수행 할 수 있습니다.

예를 들어를 가지고 있고 int* ptr이를 10 개의 정수 배열로 보려면 다음을 수행 할 수 있습니다.

p *(int(*)[10])ptr

표준 C 기능에만 의존하기 때문에이 방법은 플러그인이나 특수 설정없이 작동합니다. 마찬가지로 GDB 또는 CDB와 같은 다른 디버거에서도 작동하지만 배열 인쇄를위한 특수 구문도 있습니다.


답변

Xcode 8.0의 lldb부터 새로운 내장 parray 명령이 있습니다. 따라서 다음과 같이 말할 수 있습니다.

(lldb) parray <COUNT> <EXPRESSION>

의 결과가 가리키는 메모리를 표현식이 가리키는 유형 EXPRESSIONCOUNT요소 배열 로 인쇄합니다 .

카운트가 현재 프레임에서 사용 가능한 변수에 저장되면 다음을 수행 할 수 있습니다.

(lldb) parray `count_variable` pointer_to_malloced_array

이는 일반적인 lldb 기능입니다. 백틱으로 둘러싸인 lldb의 모든 명령 줄 인수는 정수를 반환하는 식으로 평가되고 명령 실행 전에 정수가 인수로 대체됩니다.


답변

내가 찾은 유일한 방법은 Python 스크립팅 모듈을 사용하는 것입니다.

""" File: parray.py """
import lldb
import shlex

def parray(debugger, command, result, dict):
    args = shlex.split(command)
    va = lldb.frame.FindVariable(args[0])
    for i in range(0, int(args[1])):
        print va.GetChildAtIndex(i, 0, 1)

lldb에서 “parray”명령을 정의하십시오.

(lldb) command script import /path/to/parray.py
(lldb) command script add --function parray.parray parray

이제 “parray variable length “를 사용할 수 있습니다 .

(lldb) parray a 5
(double) *a = 0
(double) [1] = 0
(double) [2] = 1.14468
(double) [3] = 2.28936
(double) [4] = 3.43404


답변

Xcode 4.5.1 (지금 도움이 될 수도 있고 아닐 수도 있음)을 사용하면 lldb 콘솔에서이 작업을 수행 할 수 있습니다.

(lldb) type summary add -s "${var[0-63]}" "float *"
(lldb) frame variable pointer
  (float *) pointer = 0x000000010ba92950 [0.0,1.0,2.0,3.0, ... ,63.0]

이 예에서는 ‘포인터’가 64 개의 부동 소수점 배열이라고 가정합니다. float pointer[64];


답변

Martin R 답변으로 시작하여 다음과 같이 개선했습니다.

  1. 포인터가 단순 변수가 아닌 경우, 예 :

    struct {
      int* at;
      size_t size;
    } a;
    

    그런 다음 “parray a.at 5″가 실패합니다.

    “FindVariable”을 “GetValueForVariablePath”로 바꾸어이 문제를 해결했습니다.

  2. 이제 배열의 요소가 집계이면 어떻게됩니까?

    struct {
      struct { float x; float y; }* at;
      size_t size;
    } a;
    

    그런 다음 “parray a.at 5″는 다음을 인쇄합니다. a.at-> x, a.at-> y, a.at [2], a.at [3], a.at [4] GetChildAtIndex ()가 멤버를 반환하기 때문입니다. 집계의.

    “a.at”를 확인한 다음 그 자식을 검색하는 대신 루프 내부에서 “a.at”+ “[“+ str (i) + “]”를 해결하여이 문제를 해결했습니다.

  3. 선택적인 “첫 번째”인수 (사용 : parray [FIRST] COUNT)를 추가했습니다. 이는 많은 수의 요소가있을 때 유용합니다.

  4. init에서 “command script add -f parray.parray parray”를 수행했습니다.

다음은 수정 된 버전입니다.

import lldb
import shlex

def parray(debugger, command, result, dict):
  args = shlex.split(command)
  if len(args) == 2:
    count = int(args[1])
    indices = range(count)
  elif len(args) == 3:
    first = int(args[1]), count = int(args[2])
    indices = range(first, first + count)
  else:
    print 'Usage: parray ARRAY [FIRST] COUNT'
    return
  for i in indices:
    print lldb.frame.GetValueForVariablePath(args[0] + "[" + str(i) + "]")

def __lldb_init_module(debugger, internal_dict):
  debugger.HandleCommand('command script add -f parray.parray parray')


답변

아직 지원되지 않는 것 같습니다.

메모리 읽기 기능 (메모리 읽기 / x)을 사용할 수 있습니다.

(lldb) memory read -ff -c10 `test`

그 포인터에서 float를 10 번 인쇄합니다. 이것은 gdb의 @과 동일한 기능이어야합니다.


답변

댓글을 달아 보려고했는데 전체 답변을 올리기 엔 좋지 않아서 직접 답변을했습니다. 이것은 “가치 없음”을 얻는 문제를 해결합니다. lldbinit에서 모듈을로드하는 경우 중단 점에서 멈출 때 lldb.frame이 모듈 가져 오기 시간에 설정되어 있다고 생각하므로 현재 프레임을 가져와야합니다. 중단 점에서 중지했을 때 스크립트를 가져 오거나 다시로드하면 다른 버전이 작동합니다. 아래 버전은 항상 작동합니다.

import lldb
import shlex

@lldb.command('parray', 'command script add -f parray.parray parray')
def parray(debugger, command, result, dict):

    target = debugger.GetSelectedTarget()
    process = target.GetProcess()
    thread = process.GetSelectedThread()
    frame = thread.GetSelectedFrame()

    args = shlex.split(command)
    if len(args) == 2:
        count = int(args[1])
        indices = range(count)
    elif len(args) == 3:
        first = int(args[1])
        count = int(args[2])
        indices = range(first, first + count)
    else:
        print 'Usage: parray ARRAY [FIRST] COUNT'
        return

    for i in indices:
        print frame.GetValueForVariablePath(args[0] + "[" + str(i) + "]")